1 /* NetHack 3.6 uhitm.c $NHDT-Date: 1521684760 2018/03/22 02:12:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.176 $ */
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 /* Put up an invisible monster marker, but with exceptions for
133 * monsters that hide and monsters you've been warned about.
134 * The former already prints a warning message and
135 * prevents you from hitting the monster just via the hidden monster
136 * code below; if we also did that here, similar behavior would be
137 * happening two turns in a row. The latter shows a glyph on
138 * the screen, so you know something is there.
140 if (!canspotmon(mtmp) && !glyph_is_warning(glyph_at(bhitpos.x, bhitpos.y))
141 && !glyph_is_invisible(levl[bhitpos.x][bhitpos.y].glyph)
142 && !(!Blind && mtmp->mundetected && hides_under(mtmp->data))) {
144 pline("Wait! There's %s there you can't see!", something);
146 pline("
\82¿
\82å
\82Á
\82Æ
\91Ò
\82Á
\82½
\81I
\8ep
\82Ì
\8c©
\82¦
\82È
\82¢%s
\82ª
\82¢
\82é
\81I", something);
147 map_invisible(bhitpos.x, bhitpos.y);
148 /* if it was an invisible mimic, treat it as if we stumbled
149 * onto a visible mimic
151 if (mtmp->m_ap_type && !Protection_from_shape_changers
152 /* applied pole-arm attack is too far to get stuck */
153 && distu(mtmp->mx, mtmp->my) <= 2) {
154 if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK))
157 wakeup(mtmp, TRUE); /* always necessary; also un-mimics mimics */
161 if (mtmp->m_ap_type && !Protection_from_shape_changers && !sensemon(mtmp)
162 && !glyph_is_warning(glyph_at(bhitpos.x, bhitpos.y))) {
163 /* If a hidden mimic was in a square where a player remembers
164 * some (probably different) unseen monster, the player is in
165 * luck--he attacks it even though it's hidden.
167 if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) {
171 stumble_onto_mimic(mtmp);
175 if (mtmp->mundetected && !canseemon(mtmp)
176 && !glyph_is_warning(glyph_at(bhitpos.x, bhitpos.y))
177 && (hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)) {
178 mtmp->mundetected = mtmp->msleeping = 0;
179 newsym(mtmp->mx, mtmp->my);
180 if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) {
184 if (!((Blind ? Blind_telepat : Unblind_telepat) || Detect_monsters)) {
187 if (Blind || (is_pool(mtmp->mx, mtmp->my) && !Underwater))
189 pline("Wait! There's a hidden monster there!");
191 pline("
\91Ò
\82Ä
\81I
\89ö
\95¨
\82ª
\89B
\82ê
\82Ä
\82¢
\82é
\81I");
192 else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0)
194 pline("Wait! There's %s hiding under %s!",
195 an(l_monnam(mtmp)), doname(obj));
197 pline("
\91Ò
\82Ä
\81I%s
\82Ì
\89º
\82É%s
\82ª
\89B
\82ê
\82Ä
\82¢
\82é
\81I",
198 doname(obj), l_monnam(mtmp));
205 * make sure to wake up a monster from the above cases if the
206 * hero can sense that the monster is there.
208 if ((mtmp->mundetected || mtmp->m_ap_type) && sensemon(mtmp)) {
209 mtmp->mundetected = 0;
213 if (flags.confirm && mtmp->mpeaceful && !Confusion && !Hallucination
215 /* Intelligent chaotic weapons (Stormbringer) want blood */
216 if (wep && wep->oartifact == ART_STORMBRINGER) {
217 override_confirmation = TRUE;
220 if (canspotmon(mtmp)) {
222 Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp));
224 Sprintf(qbuf, "
\96{
\93\96\82É%s
\82ð
\8dU
\8c\82\82·
\82é
\82Ì
\81H", mon_nam(mtmp));
225 if (!paranoid_query(ParanoidHit, qbuf)) {
236 * It is unchivalrous for a knight to attack the defenseless or from behind.
242 if (u.ualign.record <= -10)
245 if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL
246 && (!mtmp->mcanmove || mtmp->msleeping
247 || (mtmp->mflee && !mtmp->mavenge))) {
251 pline("
\82±
\82ê
\82Í
\94Ú
\8b¯
\82È
\8ds
\82¢
\82¾
\81I");
253 } else if (Role_if(PM_SAMURAI) && mtmp->mpeaceful) {
254 /* attacking peaceful creatures is bad for the samurai's giri */
256 You("dishonorably attack the innocent!");
258 pline("
\96³
\8eÀ
\82Ì
\8eÒ
\82ð
\8dU
\8c\82\82·
\82é
\82Ì
\82Í
\95s
\96¼
\97_
\82¾
\81I");
264 find_roll_to_hit(mtmp, aatyp, weapon, attk_count, role_roll_penalty)
265 register struct monst *mtmp;
266 uchar aatyp; /* usually AT_WEAP or AT_KICK */
267 struct obj *weapon; /* uwep or uswapwep or NULL */
268 int *attk_count, *role_roll_penalty;
272 *role_roll_penalty = 0; /* default is `none' */
274 tmp = 1 + Luck + abon() + find_mac(mtmp) + u.uhitinc
275 + maybe_polyd(youmonst.data->mlevel, u.ulevel);
277 /* some actions should occur only once during multiple attacks */
278 if (!(*attk_count)++) {
279 /* knight's chivalry or samurai's giri */
283 /* adjust vs. (and possibly modify) monster state */
289 if (mtmp->msleeping) {
293 if (!mtmp->mcanmove) {
301 /* role/race adjustments */
302 if (Role_if(PM_MONK) && !Upolyd) {
304 tmp -= (*role_roll_penalty = urole.spelarmr);
305 else if (!uwep && !uarms)
306 tmp += (u.ulevel / 3) + 2;
308 if (is_orc(mtmp->data)
309 && maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
312 /* encumbrance: with a lot of luggage, your agility diminishes */
313 if ((tmp2 = near_capacity()) != 0)
314 tmp -= (tmp2 * 2) - 1;
319 * hitval applies if making a weapon attack while wielding a weapon;
320 * weapon_hit_bonus applies if doing a weapon attack even bare-handed
321 * or if kicking as martial artist
323 if (aatyp == AT_WEAP || aatyp == AT_CLAW) {
325 tmp += hitval(weapon, mtmp);
326 tmp += weapon_hit_bonus(weapon);
327 } else if (aatyp == AT_KICK && martial_bonus()) {
328 tmp += weapon_hit_bonus((struct obj *) 0);
334 /* try to attack; return False if monster evaded;
335 u.dx and u.dy must be set */
338 register struct monst *mtmp;
340 register struct permonst *mdat = mtmp->data;
342 /* This section of code provides protection against accidentally
343 * hitting peaceful (like '@') and tame (like 'd') monsters.
344 * Protection is provided as long as player is not: blind, confused,
345 * hallucinating or stunned.
346 * changes by wwp 5/16/85
347 * More changes 12/90, -dkh-. if its tame and safepet, (and protected
348 * 07/92) then we assume that you're not trying to attack. Instead,
349 * you'll usually just swap places if this is a movement command
351 /* Intelligent chaotic weapons (Stormbringer) want blood */
352 if (is_safepet(mtmp) && !context.forcefight) {
353 if (!uwep || uwep->oartifact != ART_STORMBRINGER) {
354 /* there are some additional considerations: this won't work
355 * if in a shop or Punished or you miss a random roll or
356 * if you can walk thru walls and your pet cannot (KAA) or
357 * if your pet is a long worm (unless someone does better).
358 * there's also a chance of displacing a "frozen" monster.
359 * sleeping monsters might magically walk in their sleep.
361 boolean foo = (Punished || !rn2(7) || is_longworm(mtmp->data)),
365 for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++)
366 if (tended_shop(&rooms[*p - ROOMOFFSET])) {
371 if (inshop || foo || (IS_ROCK(levl[u.ux][u.uy].typ)
372 && !passes_walls(mtmp->data))) {
375 monflee(mtmp, rnd(6), FALSE, FALSE);
376 Strcpy(buf, y_monnam(mtmp));
377 buf[0] = highc(buf[0]);
379 You("stop. %s is in the way!", buf);
381 You("
\8e~
\82Ü
\82Á
\82½
\81D%s
\82ª
\93¹
\82É
\82¢
\82é
\81I", buf);
382 context.travel = context.travel1 = context.mv = context.run = 0;
384 } else if ((mtmp->mfrozen || (!mtmp->mcanmove)
385 || (mtmp->data->mmove == 0)) && rn2(6)) {
387 pline("%s doesn't seem to move!", Monnam(mtmp));
389 pline("%s
\82Í
\93®
\82¯
\82È
\82¢
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
390 context.travel = context.travel1 = context.mv = context.run = 0;
397 /* possibly set in attack_checks;
398 examined in known_hitum, called via hitum or hmonas below */
399 override_confirmation = FALSE;
400 /* attack_checks() used to use <u.ux+u.dx,u.uy+u.dy> directly, now
401 it uses bhitpos instead; it might map an invisible monster there */
402 bhitpos.x = u.ux + u.dx;
403 bhitpos.y = u.uy + u.dy;
404 if (attack_checks(mtmp, uwep))
407 if (Upolyd && noattacks(youmonst.data)) {
408 /* certain "pacifist" monsters don't attack */
410 You("have no way to attack monsters physically.");
412 You("
\95¨
\97\9d\93I
\82É
\89ö
\95¨
\82ð
\8dU
\8c\82\82·
\82é
\82·
\82×
\82ª
\82È
\82¢
\81D");
413 mtmp->mstrategy &= ~STRAT_WAITMASK;
418 if (check_capacity("You cannot fight while so heavily loaded.")
420 if (check_capacity("
\82 \82È
\82½
\82Í
\95¨
\82ð
\82½
\82
\82³
\82ñ
\8e\9d\82¿
\82·
\82¬
\82Ä
\90í
\82¦
\82È
\82¢
\81D")
421 /* consume extra nutrition during combat; maybe pass out */
425 if (u.twoweap && !can_twoweapon())
433 You("begin bashing monsters with %s.", yname(uwep));
435 You("%s
\82Å
\89ö
\95¨
\82ð
\82È
\82®
\82è
\82Â
\82¯
\82½
\81D", yname(uwep));
436 else if (!cantwield(youmonst.data))
438 You("begin %s monsters with your %s %s.",
439 ing_suffix(Role_if(PM_MONK) ? "strike" : "bash"),
440 uarmg ? "gloved" : "bare", /* Del Lamb */
441 makeplural(body_part(HAND)));
443 You("%s%s
\82Å
\89ö
\95¨
\82ð%s
\82Â
\82¯
\82½
\81D",
444 uarmg ? "
\83O
\83\8d\81[
\83u
\82ð
\95t
\82¯
\82½" : "
\91f",
446 Role_if(PM_MONK) ? "
\91Å
\82¿" : "
\82È
\82®
\82è");
450 exercise(A_STR, TRUE); /* you're exercising muscles */
451 /* andrew@orca: prevent unlimited pick-axe attacks */
454 /* Is the "it died" check actually correct? */
455 if (mdat->mlet == S_LEPRECHAUN && !mtmp->mfrozen && !mtmp->msleeping
456 && !mtmp->mconf && mtmp->mcansee && !rn2(7)
457 && (m_move(mtmp, 0) == 2 /* it died */
458 || mtmp->mx != u.ux + u.dx
459 || mtmp->my != u.uy + u.dy)) /* it moved */
465 (void) hitum(mtmp, youmonst.data->mattk);
466 mtmp->mstrategy &= ~STRAT_WAITMASK;
469 /* see comment in attack_checks() */
470 /* we only need to check for this if we did an attack_checks()
471 * and it returned 0 (it's okay to attack), and the monster didn't
474 if (context.forcefight && mtmp->mhp > 0 && !canspotmon(mtmp)
475 && !glyph_is_invisible(levl[u.ux + u.dx][u.uy + u.dy].glyph)
476 && !(u.uswallow && mtmp == u.ustuck))
477 map_invisible(u.ux + u.dx, u.uy + u.dy);
482 /* really hit target monster; returns TRUE if it still lives */
484 known_hitum(mon, weapon, mhit, rollneeded, armorpenalty, uattk, dieroll)
485 register struct monst *mon;
488 int rollneeded, armorpenalty; /* for monks */
489 struct attack *uattk;
492 register boolean malive = TRUE;
494 if (override_confirmation) {
495 /* this may need to be generalized if weapons other than
496 Stormbringer acquire similar anti-social behavior... */
499 Your("bloodthirsty blade attacks!");
501 Your("
\95\90\8aí
\82Í
\8c\8c\82É
\8bQ
\82¦
\82Ä
\82¢
\82é
\81I");
505 missum(mon, uattk, (rollneeded + armorpenalty > dieroll));
507 int oldhp = mon->mhp, x = u.ux + u.dx, y = u.uy + u.dy;
508 long oldweaphit = u.uconduct.weaphit;
511 if (weapon && (weapon->oclass == WEAPON_CLASS || is_weptool(weapon)))
512 u.uconduct.weaphit++;
514 /* we hit the monster; be careful: it might die or
515 be knocked into a different location */
516 notonhead = (mon->mx != x || mon->my != y);
517 malive = hmon(mon, weapon, HMON_MELEE, dieroll);
519 /* monster still alive */
520 if (!rn2(25) && mon->mhp < mon->mhpmax / 2
521 && !(u.uswallow && mon == u.ustuck)) {
522 /* maybe should regurgitate if swallowed? */
523 monflee(mon, !rn2(3) ? rnd(100) : 0, FALSE, TRUE);
525 if (u.ustuck == mon && !u.uswallow && !sticks(youmonst.data))
528 /* Vorpal Blade hit converted to miss */
529 /* could be headless monster or worm tail */
530 if (mon->mhp == oldhp) {
532 /* a miss does not break conduct */
533 u.uconduct.weaphit = oldweaphit;
535 if (mon->wormno && *mhit)
536 cutworm(mon, x, y, weapon);
542 /* hit the monster next to you and the monsters to the left and right of it;
543 return False if the primary target is killed, True otherwise */
545 hitum_cleave(target, uattk)
546 struct monst *target; /* non-Null; forcefight at nothing doesn't cleave... */
547 struct attack *uattk; /* ... but we don't enforce that here; Null works ok */
549 /* swings will be delivered in alternate directions; with consecutive
550 attacks it will simulate normal swing and backswing; when swings
551 are non-consecutive, hero will sometimes start a series of attacks
552 with a backswing--that doesn't impact actual play, just spoils the
553 simulation attempt a bit */
554 static boolean clockwise = FALSE;
556 int count, umort, x = u.ux, y = u.uy;
558 /* find the direction toward primary target */
559 for (i = 0; i < 8; ++i)
560 if (xdir[i] == u.dx && ydir[i] == u.dy)
563 impossible("hitum_cleave: unknown target direction [%d,%d,%d]?",
565 return TRUE; /* target hasn't been killed */
567 /* adjust direction by two so that loop's increment (for clockwise)
568 or decrement (for counter-clockwise) will point at the spot next
570 i = (i + (clockwise ? 6 : 2)) % 8;
571 umort = u.umortality; /* used to detect life-saving */
574 * Three attacks: adjacent to primary, primary, adjacent on other
575 * side. Primary target must be present or we wouldn't have gotten
576 * here (forcefight at thin air won't 'cleave'). However, the
577 * first attack might kill it (gas spore explosion, weak long worm
578 * occupying both spots) so we don't assume that it's still present
579 * on the second attack.
581 for (count = 3; count > 0; --count) {
583 int tx, ty, tmp, dieroll, mhit, attknum, armorpenalty;
585 /* ++i, wrap 8 to i=0 /or/ --i, wrap -1 to i=7 */
586 i = (i + (clockwise ? 1 : 7)) % 8;
588 tx = x + xdir[i], ty = y + ydir[i]; /* current target location */
593 if (glyph_is_invisible(levl[tx][ty].glyph))
594 (void) unmap_invisible(tx, ty);
598 tmp = find_roll_to_hit(mtmp, uattk->aatyp, uwep,
599 &attknum, &armorpenalty);
601 mhit = (tmp > dieroll);
602 (void) known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty,
604 (void) passive(mtmp, uwep, mhit, !DEADMONSTER(mtmp), AT_WEAP, !uwep);
606 /* stop attacking if weapon is gone or hero got killed and
607 life-saved after passive counter-attack */
608 if (!uwep || u.umortality > umort)
611 /* set up for next time */
612 clockwise = !clockwise; /* alternate */
614 /* return False if primary target died, True otherwise; note: if 'target'
615 was nonNull upon entry then it's still nonNull even if *target died */
616 return (target && DEADMONSTER(target)) ? FALSE : TRUE;
619 /* hit target monster; returns TRUE if it still lives */
623 struct attack *uattk;
625 boolean malive, wep_was_destroyed = FALSE;
626 struct obj *wepbefore = uwep;
627 int armorpenalty, attknum = 0, x = u.ux + u.dx, y = u.uy + u.dy,
628 tmp = find_roll_to_hit(mon, uattk->aatyp, uwep,
629 &attknum, &armorpenalty);
630 int dieroll = rnd(20);
631 int mhit = (tmp > dieroll || u.uswallow);
633 /* Cleaver attacks three spots, 'mon' and one on either side of 'mon';
634 it can't be part of dual-wielding but we guard against that anyway;
635 cleave return value reflects status of primary target ('mon') */
636 if (uwep && uwep->oartifact == ART_CLEAVER && !u.twoweap
637 && !u.uswallow && !u.ustuck && !NODIAG(u.umonnum))
638 return hitum_cleave(mon, uattk);
641 exercise(A_DEX, TRUE);
642 malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll);
643 if (wepbefore && !uwep)
644 wep_was_destroyed = TRUE;
645 (void) passive(mon, uwep, mhit, malive, AT_WEAP, wep_was_destroyed);
647 /* second attack for two-weapon combat; won't occur if Stormbringer
648 overrode confirmation (assumes Stormbringer is primary weapon)
649 or if the monster was killed or knocked to different location */
650 if (u.twoweap && !override_confirmation && malive && m_at(x, y) == mon) {
651 tmp = find_roll_to_hit(mon, uattk->aatyp, uswapwep, &attknum,
654 mhit = (tmp > dieroll || u.uswallow);
655 malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk,
657 /* second passive counter-attack only occurs if second attack hits */
659 (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep);
664 /* general "damage monster" routine; return True if mon still alive */
666 hmon(mon, obj, thrown, dieroll)
669 int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
672 boolean result, anger_guards;
674 anger_guards = (mon->mpeaceful
675 && (mon->ispriest || mon->isshk || is_watch(mon->data)));
676 result = hmon_hitmon(mon, obj, thrown, dieroll);
677 if (mon->ispriest && !rn2(2))
680 (void) angry_guards(!!Deaf);
686 hmon_hitmon(mon, obj, thrown, dieroll)
689 int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
693 struct permonst *mdat = mon->data;
694 int barehand_silver_rings = 0;
695 /* The basic reason we need all these booleans is that we don't want
696 * a "hit" message when a monster dies, so we have to know how much
697 * damage it did _before_ outputting a hit message, but any messages
698 * associated with the damage don't come out until _after_ outputting
701 boolean hittxt = FALSE, destroyed = FALSE, already_killed = FALSE;
702 boolean get_dmg_bonus = TRUE;
703 boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE,
705 boolean silvermsg = FALSE, silverobj = FALSE;
706 boolean valid_weapon_attack = FALSE;
707 boolean unarmed = !uwep && !uarm && !uarms;
708 boolean hand_to_hand = (thrown == HMON_MELEE
709 /* not grapnels; applied implies uwep */
710 || (thrown == HMON_APPLIED && is_pole(uwep)));
715 char unconventional[BUFSZ]; /* substituted for word "attack" in msg */
717 char saved_oname[BUFSZ];
720 unconventional[0] = '\0';
722 saved_oname[0] = '\0';
725 if (!obj) { /* attack with bare hands */
726 if (mdat == &mons[PM_SHADE])
728 else if (martial_bonus())
729 tmp = rnd(4); /* bonus for martial arts */
732 valid_weapon_attack = (tmp > 1);
733 /* blessed gloves give bonuses when fighting 'bare-handed' */
734 if (uarmg && uarmg->blessed
735 && (is_undead(mdat) || is_demon(mdat) || is_vampshifter(mon)))
737 /* So do silver rings. Note: rings are worn under gloves, so you
738 * don't get both bonuses.
741 if (uleft && objects[uleft->otyp].oc_material == SILVER)
742 barehand_silver_rings++;
743 if (uright && objects[uright->otyp].oc_material == SILVER)
744 barehand_silver_rings++;
745 if (barehand_silver_rings && mon_hates_silver(mon)) {
751 Strcpy(saved_oname, cxname(obj));
752 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
753 || obj->oclass == GEM_CLASS) {
754 /* is it not a melee weapon? */
755 if (/* if you strike with a bow... */
757 /* or strike with a missile in your hand... */
758 || (!thrown && (is_missile(obj) || is_ammo(obj)))
759 /* or use a pole at short range and not mounted... */
760 || (!thrown && !u.usteed && is_pole(obj))
761 /* or throw a missile without the proper bow... */
762 || (is_ammo(obj) && (thrown != HMON_THROWN
763 || !ammo_and_launcher(obj, uwep)))) {
764 /* then do only 1-2 points of damage */
765 if (mdat == &mons[PM_SHADE] && !shade_glare(obj))
769 if (objects[obj->otyp].oc_material == SILVER
770 && mon_hates_silver(mon)) {
773 /* if it will already inflict dmg, make it worse */
774 tmp += rnd((tmp) ? 20 : 10);
776 if (!thrown && obj == uwep && obj->otyp == BOOMERANG
777 && rnl(4) == 4 - 1) {
778 boolean more_than_1 = (obj->quan > 1L);
781 pline("As you hit %s, %s%s breaks into splinters.",
782 mon_nam(mon), more_than_1 ? "one of " : "",
785 pline("%s
\82ð
\8dU
\8c\82\82·
\82é
\82Æ
\81C%s%s
\82Í
\82±
\82Á
\82Ï
\82Ý
\82¶
\82ñ
\82É
\82È
\82Á
\82½
\81D",
786 mon_nam(mon), yname(obj),
787 more_than_1 ? "
\82Ì
\82Ð
\82Æ
\82Â" : "");
790 uwepgone(); /* set unweapon */
793 obj = (struct obj *) 0;
795 if (mdat != &mons[PM_SHADE])
799 tmp = dmgval(obj, mon);
800 /* a minimal hit doesn't exercise proficiency */
801 valid_weapon_attack = (tmp > 1);
802 if (!valid_weapon_attack || mon == u.ustuck || u.twoweap
803 /* Cleaver can hit up to three targets at once so don't
804 let it also hit from behind or shatter foes' weapons */
805 || (hand_to_hand && obj->oartifact == ART_CLEAVER)) {
806 ; /* no special bonuses */
807 } else if (mon->mflee && Role_if(PM_ROGUE) && !Upolyd
808 /* multi-shot throwing is too powerful here */
811 You("strike %s from behind!", mon_nam(mon));
813 You("%s
\82ð
\94w
\8cã
\82©
\82ç
\8dU
\8c\82\82µ
\82½
\81I", mon_nam(mon));
814 tmp += rnd(u.ulevel);
816 } else if (dieroll == 2 && obj == uwep
817 && obj->oclass == WEAPON_CLASS
819 || (Role_if(PM_SAMURAI) && obj->otyp == KATANA
821 && ((wtype = uwep_skill_type()) != P_NONE
822 && P_SKILL(wtype) >= P_SKILLED)
823 && ((monwep = MON_WEP(mon)) != 0
824 && !is_flimsy(monwep)
825 && !obj_resists(monwep,
826 50 + 15 * (greatest_erosion(obj)
827 - greatest_erosion(monwep)),
830 * 2.5% chance of shattering defender's weapon when
831 * using a two-handed weapon; less if uwep is rusted.
832 * [dieroll == 2 is most successful non-beheading or
833 * -bisecting hit, in case of special artifact damage;
834 * the percentage chance is (1/20)*(50/100).]
835 * If attacker's weapon is rustier than defender's,
836 * the obj_resists chance is increased so the shatter
837 * chance is decreased; if less rusty, then vice versa.
839 setmnotwielded(mon, monwep);
840 mon->weapon_check = NEED_WEAPON;
842 pline("%s from the force of your blow!",
843 Yobjnam2(monwep, "shatter"));
845 pline("%s
\82Ì%s
\82Í
\82 \82È
\82½
\82Ì
\88ê
\8c\82\82Å
\95²
\81X
\82É
\82È
\82Á
\82½
\81I",
846 Monnam(mon), xname(monwep));
848 m_useupall(mon, monwep);
849 /* If someone just shattered MY weapon, I'd flee! */
851 monflee(mon, d(2, 3), TRUE, TRUE);
857 && artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) {
858 if (mon->mhp <= 0) /* artifact killed monster */
864 if (objects[obj->otyp].oc_material == SILVER
865 && mon_hates_silver(mon)) {
869 if (u.usteed && !thrown && tmp > 0
870 && weapon_type(obj) == P_LANCE && mon != u.ustuck) {
871 jousting = joust(mon, obj);
872 /* exercise skill even for minimal damage hits */
874 valid_weapon_attack = TRUE;
876 if (thrown == HMON_THROWN
877 && (is_ammo(obj) || is_missile(obj))) {
878 if (ammo_and_launcher(obj, uwep)) {
879 /* Elves and Samurai do extra damage using
880 * their bows&arrows; they're highly trained.
882 if (Role_if(PM_SAMURAI) && obj->otyp == YA
883 && uwep->otyp == YUMI)
885 else if (Race_if(PM_ELF) && obj->otyp == ELVEN_ARROW
886 && uwep->otyp == ELVEN_BOW)
889 if (obj->opoisoned && is_poisonable(obj))
893 } else if (obj->oclass == POTION_CLASS) {
895 obj = splitobj(obj, 1L);
897 setuwep((struct obj *) 0);
900 hand_to_hand ? POTHIT_HERO_BASH : POTHIT_HERO_THROW);
902 return FALSE; /* killed */
904 /* in case potion effect causes transformation */
906 tmp = (mdat == &mons[PM_SHADE]) ? 0 : 1;
908 if (mdat == &mons[PM_SHADE] && !shade_aware(obj)) {
911 Strcpy(unconventional, cxname(obj));
915 case BOULDER: /* 1d20 */
916 case HEAVY_IRON_BALL: /* 1d25 */
917 case IRON_CHAIN: /* 1d4+1 */
918 tmp = dmgval(obj, mon);
921 if (breaktest(obj)) {
923 You("break %s. That's bad luck!", ysimple_name(obj));
925 You("%s
\8b¾
\82ð
\89ó
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D
\82±
\82è
\82á
\82Ü
\82¢
\82Á
\82½
\81I", ysimple_name(obj));
928 obj = (struct obj *) 0;
929 unarmed = FALSE; /* avoid obj==0 confusion */
930 get_dmg_bonus = FALSE;
935 case EXPENSIVE_CAMERA:
937 You("succeed in destroying %s. Congratulations!",
939 You("%s
\83J
\83\81\83\89\82ð
\89ó
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82½
\81D
\82¨
\82ß
\82Å
\82Æ
\82¤
\81I",
941 release_camera_demon(obj, u.ux, u.uy);
944 case CORPSE: /* fixed by polder@cs.vu.nl */
945 if (touch_petrifies(&mons[obj->corpsenm])) {
949 You("hit %s with %s.", mon_nam(mon),
950 corpse_xname(obj, (const char *) 0,
951 obj->dknown ? CXN_PFX_THE
954 You("%s
\82ð%s
\82Å
\8dU
\8c\82\82µ
\82½
\81D", mon_nam(mon),
955 corpse_xname(obj, (const char *) 0,
956 obj->dknown ? CXN_PFX_THE
960 if (!munstone(mon, TRUE))
961 minstapetrify(mon, TRUE);
962 if (resists_ston(mon))
964 /* note: hp may be <= 0 even if munstoned==TRUE */
965 return (boolean) (mon->mhp > 0);
967 } else if (touch_petrifies(mdat)) {
968 ; /* maybe turn the corpse into a statue? */
971 tmp = (obj->corpsenm >= LOW_PM ? mons[obj->corpsenm].msize
975 #define useup_eggs(o) \
978 obfree(o, (struct obj *) 0); \
981 o = (struct obj *) 0; \
984 long cnt = obj->quan;
986 tmp = 1; /* nominal physical damage */
987 get_dmg_bonus = FALSE;
988 hittxt = TRUE; /* message always given */
989 /* egg is always either used up or transformed, so next
990 hand-to-hand attack should yield a "bashing" mesg */
993 if (obj->spe && obj->corpsenm >= LOW_PM) {
995 change_luck((schar) - (obj->quan));
1000 if (touch_petrifies(&mons[obj->corpsenm])) {
1001 /*learn_egg_type(obj->corpsenm);*/
1003 pline("Splat! You hit %s with %s %s egg%s!",
1005 obj->known ? "the" : cnt > 1L ? "some" : "a",
1006 obj->known ? mons[obj->corpsenm].mname
1010 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",
1012 cnt > 1L ? "
\82¢
\82
\82Â
\82©
\82Ì" : "",
1013 obj->known ? mons[obj->corpsenm].mname
1016 obj->known = 1; /* (not much point...) */
1018 if (!munstone(mon, TRUE))
1019 minstapetrify(mon, TRUE);
1020 if (resists_ston(mon))
1022 return (boolean) (mon->mhp > 0);
1023 } else { /* ordinary egg(s) */
1026 (obj->corpsenm != NON_PM && obj->known)
1027 ? the(mons[obj->corpsenm].mname)
1028 : (cnt > 1L) ? "some" : "an";
1029 You("hit %s with %s egg%s.", mon_nam(mon), eggp,
1033 (obj->corpsenm != NON_PM && obj->known)
1034 ? mons[obj->corpsenm].mname : "";
1035 You("%s
\82É%s%s
\97\91\82ð
\93\8a\82°
\82Â
\82¯
\82½
\81D",
1036 mon_nam(mon), eggp, *eggp ? "
\82Ì" : "");
1038 if (touch_petrifies(mdat) && !stale_egg(obj)) {
1040 pline_The("egg%s %s alive any more...", plur(cnt),
1041 (cnt == 1L) ? "isn't" : "aren't");
1043 pline("
\82à
\82¤
\97\91\82ª
\9bz
\89»
\82·
\82é
\82±
\82Æ
\82Í
\82È
\82¢
\82¾
\82ë
\82¤
\81D
\81D
\81D");
1046 obj_stop_timers(obj);
1048 obj->oclass = GEM_CLASS;
1051 obj->known = obj->dknown = obj->bknown = 0;
1052 obj->owt = weight(obj);
1054 place_object(obj, mon->mx, mon->my);
1059 pline("
\83r
\83`
\83\83\83b
\81I");
1061 exercise(A_WIS, FALSE);
1067 case CLOVE_OF_GARLIC: /* no effect against demons */
1068 if (is_undead(mdat) || is_vampshifter(mon)) {
1069 monflee(mon, d(2, 4), FALSE, TRUE);
1074 case BLINDING_VENOM:
1076 if (can_blnd(&youmonst, mon,
1077 (uchar) (obj->otyp == BLINDING_VENOM
1083 pline(obj->otyp == CREAM_PIE ? "Splat!"
1086 pline(obj->otyp == CREAM_PIE ? "
\83r
\83V
\83\83\83b
\81I"
1087 : "
\83s
\83`
\83\83\83b
\81I");
1089 } else if (obj->otyp == BLINDING_VENOM) {
1091 pline_The("venom blinds %s%s!", mon_nam(mon),
1092 mon->mcansee ? "" : " further");
1094 pline("
\93Å
\89t
\82Å%s
\82Í%s
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon),
1095 mon->mcansee ? "" : "
\82³
\82ç
\82É");
1098 char *whom = mon_nam(mon);
1099 char *what = The(xname(obj));
1101 if (!thrown && obj->quan > 1L)
1102 what = An(singular(obj, xname));
1103 /* note: s_suffix returns a modifiable buffer */
1105 && mdat != &mons[PM_FLOATING_EYE])
1107 whom = strcat(strcat(s_suffix(whom), " "),
1108 mbodypart(mon, FACE));
1110 whom = strcat(s_suffix(whom),
1111 mbodypart(mon, FACE));
1114 pline("%s %s over %s!", what,
1115 vtense(what, "splash"), whom);
1117 pline("%s
\82Í%s
\82É
\82Ô
\82¿
\82Ü
\82¯
\82ç
\82ê
\82½
\81I",
1121 setmangry(mon, TRUE);
1124 if (((int) mon->mblinded + tmp) > 127)
1125 mon->mblinded = 127;
1127 mon->mblinded += tmp;
1130 pline(obj->otyp == CREAM_PIE ? "Splat!" : "Splash!");
1132 pline(obj->otyp==CREAM_PIE ? "
\83r
\83V
\83\83\83b
\81I" : "
\83s
\83`
\83\83\83b
\81I");
1133 setmangry(mon, TRUE);
1136 obfree(obj, (struct obj *) 0);
1140 get_dmg_bonus = FALSE;
1143 case ACID_VENOM: /* thrown (or spit) */
1144 if (resists_acid(mon)) {
1146 Your("venom hits %s harmlessly.", mon_nam(mon));
1148 pline("
\93Å
\89t
\82Í%s
\82É
\82Í
\8cø
\89Ê
\82ª
\82È
\82©
\82Á
\82½
\81D", mon_nam(mon));
1152 Your("venom burns %s!", mon_nam(mon));
1154 Your("
\93Å
\89t
\82Í%s
\82ð
\8fÄ
\82¢
\82½
\81I", mon_nam(mon));
1155 tmp = dmgval(obj, mon);
1158 obfree(obj, (struct obj *) 0);
1162 get_dmg_bonus = FALSE;
1165 /* non-weapons can damage because of their weight */
1166 /* (but not too much) */
1167 tmp = obj->owt / 100;
1168 if (is_wet_towel(obj)) {
1169 /* wielded wet towel should probably use whip skill
1170 (but not by setting objects[TOWEL].oc_skill==P_WHIP
1171 because that would turn towel into a weptool) */
1173 if (rn2(obj->spe + 1)) /* usually lose some wetness */
1174 dry_a_towel(obj, -1, TRUE);
1183 * Things like silver wands can arrive here so
1184 * so we need another silver check.
1186 if (objects[obj->otyp].oc_material == SILVER
1187 && mon_hates_silver(mon)) {
1197 /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG)
1198 * *OR* if attacking bare-handed!! */
1200 if (get_dmg_bonus && tmp > 0) {
1202 /* If you throw using a propellor, you don't get a strength
1203 * bonus but you do get an increase-damage bonus.
1205 if (thrown != HMON_THROWN || !obj || !uwep
1206 || !ammo_and_launcher(obj, uwep))
1210 if (valid_weapon_attack) {
1213 /* to be valid a projectile must have had the correct projector */
1214 wep = PROJECTILE(obj) ? uwep : obj;
1215 tmp += weapon_dam_bonus(wep);
1216 /* [this assumes that `!thrown' implies wielded...] */
1217 wtype = thrown ? weapon_type(wep) : uwep_skill_type();
1218 use_skill(wtype, 1);
1222 int nopoison = (10 - (obj->owt / 10));
1226 if (Role_if(PM_SAMURAI)) {
1228 You("dishonorably use a poisoned weapon!");
1230 You("
\95s
\96¼
\97_
\82É
\82à
\93Å
\82Ì
\95\90\8aí
\82ð
\8eg
\97p
\82µ
\82½
\81I");
1231 adjalign(-sgn(u.ualign.type));
1232 } else if (u.ualign.type == A_LAWFUL && u.ualign.record > -10) {
1234 You_feel("like an evil coward for using a poisoned weapon.");
1236 You("
\93Å
\82Ì
\95\90\8aí
\82ð
\8eg
\97p
\82·
\82é
\82Ì
\82Í
\94Ú
\8b¯
\82¾
\82Æ
\8a´
\82¶
\82½
\81D");
1239 if (obj && !rn2(nopoison)) {
1240 /* remove poison now in case obj ends up in a bones file */
1241 obj->opoisoned = FALSE;
1242 /* defer "obj is no longer poisoned" until after hit message */
1245 if (resists_poison(mon))
1253 /* make sure that negative damage adjustment can't result
1254 in inadvertently boosting the victim's hit points */
1256 if (mdat == &mons[PM_SHADE]) {
1259 const char *what = *unconventional ? unconventional : "attack";
1261 Your("%s %s harmlessly through %s.", what,
1262 vtense(what, "pass"), mon_nam(mon));
1264 Your("
\8dU
\8c\82\82Í%s
\82ð
\92Ê
\82è
\82Ê
\82¯
\82½
\81D", mon_nam(mon));
1275 tmp += d(2, (obj == uwep) ? 10 : 2); /* [was in dmgval()] */
1277 You("joust %s%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1279 You("%s
\82É
\93Ë
\8c\82\82µ
\82½%s", mon_nam(mon), canseemon(mon) ? exclam(tmp) : "
\81D");
1282 pline("%s shatters on impact!", Yname2(obj));
1284 Your("%s
\82Í
\8fÕ
\8c\82\82Å
\89ó
\82ê
\82½
\81I", xname(obj));
1285 /* (must be either primary or secondary weapon to get here) */
1286 u.twoweap = FALSE; /* untwoweapon() is too verbose here */
1288 uwepgone(); /* set unweapon */
1289 /* minor side-effect: broken lance won't split puddings */
1293 /* avoid migrating a dead monster */
1294 if (mon->mhp > tmp) {
1295 mhurtle(mon, u.dx, u.dy, 1);
1296 mdat = mon->data; /* in case of a polymorph trap */
1297 if (DEADMONSTER(mon))
1298 already_killed = TRUE;
1301 } else if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) {
1302 /* VERY small chance of stunning opponent if unarmed. */
1303 if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) && !bigmonst(mdat)
1304 && !thick_skinned(mdat)) {
1305 if (canspotmon(mon))
1307 pline("%s %s from your powerful strike!", Monnam(mon),
1308 makeplural(stagger(mon->data, "stagger")));
1310 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\89ï
\90S
\82Ì
\88ê
\8c\82\82Å%s
\81I", Monnam(mon),
1311 jpast(stagger(mon->data, "
\82æ
\82ë
\82ß
\82")));
1313 /* avoid migrating a dead monster */
1314 if (mon->mhp > tmp) {
1315 mhurtle(mon, u.dx, u.dy, 1);
1316 mdat = mon->data; /* in case of a polymorph trap */
1317 if (DEADMONSTER(mon))
1318 already_killed = TRUE;
1324 if (!already_killed)
1326 /* adjustments might have made tmp become less than what
1327 a level draining artifact has already done to max HP */
1328 if (mon->mhp > mon->mhpmax)
1329 mon->mhp = mon->mhpmax;
1332 if (mon->mtame && tmp > 0) {
1333 /* do this even if the pet is being killed (affects revival) */
1334 abuse_dog(mon); /* reduces tameness */
1335 /* flee if still alive and still tame; if already suffering from
1336 untimed fleeing, no effect, otherwise increases timed fleeing */
1337 if (mon->mtame && !destroyed)
1338 monflee(mon, 10 * rnd(tmp), FALSE, FALSE);
1340 if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
1341 /* pudding is alive and healthy enough to split */
1342 && mon->mhp > 1 && !mon->mcan
1343 /* iron weapon using melee or polearm hit [3.6.1: metal weapon too;
1344 also allow either or both weapons to cause split when twoweap] */
1345 && obj && (obj == uwep || (u.twoweap && obj == uswapwep))
1346 && ((objects[obj->otyp].oc_material == IRON
1347 /* allow scalpel and tsurugi to split puddings */
1348 || objects[obj->otyp].oc_material == METAL)
1349 /* but not bashing with darts, arrows or ya */
1350 && !(is_ammo(obj) || is_missile(obj)))
1352 if (clone_mon(mon, 0, 0)) {
1353 char withwhat[BUFSZ];
1357 if (u.twoweap && flags.verbose)
1358 Sprintf(withwhat, " with %s", yname(obj));
1359 pline("%s divides as you hit it%s!", Monnam(mon), withwhat);
1361 if (u.twoweap && flags.verbose)
1362 Sprintf(withwhat, "%s
\82Å
\82Ì", yname(obj));
1363 pline("
\82 \82È
\82½
\82Ì%s
\8dU
\8c\82\82Å%s
\82Í
\95ª
\97ô
\82µ
\82½
\81I", withwhat, Monnam(mon));
1369 if (!hittxt /*( thrown => obj exists )*/
1371 || (thrown && m_shot.n > 1 && m_shot.o == obj->otyp))) {
1373 hit(mshot_xname(obj), mon, exclam(tmp));
1374 else if (!flags.verbose)
1378 pline("
\8dU
\8c\82\82Í
\96½
\92\86\82µ
\82½
\81D");
1381 You("%s %s%s", Role_if(PM_BARBARIAN) ? "smite" : "hit",
1382 mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
1384 Your("%s
\82Ö
\82Ì
\8dU
\8c\82\82Í
\96½
\92\86\82µ
\82½%s",
1385 mon_nam(mon), canseemon(mon) ? exclam(tmp) : "
\81D");
1391 char *whom = mon_nam(mon);
1392 char silverobjbuf[BUFSZ];
1394 if (canspotmon(mon)) {
1395 if (barehand_silver_rings == 1)
1397 fmt = "Your silver ring sears %s!";
1399 fmt = "%s
\82Í
\8bâ
\82Ì
\8ew
\97Ö
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1400 else if (barehand_silver_rings == 2)
1402 fmt = "Your silver rings sear %s!";
1404 fmt = "%s
\82Í
\8bâ
\82Ì
\8ew
\97Ö
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1405 else if (silverobj && saved_oname[0]) {
1406 /* guard constructed format string against '%' in
1407 saved_oname[] from xname(via cxname()) */
1409 Sprintf(silverobjbuf, "Your %s%s %s",
1410 strstri(saved_oname, "silver") ? "" : "silver ",
1411 saved_oname, vtense(saved_oname, "sear"));
1413 Sprintf(silverobjbuf, "%%s
\82Í%s%s
\82Å
\8fÄ
\82©
\82ê
\82½
\81I",
1414 strstri(saved_oname, "
\8bâ") ?
1418 (void) strNsubst(silverobjbuf, "%", "%%", 0);
1419 Strcat(silverobjbuf, " %s!");
1423 fmt = "The silver sears %s!";
1425 fmt = "%s
\82Í
\8bâ
\82Å
\8fÄ
\82©
\82ê
\82½
\81I";
1427 *whom = highc(*whom); /* "it" -> "It" */
1429 fmt = "%s is seared!";
1431 fmt = "%s
\82Í
\8fÄ
\82©
\82ê
\82½
\81I";
1433 /* note: s_suffix returns a modifiable buffer */
1434 if (!noncorporeal(mdat) && !amorphous(mdat))
1436 whom = strcat(s_suffix(whom), " flesh");
1438 whom = strcat(s_suffix(whom), "
\93÷");
1441 /* if a "no longer poisoned" message is coming, it will be last;
1442 obj->opoisoned was cleared above and any message referring to
1443 "poisoned <obj>" has now been given; we want just "<obj>" for
1444 last message, so reformat while obj is still accessible */
1446 Strcpy(saved_oname, cxname(obj));
1448 /* [note: thrown obj might go away during killed/xkilled call] */
1452 pline_The("poison doesn't seem to affect %s.", mon_nam(mon));
1454 pline("
\93Å
\82Í%s
\82É
\8cø
\82©
\82È
\82©
\82Á
\82½
\82æ
\82¤
\82¾
\81D", mon_nam(mon));
1457 pline_The("poison was deadly...");
1459 pline("
\93Å
\82Í
\92v
\8e\80\97Ê
\82¾
\82Á
\82½
\81D
\81D
\81D");
1460 if (!already_killed)
1461 xkilled(mon, XKILL_NOMSG);
1462 destroyed = TRUE; /* return FALSE; */
1463 } else if (destroyed) {
1464 if (!already_killed)
1465 killed(mon); /* takes care of most messages */
1466 } else if (u.umconf && hand_to_hand) {
1468 if (!mon->mconf && !resist(mon, SPBOOK_CLASS, 0, NOTELL)) {
1470 if (!mon->mstun && mon->mcanmove && !mon->msleeping
1473 pline("%s appears confused.", Monnam(mon));
1475 pline("%s
\82Í
\8d¬
\97\90\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mon));
1480 Your("%s %s no longer poisoned.", saved_oname,
1481 vtense(saved_oname, "are"));
1483 Your("%s
\82Í
\82à
\82¤
\93Å
\82ª
\93h
\82ç
\82ê
\82Ä
\82¢
\82È
\82¢
\81D", xname(obj));
1486 return destroyed ? FALSE : TRUE;
1496 * The things in this list either
1499 * 2) are dealt with properly by other routines
1500 * when it comes to shades.
1502 if (obj->otyp == BOULDER
1503 || obj->otyp == HEAVY_IRON_BALL
1504 || obj->otyp == IRON_CHAIN /* dmgval handles those first three */
1505 || obj->otyp == MIRROR /* silver in the reflective surface */
1506 || obj->otyp == CLOVE_OF_GARLIC /* causes shades to flee */
1507 || objects[obj->otyp].oc_material == SILVER)
1512 /* check whether slippery clothing protects from hug or wrap attack */
1513 /* [currently assumes that you are the attacker] */
1515 m_slips_free(mdef, mattk)
1517 struct attack *mattk;
1521 if (mattk->adtyp == AD_DRIN) {
1522 /* intelligence drain attacks the head */
1523 obj = which_armor(mdef, W_ARMH);
1525 /* grabbing attacks the body */
1526 obj = which_armor(mdef, W_ARMC); /* cloak */
1528 obj = which_armor(mdef, W_ARM); /* suit */
1530 obj = which_armor(mdef, W_ARMU); /* shirt */
1533 /* if monster's cloak/armor is greased, your grab slips off; this
1534 protection might fail (33% chance) when the armor is cursed */
1535 if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK)
1536 && (!obj->cursed || rn2(3))) {
1539 mattk->adtyp == AD_WRAP ? "slip off of"
1540 : "grab, but cannot hold onto",
1541 s_suffix(mon_nam(mdef)), obj->greased ? "greased" : "slippery",
1542 /* avoid "slippery slippery cloak"
1543 for undiscovered oilskin cloak */
1544 (obj->greased || objects[obj->otyp].oc_name_known)
1546 : cloak_simple_name(obj));
1548 You("%s
\82Ì%s%s%s
\81I",
1549 mon_nam(mdef), obj->greased ? "
\96û
\82Ì
\93h
\82ç
\82ê
\82½" : "
\8a\8a\82è
\82â
\82·
\82¢",
1550 (obj->greased || objects[obj->otyp].oc_name_known)
1552 : cloak_simple_name(obj),
1553 mattk->adtyp == AD_WRAP ? "
\82Å
\8a\8a\82Á
\82½"
1554 : "
\82ð
\82Â
\82©
\82Ü
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª
\81C
\82Å
\82«
\82È
\82©
\82Á
\82½");
1557 if (obj->greased && !rn2(2)) {
1559 pline_The("grease wears off.");
1561 pline("
\96û
\82Í
\97\8e\82¿
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
1569 /* used when hitting a monster with a lance while mounted;
1570 1: joust hit; 0: ordinary hit; -1: joust but break lance */
1573 struct monst *mon; /* target */
1574 struct obj *obj; /* weapon */
1576 int skill_rating, joust_dieroll;
1578 if (Fumbling || Stunned)
1580 /* sanity check; lance must be wielded in order to joust */
1581 if (obj != uwep && (obj != uswapwep || !u.twoweap))
1584 /* if using two weapons, use worse of lance and two-weapon skills */
1585 skill_rating = P_SKILL(weapon_type(obj)); /* lance skill */
1586 if (u.twoweap && P_SKILL(P_TWO_WEAPON_COMBAT) < skill_rating)
1587 skill_rating = P_SKILL(P_TWO_WEAPON_COMBAT);
1588 if (skill_rating == P_ISRESTRICTED)
1589 skill_rating = P_UNSKILLED; /* 0=>1 */
1591 /* odds to joust are expert:80%, skilled:60%, basic:40%, unskilled:20% */
1592 if ((joust_dieroll = rn2(5)) < skill_rating) {
1593 if (joust_dieroll == 0 && rnl(50) == (50 - 1) && !unsolid(mon->data)
1594 && !obj_resists(obj, 0, 100))
1595 return -1; /* hit that breaks lance */
1596 return 1; /* successful joust */
1598 return 0; /* no joust bonus; revert to ordinary attack */
1602 * Send in a demon pet for the hero. Exercise wisdom.
1604 * This function used to be inline to damageum(), but the Metrowerks compiler
1605 * (DR4 and DR4.5) screws up with an internal error 5 "Expression Too
1607 * Pulling it out makes it work.
1613 struct permonst *pm;
1617 pline("Some hell-p has arrived!");
1619 pline("
\92n
\8d\96\82Ì
\92\87\8aÔ
\82ª
\8c»
\82í
\82ê
\82½
\81I");
1620 i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM;
1621 pm = i != NON_PM ? &mons[i] : youmonst.data;
1622 if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0)
1623 (void) tamedog(dtmp, (struct obj *) 0);
1624 exercise(A_WIS, TRUE);
1628 theft_petrifies(otmp)
1631 if (uarmg || otmp->otyp != CORPSE
1632 || !touch_petrifies(&mons[otmp->corpsenm]) || Stone_resistance)
1635 #if 0 /* no poly_when_stoned() critter has theft capability */
1636 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
1637 display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */
1642 /* stealing this corpse is fatal... */
1644 instapetrify(corpse_xname(otmp, "stolen", CXN_ARTICLE));
1646 instapetrify(corpse_xname(otmp, "
\93\90\82Ü
\82ê
\82½", CXN_ARTICLE));
1647 /* apparently wasn't fatal after all... */
1652 * Player uses theft attack against monster.
1654 * If the target is wearing body armor, take all of its possessions;
1655 * otherwise, take one object. [Is this really the behavior we want?]
1658 steal_it(mdef, mattk)
1660 struct attack *mattk;
1662 struct obj *otmp, *stealoid, **minvent_ptr;
1666 return; /* nothing to take */
1668 /* look for worn body armor */
1669 stealoid = (struct obj *) 0;
1670 if (could_seduce(&youmonst, mdef, mattk)) {
1671 /* find armor, and move it to end of inventory in the process */
1672 minvent_ptr = &mdef->minvent;
1673 while ((otmp = *minvent_ptr) != 0)
1674 if (otmp->owornmask & W_ARM) {
1676 panic("steal_it: multiple worn suits");
1677 *minvent_ptr = otmp->nobj; /* take armor out of minvent */
1679 stealoid->nobj = (struct obj *) 0;
1681 minvent_ptr = &otmp->nobj;
1683 *minvent_ptr = stealoid; /* put armor back into minvent */
1686 if (stealoid) { /* we will be taking everything */
1687 if (gender(mdef) == (int) u.mfemale && youmonst.data->mlet == S_NYMPH)
1689 You("charm %s. She gladly hands over her possessions.",
1691 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",
1695 You("seduce %s and %s starts to take off %s clothes.",
1696 mon_nam(mdef), mhe(mdef), mhis(mdef));
1698 You("%s
\82ð
\97U
\98f
\82µ
\82½
\81D%s
\82Í
\95\9e\82ð
\92E
\82¬
\82Í
\82¶
\82ß
\82½
\81D",
1699 mon_nam(mdef), mhe(mdef));
1703 while ((otmp = mdef->minvent) != 0) {
1705 break; /* no longer have ability to steal */
1706 /* take the object away from the monster */
1707 obj_extract_self(otmp);
1708 if ((unwornmask = otmp->owornmask) != 0L) {
1709 mdef->misc_worn_check &= ~unwornmask;
1710 if (otmp->owornmask & W_WEP)
1711 setmnotwielded(mdef, otmp);
1712 otmp->owornmask = 0L;
1713 update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1715 if (otmp == stealoid) /* special message for final item */
1717 pline("%s finishes taking off %s suit.", Monnam(mdef),
1720 pline("%s
\82Í
\92E
\82¬
\8fI
\82¦
\82½
\81D", Monnam(mdef));
1723 /* give the object to the character */
1725 otmp = hold_another_object(otmp, "You snatched but dropped %s.",
1726 doname(otmp), "You steal: ");
1728 otmp = hold_another_object(otmp, "
\82 \82È
\82½
\82Í%s
\82ð
\93\90\82ñ
\82¾
\82ª
\97\8e\82Æ
\82µ
\82½
\81D",
1729 doname(otmp), "
\82ð
\93\90\82ñ
\82¾
\81D");
1731 if (otmp->where != OBJ_INVENT)
1733 if (theft_petrifies(otmp))
1734 break; /* stop thieving even though hero survived */
1735 /* more take-away handling, after theft message */
1736 if (unwornmask & W_WEP) { /* stole wielded weapon */
1737 possibly_unwield(mdef, FALSE);
1738 } else if (unwornmask & W_ARMG) { /* stole worn gloves */
1739 mselftouch(mdef, (const char *) 0, TRUE);
1740 if (mdef->mhp <= 0) /* it's now a statue */
1741 return; /* can't continue stealing */
1745 break; /* only taking one item */
1750 damageum(mdef, mattk)
1751 register struct monst *mdef;
1752 register struct attack *mattk;
1754 register struct permonst *pd = mdef->data;
1755 int armpro, tmp = d((int) mattk->damn, (int) mattk->damd);
1758 armpro = magic_negation(mdef);
1759 /* since hero can't be cancelled, only defender's armor applies */
1760 negated = !(rn2(10) >= 3 * armpro);
1762 if (is_demon(youmonst.data) && !rn2(13) && !uwep
1763 && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
1764 && u.umonnum != PM_BALROG) {
1768 switch (mattk->adtyp) {
1772 pline("%s %s for a moment.", Monnam(mdef),
1773 makeplural(stagger(pd, "stagger")));
1775 pline("%s
\82Í
\88ê
\8fu%s
\81D", Monnam(mdef),
1776 jpast(stagger(pd, "
\82æ
\82ë
\82ß
\82")));
1788 case AD_WERE: /* no special effect on monsters */
1789 case AD_HEAL: /* likewise */
1792 if (mattk->aatyp == AT_WEAP) {
1795 } else if (mattk->aatyp == AT_KICK) {
1796 if (thick_skinned(pd))
1798 if (pd == &mons[PM_SHADE]) {
1799 if (!(uarmf && uarmf->blessed)) {
1800 impossible("bad shade attack function flow?");
1803 tmp = rnd(4); /* bless damage */
1805 /* add ring(s) of increase damage */
1806 if (u.udaminc > 0) {
1807 /* applies even if damage was 0 */
1809 } else if (tmp > 0) {
1810 /* ring(s) might be negative; avoid converting
1811 0 to non-0 or positive to non-positive */
1825 pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
1827 pline("%s
\82Í%s
\81I", Monnam(mdef), on_fire(mdef->data, mattk));
1828 if (completelyburns(pd)) { /* paper golem or straw golem */
1831 pline("%s burns completely!", Monnam(mdef));
1833 pline("%s
\82Í
\8a®
\91S
\82É
\94R
\82¦
\90s
\82«
\82½
\81I", Monnam(mdef));
1835 You("smell burning%s.",
1836 (pd == &mons[PM_PAPER_GOLEM]) ? " paper"
1837 : (pd == &mons[PM_STRAW_GOLEM]) ? " straw" : "");
1838 xkilled(mdef, XKILL_NOMSG | XKILL_NOCORPSE);
1841 /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
1843 tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
1844 tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
1845 if (resists_fire(mdef)) {
1848 pline_The("fire doesn't heat %s!", mon_nam(mdef));
1850 pline("
\89\8a\82Í%s
\82É
\89e
\8b¿
\82ª
\82È
\82¢
\81I", mon_nam(mdef));
1851 golemeffects(mdef, AD_FIRE, tmp);
1852 shieldeff(mdef->mx, mdef->my);
1855 /* only potions damage resistant players in destroy_item */
1856 tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
1865 pline("%s is covered in frost!", Monnam(mdef));
1867 pline("%s
\82Í
\95X
\82Å
\95¢
\82í
\82ê
\82½
\81I", Monnam(mdef));
1868 if (resists_cold(mdef)) {
1869 shieldeff(mdef->mx, mdef->my);
1872 pline_The("frost doesn't chill %s!", mon_nam(mdef));
1874 pline("
\95X
\82Í%s
\82ð
\93\80\82ç
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I", mon_nam(mdef));
1875 golemeffects(mdef, AD_COLD, tmp);
1878 tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
1887 pline("%s is zapped!", Monnam(mdef));
1889 pline("%s
\82Í
\93d
\8c\82\82ð
\82
\82ç
\82Á
\82½
\81I", Monnam(mdef));
1890 tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
1891 if (resists_elec(mdef)) {
1894 pline_The("zap doesn't shock %s!", mon_nam(mdef));
1896 pline("
\93d
\8c\82\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82¢
\81I", mon_nam(mdef));
1897 golemeffects(mdef, AD_ELEC, tmp);
1898 shieldeff(mdef->mx, mdef->my);
1901 /* only rings damage resistant players in destroy_item */
1902 tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
1905 if (resists_acid(mdef))
1909 if (!munstone(mdef, TRUE))
1910 minstapetrify(mdef, TRUE);
1916 steal_it(mdef, mattk);
1920 /* This you as a leprechaun, so steal
1921 real gold only, no lesser coins */
1923 struct obj *mongold = findgold(mdef->minvent);
1925 obj_extract_self(mongold);
1926 if (merge_choice(invent, mongold) || inv_cnt(FALSE) < 52) {
1929 Your("purse feels heavier.");
1931 You("
\8dà
\95z
\82ª
\8fd
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
1934 You("grab %s's gold, but find no room in your knapsack.",
1936 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",
1942 exercise(A_DEX, TRUE);
1948 if (!negated && tmp < mdef->mhp) {
1951 canseemon(mdef) || (u.uswallow && u.ustuck == mdef);
1952 /* record the name before losing sight of monster */
1953 Strcpy(nambuf, Monnam(mdef));
1954 if (u_teleport_mon(mdef, FALSE) && u_saw_mon
1955 && !(canseemon(mdef) || (u.uswallow && u.ustuck == mdef)))
1957 pline("%s suddenly disappears!", nambuf);
1959 pline("%s
\82Í
\93Ë
\91R
\8fÁ
\82¦
\82½
\81I", nambuf);
1963 if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj *) 0)) {
1964 if (!Blind && mdef->mcansee)
1966 pline("%s is blinded.", Monnam(mdef));
1968 pline("%s
\82Í
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81D", Monnam(mdef));
1970 tmp += mdef->mblinded;
1973 mdef->mblinded = tmp;
1978 if (night() && !rn2(10) && !mdef->mcan) {
1979 if (pd == &mons[PM_CLAY_GOLEM]) {
1982 pline("Some writing vanishes from %s head!",
1983 s_suffix(mon_nam(mdef)));
1985 pline("%s
\82Ì
\93ª
\82É
\8f\91\82¢
\82Ä
\82 \82é
\95¶
\8e\9a\82Ì
\82¢
\82
\82Â
\82©
\82ª
\8fÁ
\82¦
\82½
\81I",
1988 xkilled(mdef, XKILL_NOMSG);
1989 /* Don't return yet; keep hp<1 and tmp=0 for pet msg */
1995 You("
\82
\82·
\82
\82·
\8fÎ
\82Á
\82½
\81D");
2001 if (!negated && !rn2(3) && !resists_drli(mdef)) {
2005 pline("%s suddenly seems weaker!", Monnam(mdef));
2007 pline("%s
\82Í
\93Ë
\91R
\8eã
\82
\82È
\82Á
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82½
\81I", Monnam(mdef));
2008 mdef->mhpmax -= xtmp;
2010 /* !m_lev: level 0 monster is killed regardless of hit points
2011 rather than drop to level -1 */
2012 if (mdef->mhp <= 0 || !mdef->m_lev) {
2014 pline("%s dies!", Monnam(mdef));
2016 pline("%s
\82Í
\8e\80\82ñ
\82¾
\81I", Monnam(mdef));
2017 xkilled(mdef, XKILL_NOMSG);
2024 if (pd == &mons[PM_IRON_GOLEM]) {
2026 pline("%s falls to pieces!", Monnam(mdef));
2028 pline("%s
\82Í
\83o
\83\89\83o
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2029 xkilled(mdef, XKILL_NOMSG);
2031 erode_armor(mdef, ERODE_RUST);
2035 erode_armor(mdef, ERODE_CORRODE);
2039 if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) {
2041 pline("%s falls to pieces!", Monnam(mdef));
2043 pline("%s
\82Í
\83o
\83\89\83o
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2044 xkilled(mdef, XKILL_NOMSG);
2046 erode_armor(mdef, ERODE_ROT);
2050 if (!negated && !rn2(4))
2051 xdrainenergym(mdef, TRUE);
2057 if (!negated && !rn2(8)) {
2059 Your("%s was poisoned!", mpoisons_subj(&youmonst, mattk));
2061 Your("%s
\82Í
\93Å
\82³
\82ê
\82Ä
\82¢
\82é
\81I", mpoisons_subj(&youmonst, mattk));
2062 if (resists_poison(mdef))
2064 pline_The("poison doesn't seem to affect %s.", mon_nam(mdef));
2066 pline("
\93Å
\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82¢
\81D", mon_nam(mdef));
2070 Your("poison was deadly...");
2072 Your("
\97^
\82¦
\82½
\93Å
\82Í
\92v
\8e\80\97Ê
\82¾
\82Á
\82½
\81D
\81D
\81D");
2082 if (notonhead || !has_head(pd)) {
2084 pline("%s doesn't seem harmed.", Monnam(mdef));
2086 pline("%s
\82Í
\8f\9d\82Â
\82¢
\82½
\82æ
\82¤
\82É
\82Í
\8c©
\82¦
\82È
\82¢
\81D", Monnam(mdef));
2088 if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) {
2091 You("suck in some slime and don't feel very well.");
2093 You("
\83X
\83\89\83C
\83\80\82ð
\8bz
\82¢
\8eæ
\82Á
\82Ä
\81C
\8bï
\8d\87\82ª
\88«
\82
\82È
\82Á
\82½
\81D");
2094 make_slimed(10L, (char *) 0);
2099 if (m_slips_free(mdef, mattk))
2102 if ((helmet = which_armor(mdef, W_ARMH)) != 0 && rn2(8)) {
2104 pline("%s %s blocks your attack to %s head.",
2105 s_suffix(Monnam(mdef)), helm_simple_name(helmet),
2108 pline("%s
\82Ì%s
\82ª
\93ª
\82Ö
\82Ì
\8dU
\8c\82\82ð
\96h
\82¢
\82¾
\81D",
2109 Monnam(mdef), helm_simple_name(helmet));
2114 (void) eat_brains(&youmonst, mdef, TRUE, &tmp);
2118 if (!negated && !sticks(pd))
2119 u.ustuck = mdef; /* it's now stuck to you */
2123 if (!u.ustuck && !rn2(10)) {
2124 if (m_slips_free(mdef, mattk)) {
2128 You("swing yourself around %s!", mon_nam(mdef));
2130 You("%s
\82É
\90g
\91Ì
\82ð
\97\8d\82Ý
\82Â
\82©
\82¹
\82½
\81I", mon_nam(mdef));
2133 } else if (u.ustuck == mdef) {
2134 /* Monsters don't wear amulets of magical breathing */
2135 if (is_pool(u.ux, u.uy) && !is_swimmer(pd)
2136 && !amphibious(pd)) {
2138 You("drown %s...", mon_nam(mdef));
2140 You("%s
\82ð
\93M
\82ê
\82³
\82¹
\82½
\81D
\81D
\81D", mon_nam(mdef));
2142 } else if (mattk->aatyp == AT_HUGS)
2144 pline("%s is being crushed.", Monnam(mdef));
2146 pline("%s
\82Í
\89\9f\82µ
\82Â
\82Ô
\82³
\82ê
\82Ä
\82¢
\82é
\81D", Monnam(mdef));
2151 You("brush against %s %s.", s_suffix(mon_nam(mdef)),
2152 mbodypart(mdef, LEG));
2154 You("%s
\82Ì%s
\82É
\90G
\82ê
\82½
\81D", mon_nam(mdef),
2155 mbodypart(mdef, LEG));
2162 if (!negated && mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) {
2165 pline("%s is frozen by you!", Monnam(mdef));
2167 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\82É
\82ç
\82Ý
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", Monnam(mdef));
2168 paralyze_monst(mdef, rnd(10));
2172 if (!negated && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) {
2175 pline("%s is put to sleep by you!", Monnam(mdef));
2177 pline("%s
\82Í
\93Ë
\91R
\96°
\82è
\82É
\82¨
\82¿
\82½
\81I", Monnam(mdef));
2183 break; /* physical damage only */
2184 if (!rn2(4) && !slimeproof(pd)) {
2185 if (!munslime(mdef, TRUE) && mdef->mhp > 0) {
2186 /* this assumes newcham() won't fail; since hero has
2187 a slime attack, green slimes haven't been geno'd */
2189 You("turn %s into slime.", mon_nam(mdef));
2191 pline("%s
\82Í
\83X
\83\89\83C
\83\80\82É
\82È
\82Á
\82½
\81D", mon_nam(mdef));
2192 if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE))
2195 /* munslime attempt could have been fatal */
2197 return 2; /* skip death message */
2201 case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
2202 /* there's no msomearmor() function, so just do damage */
2203 /* if (negated) break; */
2206 if (!negated && mdef->mspeed != MSLOW) {
2207 unsigned int oldspeed = mdef->mspeed;
2209 mon_adjust_speed(mdef, -1, (struct obj *) 0);
2210 if (mdef->mspeed != oldspeed && canseemon(mdef))
2212 pline("%s slows down.", Monnam(mdef));
2214 pline("%s
\82Í
\82Ì
\82ë
\82
\82È
\82Á
\82½
\81D", Monnam(mdef));
2219 if (canseemon(mdef))
2221 pline("%s looks confused.", Monnam(mdef));
2223 pline("%s
\82Í
\8d¬
\97\90\82µ
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2232 mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */
2234 if (mdef->mhp < 1) {
2235 if (mdef->mtame && !cansee(mdef->mx, mdef->my)) {
2237 You_feel("embarrassed for a moment.");
2239 You("
\82µ
\82Î
\82ç
\82
\8d¢
\98f
\82µ
\82½
\81D");
2241 xkilled(mdef, XKILL_NOMSG); /* !tmp but hp<1: already killed */
2242 } else if (!flags.verbose) {
2246 You("
\93|
\82µ
\82½
\81I");
2248 xkilled(mdef, XKILL_NOMSG);
2258 register struct monst *mdef;
2259 register struct attack *mattk;
2261 register int tmp = d((int) mattk->damn, (int) mattk->damd);
2266 You("
\94\9a\94
\82µ
\82½
\81I");
2267 switch (mattk->adtyp) {
2268 boolean resistance; /* only for cold/fire/elec */
2271 if (!resists_blnd(mdef)) {
2273 pline("%s is blinded by your flash of light!", Monnam(mdef));
2275 pline("%s
\82Í
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I", Monnam(mdef));
2276 mdef->mblinded = min((int) mdef->mblinded + tmp, 127);
2281 if (haseyes(mdef->data) && mdef->mcansee) {
2283 pline("%s is affected by your flash of light!", Monnam(mdef));
2285 pline("%s
\82Í
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\89e
\8b¿
\82ð
\8eó
\82¯
\82½
\81I", Monnam(mdef));
2290 resistance = resists_cold(mdef);
2293 resistance = resists_fire(mdef);
2296 resistance = resists_elec(mdef);
2300 pline("%s gets blasted!", Monnam(mdef));
2302 pline("%s
\82Í
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I", Monnam(mdef));
2304 if (mdef->mhp <= 0) {
2309 shieldeff(mdef->mx, mdef->my);
2310 if (is_golem(mdef->data))
2311 golemeffects(mdef, (int) mattk->adtyp, tmp);
2314 pline_The("blast doesn't seem to affect %s.", mon_nam(mdef));
2316 pline("
\94\9a\94
\82Í%s
\82É
\89e
\8b¿
\82ð
\97^
\82¦
\82È
\82©
\82Á
\82½
\82æ
\82¤
\82¾
\81D", mon_nam(mdef));
2330 map_location(u.ux, u.uy, TRUE);
2331 tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst));
2332 tmp_at(mdef->mx, mdef->my);
2335 You("engulf %s!", mon_nam(mdef));
2337 You("%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82¾
\81I", mon_nam(mdef));
2346 tmp_at(DISP_END, 0);
2353 register struct monst *mdef;
2354 register struct attack *mattk;
2356 #ifdef LINT /* static char msgbuf[BUFSZ]; */
2359 static char msgbuf[BUFSZ]; /* for nomovemsg */
2362 register int dam = d((int) mattk->damn, (int) mattk->damd);
2365 struct permonst *pd = mdef->data;
2367 /* Not totally the same as for real monsters. Specifically, these
2368 * don't take multiple moves. (It's just too hard, for too little
2369 * result, to program monsters which attack from inside you, which
2370 * would be necessary if done accurately.) Instead, we arbitrarily
2371 * kill the monster immediately for AD_DGST and we regurgitate them
2372 * after exactly 1 round of attack otherwise. -KAA
2375 if (!engulf_target(&youmonst, mdef))
2378 if (u.uhunger < 1500 && !u.uswallow) {
2379 for (otmp = mdef->minvent; otmp; otmp = otmp->nobj)
2380 (void) snuff_lit(otmp);
2382 /* force vampire in bat, cloud, or wolf form to revert back to
2383 vampire form now instead of dealing with that when it dies */
2384 if (is_vampshifter(mdef)
2385 && newcham(mdef, &mons[mdef->cham], FALSE, FALSE)) {
2387 You("engulf it, then expel it.");
2389 You("
\88ù
\82Ý
\8d\9e\82ñ
\82Å
\81C
\93f
\82«
\8fo
\82µ
\82½
\81D");
2390 if (canspotmon(mdef))
2392 pline("It turns into %s.", a_monnam(mdef));
2394 pline("
\82»
\82ê
\82Í%s
\82É
\82È
\82Á
\82½
\81D", a_monnam(mdef));
2396 map_invisible(mdef->mx, mdef->my);
2400 /* engulfing a cockatrice or digesting a Rider or Medusa */
2401 fatal_gulp = (touch_petrifies(pd) && !Stone_resistance)
2402 || (mattk->adtyp == AD_DGST
2403 && (is_rider(pd) || (pd == &mons[PM_MEDUSA]
2404 && !Stone_resistance)));
2406 if ((mattk->adtyp == AD_DGST && !Slow_digestion) || fatal_gulp)
2407 eating_conducts(pd);
2409 if (fatal_gulp && !is_rider(pd)) { /* petrification */
2411 const char *mname = pd->mname;
2413 if (!type_is_pname(pd))
2416 You("englut %s.", mon_nam(mdef));
2418 You("%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82¾
\81D", mon_nam(mdef));
2420 Sprintf(kbuf, "swallowing %s whole", mname);
2422 Sprintf(kbuf, "%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82Å", mname);
2426 switch (mattk->adtyp) {
2428 /* eating a Rider or its corpse is fatal */
2431 pline("Unfortunately, digesting any of it is fatal.");
2433 pline("
\8ec
\94O
\82È
\82ª
\82ç
\81C
\82»
\82ê
\82ð
\90H
\82×
\82é
\82Ì
\82Í
\92v
\96½
\93I
\82È
\8aÔ
\88á
\82¢
\82¾
\81D");
2436 Sprintf(killer.name, "unwisely tried to eat %s",
2438 killer.format = NO_KILLER_PREFIX;
2440 Sprintf(killer.name, "
\8bð
\82©
\82É
\82à%s
\82ð
\90H
\82×
\82æ
\82¤
\82Æ
\82µ
\82Ä",
2442 killer.format = KILLED_BY;
2445 return 0; /* lifesaved */
2448 if (Slow_digestion) {
2453 /* Use up amulet of life saving */
2454 if (!!(otmp = mlifesaver(mdef)))
2455 m_useup(mdef, otmp);
2458 /* start_engulf() issues "you engulf <mdef>" above; this
2459 used to specify XKILL_NOMSG but we need "you kill <mdef>"
2460 in case we're also going to get "welcome to level N+1";
2461 "you totally digest <mdef>" will be coming soon (after
2462 several turns) but the level-gain message seems out of
2463 order if the kill message is left implicit */
2464 xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE);
2465 if (mdef->mhp > 0) { /* monster lifesaved */
2467 You("hurriedly regurgitate the sizzling in your %s.",
2469 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",
2470 body_part(STOMACH));
2472 tmp = 1 + (pd->cwt >> 8);
2473 if (corpse_chance(mdef, &youmonst, TRUE)
2474 && !(mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) {
2475 /* nutrition only if there can be a corpse */
2476 u.uhunger += (pd->cnutrit + 1) / 2;
2480 Sprintf(msgbuf, "You totally digest %s.", mon_nam(mdef));
2482 Sprintf(msgbuf, "
\82 \82È
\82½
\82Í%s
\82ð
\8a®
\91S
\82É
\8fÁ
\89»
\82µ
\82½
\81D", mon_nam(mdef));
2484 /* setting afternmv = end_engulf is tempting,
2485 * but will cause problems if the player is
2486 * attacked (which uses his real location) or
2487 * if his See_invisible wears off
2490 You("digest %s.", mon_nam(mdef));
2492 You("%s
\82ð
\8fÁ
\89»
\82µ
\82Ä
\82¢
\82é
\81D", mon_nam(mdef));
2497 multi_reason = "digesting something";
2499 multi_reason = "
\8fÁ
\89»
\92\86\82É";
2503 if (pd == &mons[PM_GREEN_SLIME]) {
2505 Sprintf(msgbuf, "%s isn't sitting well with you.",
2507 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",
2510 make_slimed(5L, (char *) 0);
2513 exercise(A_CON, TRUE);
2518 if (youmonst.data == &mons[PM_FOG_CLOUD]) {
2520 pline("%s is laden with your moisture.", Monnam(mdef));
2522 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\8e¼
\8bC
\82É
\8bê
\82µ
\82ß
\82ç
\82ê
\82Ä
\82¢
\82é
\81D", Monnam(mdef));
2523 if (amphibious(pd) && !flaming(pd)) {
2526 pline("%s seems unharmed.", Monnam(mdef));
2528 pline("%s
\82Í
\8f\9d\82Â
\82¢
\82Ä
\82¢
\82È
\82¢
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2532 pline("%s is pummeled with your debris!", Monnam(mdef));
2534 pline("%s
\82Í
\8a¢âI
\82Å
\92É
\82ß
\82Â
\82¯
\82ç
\82ê
\82½
\81I", Monnam(mdef));
2538 pline("%s is covered with your goo!", Monnam(mdef));
2540 pline("%s
\82Í
\82Ë
\82Î
\82Â
\82
\82à
\82Ì
\82Å
\95¢
\82í
\82ê
\82½
\81I", Monnam(mdef));
2541 if (resists_acid(mdef)) {
2543 pline("It seems harmless to %s.", mon_nam(mdef));
2545 pline("
\82µ
\82©
\82µ
\81C%s
\82Í
\82È
\82ñ
\82Æ
\82à
\82È
\82¢
\81D", mon_nam(mdef));
2550 if (can_blnd(&youmonst, mdef, mattk->aatyp,
2551 (struct obj *) 0)) {
2554 pline("%s can't see in there!", Monnam(mdef));
2556 pline("%s
\82Í
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mdef));
2558 dam += mdef->mblinded;
2561 mdef->mblinded = dam;
2568 pline_The("air around %s crackles with electricity.",
2570 pline("%s
\82Ì
\89ñ
\82è
\82Ì
\8bó
\8bC
\82Í
\93d
\8bC
\82Å
\83s
\83\8a\83s
\83\8a\82µ
\82Ä
\82¢
\82é
\81D",
2572 if (resists_elec(mdef)) {
2574 pline("%s seems unhurt.", Monnam(mdef));
2576 pline("
\82µ
\82©
\82µ
\81C%s
\82Í
\95½
\8bC
\82È
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2579 golemeffects(mdef, (int) mattk->adtyp, dam);
2585 if (resists_cold(mdef)) {
2587 pline("%s seems mildly chilly.", Monnam(mdef));
2589 pline("%s
\82Í
\97â
\82¦
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2593 pline("%s is freezing to death!", Monnam(mdef));
2595 pline("%s
\82Í
\93\80\8e\80\82µ
\82»
\82¤
\82¾
\81I", Monnam(mdef));
2596 golemeffects(mdef, (int) mattk->adtyp, dam);
2602 if (resists_fire(mdef)) {
2604 pline("%s seems mildly hot.", Monnam(mdef));
2606 pline("%s
\82Í
\92g
\82©
\82
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mdef));
2610 pline("%s is burning to a crisp!", Monnam(mdef));
2612 pline("%s
\82Í
\94R
\82¦
\82Ä
\83J
\83\89\83J
\83\89\82É
\82È
\82Á
\82½
\81I", Monnam(mdef));
2613 golemeffects(mdef, (int) mattk->adtyp, dam);
2619 xdrainenergym(mdef, TRUE);
2625 if (mdef->mhp <= 0) {
2627 if (mdef->mhp <= 0) /* not lifesaved */
2631 You("%s %s!", is_animal(youmonst.data) ? "regurgitate" : "expel",
2634 You("%s
\82ð%s
\82µ
\82½
\81I", mon_nam(mdef),
2635 is_animal(youmonst.data) ? "
\93f
\82«
\96ß" : "
\94r
\8fo");
2637 if (Slow_digestion || is_animal(youmonst.data)) {
2639 pline("Obviously, you didn't like %s taste.",
2640 s_suffix(mon_nam(mdef)));
2642 pline("
\82Ç
\82¤
\82à%s
\82Ì
\96¡
\82Í
\8dD
\82«
\82É
\82È
\82ê
\82È
\82¢
\81D",
2652 missum(mdef, mattk, wouldhavehit)
2653 register struct monst *mdef;
2654 register struct attack *mattk;
2655 boolean wouldhavehit;
2657 if (wouldhavehit) /* monk is missing due to penalty for wearing suit */
2659 Your("armor is rather cumbersome...");
2661 Your("
\96h
\8bï
\82Í
\8f
\82µ
\8e×
\96\82\82¾
\81D
\81D
\81D");
2663 if (could_seduce(&youmonst, mdef, mattk))
2665 You("pretend to be friendly to %s.", mon_nam(mdef));
2667 You("%s
\82É
\97F
\8dD
\93I
\82È
\82Ó
\82è
\82ð
\82µ
\82½
\81D", mon_nam(mdef));
2668 else if (canspotmon(mdef) && flags.verbose)
2670 You("miss %s.", mon_nam(mdef));
2672 Your("%s
\82Ö
\82Ì
\8dU
\8c\82\82Í
\8aO
\82ê
\82½
\81D", mon_nam(mdef));
2677 Your("
\89½
\8eÒ
\82©
\82Ö
\82Ì
\8dU
\8c\82\82Í
\8aO
\82ê
\82½
\81D");
2678 if (!mdef->msleeping && mdef->mcanmove)
2682 /* attack monster as a monster. */
2685 register struct monst *mon;
2687 struct attack *mattk, alt_attk;
2688 struct obj *weapon, **originalweapon;
2689 boolean altwep = FALSE, weapon_used = FALSE;
2690 int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
2693 for (i = 0; i < NATTK; i++) {
2695 mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
2697 switch (mattk->aatyp) {
2700 /* Certain monsters don't use weapons when encountered as enemies,
2701 * but players who polymorph into them have hands or claws and
2702 * thus should be able to use weapons. This shouldn't prohibit
2703 * the use of most special abilities, either.
2704 * If monster has multiple claw attacks, only one can use weapon.
2707 /* Potential problem: if the monster gets multiple weapon attacks,
2708 * we currently allow the player to get each of these as a weapon
2709 * attack. Is this really desirable?
2711 /* approximate two-weapon mode; known_hitum() -> hmon() -> &c
2712 might destroy the weapon argument, but it might also already
2713 be Null, and we want to track that for passive() */
2714 originalweapon = (altwep && uswapwep) ? &uswapwep : &uwep;
2715 if (uswapwep /* set up 'altwep' flag for next iteration */
2716 /* only switch to uswapwep if it's a weapon */
2717 && (uswapwep->oclass == WEAPON_CLASS || is_weptool(uswapwep))
2718 /* only switch if uswapwep is not bow, arrows, or darts */
2719 && !(is_launcher(uswapwep) || is_ammo(uswapwep)
2720 || is_missile(uswapwep))) /* dart, shuriken, boomerang */
2721 altwep = !altwep; /* toggle for next attack */
2722 weapon = *originalweapon;
2723 if (!weapon) /* no need to go beyond no-gloves to rings; not ...*/
2724 originalweapon = &uarmg; /*... subject to erosion damage */
2726 tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
2729 dhit = (tmp > dieroll || u.uswallow);
2730 /* Enemy dead, before any special abilities used */
2731 if (!known_hitum(mon, weapon, &dhit, tmp,
2732 armorpenalty, mattk, dieroll)) {
2737 /* originalweapon points to an equipment slot which might
2738 now be empty if the weapon was destroyed during the hit;
2739 passive(,weapon,...) won't call passive_obj() in that case */
2740 weapon = *originalweapon; /* might receive passive erosion */
2741 /* might be a worm that gets cut in half */
2742 if (m_at(u.ux + u.dx, u.uy + u.dy) != mon)
2743 return (boolean) (nsum != 0);
2744 /* Do not print "You hit" message, since known_hitum
2747 if (dhit && mattk->adtyp != AD_SPEL && mattk->adtyp != AD_PHYS)
2748 sum[i] = damageum(mon, mattk);
2751 if (uwep && !cantwield(youmonst.data) && !weapon_used)
2755 if (uwep && youmonst.data->mlet == S_LICH && !weapon_used)
2763 tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
2764 &attknum, &armorpenalty);
2766 dhit = (tmp > dieroll || u.uswallow);
2771 && (compat = could_seduce(&youmonst, mon, mattk))) {
2774 mon->mcansee && haseyes(mon->data) ? "smile at"
2777 compat == 2 ? "engagingly" : "seductively");
2779 You("%s
\82Ö%s%s
\81D",
2781 compat == 2 ? "
\96£
\97Í
\93I
\82É" : "
\97U
\98f
\93I
\82É",
2782 mon->mcansee && haseyes(mon->data) ? "
\94÷
\8fÎ
\82Ý
\82©
\82¯
\82½"
2783 : "
\98b
\82µ
\82©
\82¯
\82½");
2785 /* doesn't anger it; no wakeup() */
2786 sum[i] = damageum(mon, mattk);
2790 /* maybe this check should be in damageum()? */
2791 if (mon->data == &mons[PM_SHADE]
2792 && !(mattk->aatyp == AT_KICK && uarmf
2793 && uarmf->blessed)) {
2795 Your("attack passes harmlessly through %s.",
2797 Your("
\8dU
\8c\82\82Í%s
\82ð
\82·
\82Á
\82Æ
\92Ê
\82è
\82Ê
\82¯
\82½
\81D",
2801 if (mattk->aatyp == AT_KICK)
2803 You("kick %s.", mon_nam(mon));
2805 You("%s
\82ð
\8fR
\82Á
\82½
\81D", mon_nam(mon));
2806 else if (mattk->aatyp == AT_BITE)
2808 You("bite %s.", mon_nam(mon));
2810 You("%s
\82É
\8a\9a\82Ý
\82Â
\82¢
\82½
\81D", mon_nam(mon));
2811 else if (mattk->aatyp == AT_STNG)
2813 You("sting %s.", mon_nam(mon));
2815 You("%s
\82É
\93Ë
\82«
\82³
\82µ
\82½
\81D", mon_nam(mon));
2816 else if (mattk->aatyp == AT_BUTT)
2818 You("butt %s.", mon_nam(mon));
2820 You("%s
\82É
\93ª
\93Ë
\82«
\82ð
\82
\82ç
\82í
\82µ
\82½
\81D", mon_nam(mon));
2821 else if (mattk->aatyp == AT_TUCH)
2823 You("touch %s.", mon_nam(mon));
2825 You("%s
\82É
\90G
\82ê
\82½
\81D", mon_nam(mon));
2826 else if (mattk->aatyp == AT_TENT)
2828 Your("tentacles suck %s.", mon_nam(mon));
2830 Your("
\90G
\8eè
\82ª%s
\82Ì
\91Ì
\89t
\82ð
\8bz
\82¢
\82Æ
\82Á
\82½
\81D", mon_nam(mon));
2833 You("hit %s.", mon_nam(mon));
2835 Your("%s
\82Ö
\82Ì
\8dU
\8c\82\82Í
\96½
\92\86\82µ
\82½
\81D", mon_nam(mon));
2836 sum[i] = damageum(mon, mattk);
2838 missum(mon, mattk, (tmp + armorpenalty > dieroll));
2843 /* automatic if prev two attacks succeed, or if
2844 * already grabbed in a previous attack
2848 if (mon->data == &mons[PM_SHADE])
2850 Your("hug passes harmlessly through %s.", mon_nam(mon));
2852 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª
\92Ê
\82è
\82Ê
\82¯
\82½
\81D", mon_nam(mon));
2853 else if (!sticks(mon->data) && !u.uswallow) {
2854 if (mon == u.ustuck) {
2856 pline("%s is being %s.", Monnam(mon),
2857 u.umonnum == PM_ROPE_GOLEM ? "choked" : "crushed");
2859 pline("%s
\82Í%s
\81D", Monnam(mon),
2860 u.umonnum==PM_ROPE_GOLEM ? "
\8eñ
\82ð
\8di
\82ß
\82ç
\82ê
\82Ä
\82¢
\82é"
2861 : "
\89\9f\82µ
\82Â
\82Ô
\82³
\82ê
\82Ä
\82¢
\82é");
2863 sum[i] = damageum(mon, mattk);
2864 } else if (i >= 2 && sum[i - 1] && sum[i - 2]) {
2866 You("grab %s!", mon_nam(mon));
2868 You("%s
\82ð
\82Â
\82©
\82Ü
\82¦
\82½
\81I", mon_nam(mon));
2870 sum[i] = damageum(mon, mattk);
2875 case AT_EXPL: /* automatic hit if next to */
2878 sum[i] = explum(mon, mattk);
2882 tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
2883 &attknum, &armorpenalty);
2884 if ((dhit = (tmp > rnd(20 + i)))) {
2886 if (mon->data == &mons[PM_SHADE])
2888 Your("attempt to surround %s is harmless.", mon_nam(mon));
2890 You("%s
\82ð
\88ù
\82Ý
\82±
\82à
\82¤
\82Æ
\82µ
\82½
\82ª
\8e¸
\94s
\82µ
\82½
\81D", mon_nam(mon));
2892 sum[i] = gulpum(mon, mattk);
2893 if (sum[i] == 2 && (mon->data->mlet == S_ZOMBIE
2894 || mon->data->mlet == S_MUMMY)
2895 && rn2(5) && !Sick_resistance) {
2897 You_feel("%ssick.", (Sick) ? "very " : "");
2899 You_feel("%s
\8bC
\95ª
\82ª
\88«
\82¢
\81D", (Sick) ? "
\82Æ
\82Ä
\82à" : "");
2900 mdamageu(mon, rnd(8));
2904 missum(mon, mattk, FALSE);
2909 /* No check for uwep; if wielding nothing we want to
2910 * do the normal 1-2 points bare hand damage...
2912 if ((youmonst.data->mlet == S_KOBOLD
2913 || youmonst.data->mlet == S_ORC
2914 || youmonst.data->mlet == S_GNOME) && !weapon_used)
2921 /* Not break--avoid passive attacks from enemy */
2925 case AT_GAZE: /* all done using #monster command */
2929 default: /* Strange... */
2930 impossible("strange attack of yours (%d)", mattk->aatyp);
2933 u.mh = -1; /* dead in the current form */
2938 return (boolean) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE);
2940 (void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE);
2944 break; /* No extra attacks if no longer a monster */
2946 break; /* If paralyzed while attacking, i.e. floating eye */
2948 return (boolean) (nsum != 0);
2951 /* Special (passive) attacks on you by monsters done here.
2954 passive(mon, weapon, mhit, malive, aatyp, wep_was_destroyed)
2956 struct obj *weapon; /* uwep or uswapwep or uarmg or uarmf or Null */
2960 boolean wep_was_destroyed;
2962 register struct permonst *ptr = mon->data;
2963 register int i, tmp;
2967 return (malive | mhit); /* no passive attacks */
2968 if (ptr->mattk[i].aatyp == AT_NONE)
2969 break; /* try this one */
2971 /* Note: tmp not always used */
2972 if (ptr->mattk[i].damn)
2973 tmp = d((int) ptr->mattk[i].damn, (int) ptr->mattk[i].damd);
2974 else if (ptr->mattk[i].damd)
2975 tmp = d((int) mon->m_lev + 1, (int) ptr->mattk[i].damd);
2979 /* These affect you even if they just died.
2981 switch (ptr->mattk[i].adtyp) {
2983 if (mhit && !mon->mcan && weapon) {
2984 if (aatyp == AT_KICK) {
2985 if (uarmf && !rn2(6))
2986 (void) erode_obj(uarmf, xname(uarmf), ERODE_BURN,
2987 EF_GREASE | EF_VERBOSE);
2988 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
2989 || aatyp == AT_MAGC || aatyp == AT_TUCH)
2990 passive_obj(mon, weapon, &(ptr->mattk[i]));
2994 if (mhit && rn2(2)) {
2995 if (Blind || !flags.verbose)
2997 You("are splashed!");
2999 You("
\89½
\82©
\82ð
\97\81\82Ñ
\82¹
\82ç
\82ê
\82½
\81I");
3002 You("are splashed by %s %s!", s_suffix(mon_nam(mon)),
3005 You("%s
\82Ì%s
\82ð
\97\81\82Ñ
\82¹
\82ç
\82ê
\82½
\81I", mon_nam(mon),
3009 if (!Acid_resistance)
3012 erode_armor(&youmonst, ERODE_CORRODE);
3014 if (mhit && weapon) {
3015 if (aatyp == AT_KICK) {
3016 if (uarmf && !rn2(6))
3017 (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3018 EF_GREASE | EF_VERBOSE);
3019 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3020 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3021 passive_obj(mon, weapon, &(ptr->mattk[i]));
3023 exercise(A_STR, FALSE);
3026 if (mhit) { /* successful attack */
3027 long protector = attk_protection((int) aatyp);
3029 /* hero using monsters' AT_MAGC attack is hitting hand to
3030 hand rather than casting a spell */
3031 if (aatyp == AT_MAGC)
3034 if (protector == 0L /* no protection */
3035 || (protector == W_ARMG && !uarmg
3036 && !uwep && !wep_was_destroyed)
3037 || (protector == W_ARMF && !uarmf)
3038 || (protector == W_ARMH && !uarmh)
3039 || (protector == (W_ARMC | W_ARMG) && (!uarmc || !uarmg))) {
3040 if (!Stone_resistance
3041 && !(poly_when_stoned(youmonst.data)
3042 && polymon(PM_STONE_GOLEM))) {
3043 done_in_by(mon, STONING); /* "You turn to stone..." */
3050 if (mhit && !mon->mcan && weapon) {
3051 if (aatyp == AT_KICK) {
3053 (void) erode_obj(uarmf, xname(uarmf), ERODE_RUST,
3054 EF_GREASE | EF_VERBOSE);
3055 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3056 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3057 passive_obj(mon, weapon, &(ptr->mattk[i]));
3061 if (mhit && !mon->mcan && weapon) {
3062 if (aatyp == AT_KICK) {
3064 (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE,
3065 EF_GREASE | EF_VERBOSE);
3066 } else if (aatyp == AT_WEAP || aatyp == AT_CLAW
3067 || aatyp == AT_MAGC || aatyp == AT_TUCH)
3068 passive_obj(mon, weapon, &(ptr->mattk[i]));
3072 /* wrath of gods for attacking Oracle */
3074 shieldeff(u.ux, u.uy);
3076 pline("A hail of magic missiles narrowly misses you!");
3078 pline("
\96\82\96@
\82Ì
\96î
\82Ì
\89J
\82ð
\82È
\82ñ
\82Æ
\82©
\82©
\82í
\82µ
\82½
\81I");
3081 You("are hit by magic missiles appearing from thin air!");
3083 pline("
\93Ë
\94@
\8bó
\92\86\82É
\8c»
\82í
\82ê
\82½
\96\82\96@
\82Ì
\96î
\82ª
\96½
\92\86\82µ
\82½
\81I");
3087 case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
3089 if (aatyp == AT_KICK) {
3092 } else if (aatyp == AT_BITE || aatyp == AT_BUTT
3093 || (aatyp >= AT_STNG && aatyp < AT_WEAP)) {
3094 break; /* no object involved */
3096 passive_obj(mon, weapon, &(ptr->mattk[i]));
3103 /* These only affect you if they still live.
3105 if (malive && !mon->mcan && rn2(3)) {
3106 switch (ptr->mattk[i].adtyp) {
3108 if (ptr == &mons[PM_FLOATING_EYE]) {
3109 if (!canseemon(mon)) {
3114 if (ureflects("%s gaze is reflected by your %s.",
3115 s_suffix(Monnam(mon)))) {
3117 if (ureflects("%s
\82Ì
\82É
\82ç
\82Ý
\82Í%s
\82É
\82æ
\82Á
\82Ä
\94½
\8eË
\82³
\82ê
\82½
\81D",
3121 } else if (Free_action) {
3123 You("momentarily stiffen under %s gaze!",
3124 s_suffix(mon_nam(mon)));
3126 You("%s
\82Ì
\82É
\82ç
\82Ý
\82Å
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81I",
3129 } else if (Hallucination && rn2(4)) {
3131 pline("%s looks %s%s.", Monnam(mon),
3132 !rn2(2) ? "" : "rather ",
3133 !rn2(2) ? "numb" : "stupified");
3135 pline("%s
\82Í%s
\82Î
\82©
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mon),
3136 !rn2(2) ? "" : "
\8f
\82µ");
3140 You("are frozen by %s gaze!", s_suffix(mon_nam(mon)));
3142 You("%s
\82Ì
\82É
\82ç
\82Ý
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon));
3143 nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127);
3145 multi_reason = "frozen by a monster's gaze";
3147 multi_reason = "
\89ö
\95¨
\82Ì
\82É
\82ç
\82Ý
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
3152 pline("%s cannot defend itself.",
3153 Adjmonnam(mon, "blind"));
3155 pline("%s
\82Í
\96h
\8cä
\82Å
\82«
\82È
\82¢
\81D",
3156 Adjmonnam(mon,"
\96Ú
\82Ì
\8c©
\82¦
\82È
\82¢"));
3161 } else if (Free_action) {
3163 You("momentarily stiffen.");
3165 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
3166 } else { /* gelatinous cube */
3168 You("are frozen by %s!", mon_nam(mon));
3170 You("%s
\82É
\82æ
\82Á
\82Ä
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I", mon_nam(mon));
3171 nomovemsg = You_can_move_again;
3174 multi_reason = "frozen by a monster";
3176 multi_reason = "
\89ö
\95¨
\82É
\82æ
\82Á
\82Ä
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
3177 exercise(A_DEX, FALSE);
3180 case AD_COLD: /* brown mold or blue jelly */
3181 if (monnear(mon, u.ux, u.uy)) {
3182 if (Cold_resistance) {
3183 shieldeff(u.ux, u.uy);
3185 You_feel("a mild chill.");
3187 You("
\8a¦
\82³
\82ð
\8a´
\82¶
\82½
\81D");
3188 ugolemeffects(AD_COLD, tmp);
3192 You("are suddenly very cold!");
3194 You("
\93Ë
\91R
\81C
\96Ò
\97ó
\82É
\8a¦
\82
\82È
\82Á
\82½
\81I");
3196 /* monster gets stronger with your heat! */
3197 mon->mhp += tmp / 2;
3198 if (mon->mhpmax < mon->mhp)
3199 mon->mhpmax = mon->mhp;
3200 /* at a certain point, the monster will reproduce! */
3201 if (mon->mhpmax > ((int) (mon->m_lev + 1) * 8))
3202 (void) split_mon(mon, &youmonst);
3205 case AD_STUN: /* specifically yellow mold */
3207 make_stunned((long) tmp, TRUE);
3210 if (monnear(mon, u.ux, u.uy)) {
3211 if (Fire_resistance) {
3212 shieldeff(u.ux, u.uy);
3214 You_feel("mildly warm.");
3216 You("
\92g
\82©
\82³
\82ð
\8a´
\82¶
\82½
\81D");
3217 ugolemeffects(AD_FIRE, tmp);
3221 You("are suddenly very hot!");
3223 You("
\93Ë
\91R
\81C
\96Ò
\97ó
\82É
\94M
\82
\82È
\82Á
\82½
\81I");
3224 mdamageu(mon, tmp); /* fire damage */
3228 if (Shock_resistance) {
3229 shieldeff(u.ux, u.uy);
3231 You_feel("a mild tingle.");
3233 You("
\83s
\83\8a\83s
\83\8a\82Æá
\83\82ê
\82ð
\8a´
\82¶
\82½
\81D");
3234 ugolemeffects(AD_ELEC, tmp);
3238 You("are jolted with electricity!");
3240 You("
\93d
\8bC
\83V
\83\87\83b
\83N
\82ð
\82¤
\82¯
\82½
\81I");
3247 return (malive | mhit);
3251 * Special (passive) attacks on an attacking object by monsters done here.
3252 * Assumes the attack was successful.
3255 passive_obj(mon, obj, mattk)
3257 struct obj *obj; /* null means pick uwep, uswapwep or uarmg */
3258 struct attack *mattk; /* null means we find one internally */
3260 struct permonst *ptr = mon->data;
3263 /* [this first bit is obsolete; we're not called with Null anymore] */
3264 /* if caller hasn't specified an object, use uwep, uswapwep or uarmg */
3266 obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep;
3267 if (!obj && mattk->adtyp == AD_ENCH)
3268 obj = uarmg; /* no weapon? then must be gloves */
3270 return; /* no object to affect */
3273 /* if caller hasn't specified an attack, find one */
3277 return; /* no passive attacks */
3278 if (ptr->mattk[i].aatyp == AT_NONE)
3279 break; /* try this one */
3281 mattk = &(ptr->mattk[i]);
3284 switch (mattk->adtyp) {
3286 if (!rn2(6) && !mon->mcan
3287 /* steam vortex: fire resist applies, fire damage doesn't */
3288 && mon->data != &mons[PM_STEAM_VORTEX]) {
3289 (void) erode_obj(obj, NULL, ERODE_BURN, EF_NONE);
3294 (void) erode_obj(obj, NULL, ERODE_CORRODE, EF_GREASE);
3299 (void) erode_obj(obj, (char *) 0, ERODE_RUST, EF_GREASE);
3304 (void) erode_obj(obj, (char *) 0, ERODE_CORRODE, EF_GREASE);
3309 if (drain_item(obj, TRUE) && carried(obj)
3310 && (obj->known || obj->oclass == ARMOR_CLASS)) {
3312 pline("%s less effective.", Yobjnam2(obj, "seem"));
3314 Your("%s
\82©
\82ç
\96\82\97Í
\82ª
\8fÁ
\82¦
\82½
\82æ
\82¤
\82¾
\81D", xname(obj));
3326 /* Note: caller must ascertain mtmp is mimicking... */
3328 stumble_onto_mimic(mtmp)
3332 const char *fmt = "Wait! That's %s!", *generic = "a monster", *what = 0;
3334 const char *fmt = "
\82¿
\82å
\82Á
\82Æ
\82Ü
\82Á
\82½
\81I%s
\82¾
\81I", *generic = "
\89ö
\95¨", *what = 0;
3336 if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK))
3341 what = generic; /* with default fmt */
3342 else if (mtmp->m_ap_type == M_AP_MONSTER)
3343 what = a_monnam(mtmp); /* differs from what was sensed */
3345 int glyph = levl[u.ux + u.dx][u.uy + u.dy].glyph;
3347 if (glyph_is_cmap(glyph) && (glyph_to_cmap(glyph) == S_hcdoor
3348 || glyph_to_cmap(glyph) == S_vcdoor))
3350 fmt = "The door actually was %s!";
3352 fmt = "
\94à
\82Í
\8eÀ
\8dÛ
\82É
\82Í%s
\82¾
\82Á
\82½
\81I";
3353 else if (glyph_is_object(glyph) && glyph_to_obj(glyph) == GOLD_PIECE)
3355 fmt = "That gold was %s!";
3357 fmt = "
\8bà
\89Ý
\82Í%s
\82¾
\82Á
\82½
\81I";
3359 /* cloned Wiz starts out mimicking some other monster and
3360 might make himself invisible before being revealed */
3361 if (mtmp->minvis && !See_invisible)
3364 what = a_monnam(mtmp);
3369 wakeup(mtmp, FALSE); /* clears mimicking */
3370 /* if hero is blind, wakeup() won't display the monster even though
3371 it's no longer concealed */
3372 if (!canspotmon(mtmp)
3373 && !glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
3374 map_invisible(mtmp->mx, mtmp->my);
3381 char *hands = makeplural(body_part(HAND));
3383 if (!u.umconf || mon->mconf)
3385 if (u.umconf == 1) {
3388 Your("%s stop tingling.", hands);
3390 Your("%s
\82Ìá
\83\82ê
\82ª
\82Æ
\82ê
\82½
\81D", hands);
3393 Your("%s stop glowing %s.", hands, hcolor(NH_RED));
3395 Your("%s
\82Ì%s
\8bP
\82«
\82Í
\82È
\82
\82È
\82Á
\82½
\81D", hands, hcolor(NH_RED));
3399 pline_The("tingling in your %s lessens.", hands);
3401 pline("%s
\82Ìá
\83\82ê
\82ª
\82Æ
\82ê
\82Ä
\82«
\82½
\81D",hands);
3404 Your("%s no longer glow so brightly %s.", hands, hcolor(NH_RED));
3406 Your("%s
\82Ì%s
\8bP
\82«
\82ª
\82È
\82
\82È
\82Á
\82Ä
\82«
\82½
\81D",hands, hcolor(NH_RED));
3412 flash_hits_mon(mtmp, otmp)
3414 struct obj *otmp; /* source of flash */
3416 int tmp, amt, res = 0, useeit = canseemon(mtmp);
3418 if (mtmp->msleeping) {
3419 mtmp->msleeping = 0;
3422 pline_The("flash awakens %s.", mon_nam(mtmp));
3424 pline("
\91M
\8cõ
\82Å%s
\82ª
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81D", mon_nam(mtmp));
3427 } else if (mtmp->data->mlet != S_LIGHT) {
3428 if (!resists_blnd(mtmp)) {
3429 tmp = dist2(otmp->ox, otmp->oy, mtmp->mx, mtmp->my);
3432 pline("%s is blinded by the flash!", Monnam(mtmp));
3434 pline("%s
\82Í
\91M
\8cõ
\82Å
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I", Monnam(mtmp));
3437 if (mtmp->data == &mons[PM_GREMLIN]) {
3438 /* Rule #1: Keep them out of the light. */
3439 amt = otmp->otyp == WAN_LIGHT ? d(1 + otmp->spe, 4)
3440 : rn2(min(mtmp->mhp, 4));
3441 light_hits_gremlin(mtmp, amt);
3443 if (mtmp->mhp > 0) {
3444 if (!context.mon_moving)
3445 setmangry(mtmp, TRUE);
3446 if (tmp < 9 && !mtmp->isshk && rn2(4))
3447 monflee(mtmp, rn2(4) ? rnd(100) : 0, FALSE, TRUE);
3449 mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50 / tmp);
3457 light_hits_gremlin(mon, dmg)
3462 pline("%s %s!", Monnam(mon),
3463 (dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain");
3465 pline("%s
\82Í%s
\81I", Monnam(mon),
3466 (dmg > mon->mhp / 2) ? "
\8bê
\92É
\82Ì
\90º
\82ð
\82 \82°
\82½" : "
\8c\83\92É
\82Å
\8b©
\82ñ
\82¾");
3469 wake_nearto(mon->mx, mon->my, 30);
3470 if (mon->mhp <= 0) {
3471 if (context.mon_moving)
3472 monkilled(mon, (char *) 0, AD_BLND);
3475 } else if (cansee(mon->mx, mon->my) && !canspotmon(mon)) {
3476 map_invisible(mon->mx, mon->my);