1 /* NetHack 3.6 mcastu.c $NHDT-Date: 1436753517 2015/07/13 02:11:57 $ $NHDT-Branch: master $:$NHDT-Revision: 1.44 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
7 /* monster mage spells */
9 #define MGC_CURE_SELF 1
10 #define MGC_HASTE_SELF 2
11 #define MGC_STUN_YOU 3
12 #define MGC_DISAPPEAR 4
13 #define MGC_WEAKEN_YOU 5
14 #define MGC_DESTRY_ARMR 6
15 #define MGC_CURSE_ITEMS 7
16 #define MGC_AGGRAVATION 8
17 #define MGC_SUMMON_MONS 9
18 #define MGC_CLONE_WIZ 10
19 #define MGC_DEATH_TOUCH 11
21 /* monster cleric spells */
22 #define CLC_OPEN_WOUNDS 0
23 #define CLC_CURE_SELF 1
24 #define CLC_CONFUSE_YOU 2
25 #define CLC_PARALYZE 3
26 #define CLC_BLIND_YOU 4
28 #define CLC_CURSE_ITEMS 6
29 #define CLC_LIGHTNING 7
30 #define CLC_FIRE_PILLAR 8
33 STATIC_DCL
void FDECL(cursetxt
, (struct monst
*, BOOLEAN_P
));
34 STATIC_DCL
int FDECL(choose_magic_spell
, (int));
35 STATIC_DCL
int FDECL(choose_clerical_spell
, (int));
36 STATIC_DCL
void FDECL(cast_wizard_spell
, (struct monst
*, int, int));
37 STATIC_DCL
void FDECL(cast_cleric_spell
, (struct monst
*, int, int));
38 STATIC_DCL boolean
FDECL(is_undirected_spell
, (unsigned int, int));
40 FDECL(spell_would_be_useless
, (struct monst
*, unsigned int, int));
42 extern const char *const flash_types
[]; /* from zap.c */
44 /* feedback when frustrated monster couldn't cast a spell */
47 cursetxt(mtmp
, undirected
)
51 if (canseemon(mtmp
) && couldsee(mtmp
->mx
, mtmp
->my
)) {
52 const char *point_msg
; /* spellcasting monsters are impolite */
55 point_msg
= "all around, then curses";
56 else if ((Invis
&& !perceives(mtmp
->data
)
57 && (mtmp
->mux
!= u
.ux
|| mtmp
->muy
!= u
.uy
))
58 || is_obj_mappear(&youmonst
, STRANGE_OBJECT
)
60 point_msg
= "and curses in your general direction";
61 else if (Displaced
&& (mtmp
->mux
!= u
.ux
|| mtmp
->muy
!= u
.uy
))
62 point_msg
= "and curses at your displaced image";
64 point_msg
= "at you, then curses";
66 pline("%s points %s.", Monnam(mtmp
), point_msg
);
67 } else if ((!(moves
% 4) || !rn2(4))) {
69 Norep("You hear a mumbled curse.");
73 /* convert a level based random selection into a specific mage spell;
74 inappropriate choices will be screened out by spell_would_be_useless() */
76 choose_magic_spell(spellval
)
79 /* for 3.4.3 and earlier, val greater than 22 selected the default spell
81 while (spellval
> 24 && rn2(25))
82 spellval
= rn2(spellval
);
87 if (Antimagic
|| Hallucination
)
89 /* else FALL THROUGH */
93 return MGC_DEATH_TOUCH
;
100 return MGC_SUMMON_MONS
;
103 return MGC_AGGRAVATION
;
107 return MGC_CURSE_ITEMS
;
110 return MGC_DESTRY_ARMR
;
113 return MGC_WEAKEN_YOU
;
116 return MGC_DISAPPEAR
;
120 return MGC_HASTE_SELF
;
122 return MGC_CURE_SELF
;
129 /* convert a level based random selection into a specific cleric spell */
131 choose_clerical_spell(spellnum
)
134 /* for 3.4.3 and earlier, num greater than 13 selected the default spell
136 while (spellnum
> 15 && rn2(16))
137 spellnum
= rn2(spellnum
);
143 return CLC_OPEN_WOUNDS
;
144 /* else FALL THROUGH */
148 return CLC_FIRE_PILLAR
;
150 return CLC_LIGHTNING
;
153 return CLC_CURSE_ITEMS
;
158 return CLC_BLIND_YOU
;
164 return CLC_CONFUSE_YOU
;
166 return CLC_CURE_SELF
;
169 return CLC_OPEN_WOUNDS
;
174 * 1: successful spell
175 * 0: unsuccessful spell
178 castmu(mtmp
, mattk
, thinks_it_foundyou
, foundyou
)
179 register struct monst
*mtmp
;
180 register struct attack
*mattk
;
181 boolean thinks_it_foundyou
;
184 int dmg
, ml
= mtmp
->m_lev
;
189 * -- monster is attacking you. Search for a useful spell.
190 * -- monster thinks it's attacking you. Search for a useful spell,
191 * without checking for undirected. If the spell found is directed,
192 * it fails with cursetxt() and loss of mspec_used.
193 * -- monster isn't trying to attack. Select a spell once. Don't keep
194 * searching; if that spell is not useful (or if it's directed),
195 * return and do something else.
196 * Since most spells are directed, this means that a monster that isn't
197 * attacking casts spells only a small portion of the time that an
198 * attacking monster does.
200 if ((mattk
->adtyp
== AD_SPEL
|| mattk
->adtyp
== AD_CLRC
) && ml
) {
205 if (mattk
->adtyp
== AD_SPEL
)
206 spellnum
= choose_magic_spell(spellnum
);
208 spellnum
= choose_clerical_spell(spellnum
);
209 /* not trying to attack? don't allow directed spells */
210 if (!thinks_it_foundyou
) {
211 if (!is_undirected_spell(mattk
->adtyp
, spellnum
)
212 || spell_would_be_useless(mtmp
, mattk
->adtyp
, spellnum
)) {
215 "spellcasting monster found you and doesn't know it?");
221 && spell_would_be_useless(mtmp
, mattk
->adtyp
, spellnum
));
226 /* monster unable to cast spells? */
227 if (mtmp
->mcan
|| mtmp
->mspec_used
|| !ml
) {
228 cursetxt(mtmp
, is_undirected_spell(mattk
->adtyp
, spellnum
));
232 if (mattk
->adtyp
== AD_SPEL
|| mattk
->adtyp
== AD_CLRC
) {
233 mtmp
->mspec_used
= 10 - mtmp
->m_lev
;
234 if (mtmp
->mspec_used
< 2)
235 mtmp
->mspec_used
= 2;
238 /* monster can cast spells, but is casting a directed spell at the
239 wrong place? If so, give a message, and return. Do this *after*
240 penalizing mspec_used. */
241 if (!foundyou
&& thinks_it_foundyou
242 && !is_undirected_spell(mattk
->adtyp
, spellnum
)) {
243 pline("%s casts a spell at %s!",
244 canseemon(mtmp
) ? Monnam(mtmp
) : "Something",
245 levl
[mtmp
->mux
][mtmp
->muy
].typ
== WATER
? "empty water"
251 if (rn2(ml
* 10) < (mtmp
->mconf
? 100 : 20)) { /* fumbled attack */
252 if (canseemon(mtmp
) && !Deaf
)
253 pline_The("air crackles around %s.", mon_nam(mtmp
));
256 if (canspotmon(mtmp
) || !is_undirected_spell(mattk
->adtyp
, spellnum
)) {
257 pline("%s casts a spell%s!",
258 canspotmon(mtmp
) ? Monnam(mtmp
) : "Something",
259 is_undirected_spell(mattk
->adtyp
, spellnum
)
261 : (Invisible
&& !perceives(mtmp
->data
)
262 && (mtmp
->mux
!= u
.ux
|| mtmp
->muy
!= u
.uy
))
263 ? " at a spot near you"
265 && (mtmp
->mux
!= u
.ux
|| mtmp
->muy
!= u
.uy
))
266 ? " at your displaced image"
271 * As these are spells, the damage is related to the level
272 * of the monster casting the spell.
276 if (mattk
->adtyp
!= AD_SPEL
&& mattk
->adtyp
!= AD_CLRC
) {
278 "%s casting non-hand-to-hand version of hand-to-hand spell %d?",
279 Monnam(mtmp
), mattk
->adtyp
);
282 } else if (mattk
->damd
)
283 dmg
= d((int) ((ml
/ 2) + mattk
->damn
), (int) mattk
->damd
);
285 dmg
= d((int) ((ml
/ 2) + 1), 6);
286 if (Half_spell_damage
)
291 switch (mattk
->adtyp
) {
293 pline("You're enveloped in flames.");
294 if (Fire_resistance
) {
295 shieldeff(u
.ux
, u
.uy
);
296 pline("But you resist the effects.");
302 pline("You're covered in frost.");
303 if (Cold_resistance
) {
304 shieldeff(u
.ux
, u
.uy
);
305 pline("But you resist the effects.");
310 You("are hit by a shower of missiles!");
312 shieldeff(u
.ux
, u
.uy
);
313 pline_The("missiles bounce off!");
316 dmg
= d((int) mtmp
->m_lev
/ 2 + 1, 6);
318 case AD_SPEL
: /* wizard spell */
319 case AD_CLRC
: /* clerical spell */
321 if (mattk
->adtyp
== AD_SPEL
)
322 cast_wizard_spell(mtmp
, dmg
, spellnum
);
324 cast_cleric_spell(mtmp
, dmg
, spellnum
);
325 dmg
= 0; /* done by the spell casting functions */
334 /* monster wizard and cleric spellcasting functions */
336 If dmg is zero, then the monster is not casting at you.
337 If the monster is intentionally not casting at you, we have previously
338 called spell_would_be_useless() and spellnum should always be a valid
340 If you modify either of these, be sure to change is_undirected_spell()
341 and spell_would_be_useless().
345 cast_wizard_spell(mtmp
, dmg
, spellnum
)
350 if (dmg
== 0 && !is_undirected_spell(AD_SPEL
, spellnum
)) {
351 impossible("cast directed wizard spell (%d) with dmg=0?", spellnum
);
356 case MGC_DEATH_TOUCH
:
357 pline("Oh no, %s's using the touch of death!", mhe(mtmp
));
358 if (nonliving(youmonst
.data
) || is_demon(youmonst
.data
)) {
359 You("seem no deader than before.");
360 } else if (!Antimagic
&& rn2(mtmp
->m_lev
) > 12) {
362 You("have an out of body experience.");
364 killer
.format
= KILLED_BY_AN
;
365 Strcpy(killer
.name
, "touch of death");
370 shieldeff(u
.ux
, u
.uy
);
371 pline("Lucky for you, it didn't work!");
376 if (mtmp
->iswiz
&& context
.no_of_wizards
== 1) {
377 pline("Double Trouble...");
381 impossible("bad wizard cloning?");
383 case MGC_SUMMON_MONS
: {
386 count
= nasty(mtmp
); /* summon something nasty */
388 verbalize("Destroy the thief, my pet%s!", plur(count
));
390 const char *mappear
=
391 (count
== 1) ? "A monster appears" : "Monsters appear";
393 /* messages not quite right if plural monsters created but
394 only a single monster is seen */
395 if (Invisible
&& !perceives(mtmp
->data
)
396 && (mtmp
->mux
!= u
.ux
|| mtmp
->muy
!= u
.uy
))
397 pline("%s around a spot near you!", mappear
);
398 else if (Displaced
&& (mtmp
->mux
!= u
.ux
|| mtmp
->muy
!= u
.uy
))
399 pline("%s around your displaced image!", mappear
);
401 pline("%s from nowhere!", mappear
);
406 case MGC_AGGRAVATION
:
407 You_feel("that monsters are aware of your presence.");
411 case MGC_CURSE_ITEMS
:
412 You_feel("as if you need some help.");
416 case MGC_DESTRY_ARMR
:
418 shieldeff(u
.ux
, u
.uy
);
419 pline("A field of force surrounds you!");
420 } else if (!destroy_arm(some_armor(&youmonst
))) {
421 Your("skin itches.");
425 case MGC_WEAKEN_YOU
: /* drain strength */
427 shieldeff(u
.ux
, u
.uy
);
428 You_feel("momentarily weakened.");
430 You("suddenly feel weaker!");
431 dmg
= mtmp
->m_lev
- 6;
432 if (Half_spell_damage
)
436 done_in_by(mtmp
, DIED
);
440 case MGC_DISAPPEAR
: /* makes self invisible */
441 if (!mtmp
->minvis
&& !mtmp
->invis_blkd
) {
443 pline("%s suddenly %s!", Monnam(mtmp
),
444 !See_invisible
? "disappears" : "becomes transparent");
445 mon_set_minvis(mtmp
);
446 if (cansee(mtmp
->mx
, mtmp
->my
) && !canspotmon(mtmp
))
447 map_invisible(mtmp
->mx
, mtmp
->my
);
450 impossible("no reason for monster to cast disappear spell?");
453 if (Antimagic
|| Free_action
) {
454 shieldeff(u
.ux
, u
.uy
);
456 You_feel("momentarily disoriented.");
457 make_stunned(1L, FALSE
);
459 You(Stunned
? "struggle to keep your balance." : "reel...");
460 dmg
= d(ACURR(A_DEX
) < 12 ? 6 : 4, 4);
461 if (Half_spell_damage
)
463 make_stunned((HStun
& TIMEOUT
) + (long) dmg
, FALSE
);
468 mon_adjust_speed(mtmp
, 1, (struct obj
*) 0);
472 if (mtmp
->mhp
< mtmp
->mhpmax
) {
474 pline("%s looks better.", Monnam(mtmp
));
475 /* note: player healing does 6d4; this used to do 1d8 */
476 if ((mtmp
->mhp
+= d(3, 6)) > mtmp
->mhpmax
)
477 mtmp
->mhp
= mtmp
->mhpmax
;
482 /* prior to 3.4.0 Antimagic was setting the damage to 1--this
483 made the spell virtually harmless to players with magic res. */
485 shieldeff(u
.ux
, u
.uy
);
489 You("get a slight %sache.", body_part(HEAD
));
491 Your("brain is on fire!");
493 Your("%s suddenly aches painfully!", body_part(HEAD
));
495 Your("%s suddenly aches very painfully!", body_part(HEAD
));
498 impossible("mcastu: invalid magic spell (%d)", spellnum
);
509 cast_cleric_spell(mtmp
, dmg
, spellnum
)
514 if (dmg
== 0 && !is_undirected_spell(AD_CLRC
, spellnum
)) {
515 impossible("cast directed cleric spell (%d) with dmg=0?", spellnum
);
521 /* this is physical damage (force not heat),
522 * not magical damage or fire damage
524 pline("A sudden geyser slams into you from nowhere!");
526 if (Half_physical_damage
)
529 case CLC_FIRE_PILLAR
:
530 pline("A pillar of fire strikes all around you!");
531 if (Fire_resistance
) {
532 shieldeff(u
.ux
, u
.uy
);
536 if (Half_spell_damage
)
539 (void) burnarmor(&youmonst
);
540 destroy_item(SCROLL_CLASS
, AD_FIRE
);
541 destroy_item(POTION_CLASS
, AD_FIRE
);
542 destroy_item(SPBOOK_CLASS
, AD_FIRE
);
543 (void) burn_floor_objects(u
.ux
, u
.uy
, TRUE
, FALSE
);
545 case CLC_LIGHTNING
: {
548 pline("A bolt of lightning strikes down at you from above!");
549 reflects
= ureflects("It bounces off your %s%s.", "");
550 if (reflects
|| Shock_resistance
) {
551 shieldeff(u
.ux
, u
.uy
);
557 if (Half_spell_damage
)
559 destroy_item(WAND_CLASS
, AD_ELEC
);
560 destroy_item(RING_CLASS
, AD_ELEC
);
561 (void) flashburn((long) rnd(100));
564 case CLC_CURSE_ITEMS
:
565 You_feel("as if you need some help.");
570 /* Try for insects, and if there are none
571 left, go for (sticks to) snakes. -3. */
572 struct permonst
*pm
= mkclass(S_ANT
, 0);
573 struct monst
*mtmp2
= (struct monst
*) 0;
574 char let
= (pm
? S_ANT
: S_SNAKE
);
575 boolean success
= FALSE
, seecaster
;
576 int i
, quan
, oldseen
, newseen
;
580 oldseen
= monster_census(TRUE
);
581 quan
= (mtmp
->m_lev
< 2) ? 1 : rnd((int) mtmp
->m_lev
/ 2);
584 for (i
= 0; i
<= quan
; i
++) {
585 if (!enexto(&bypos
, mtmp
->mux
, mtmp
->muy
, mtmp
->data
))
587 if ((pm
= mkclass(let
, 0)) != 0
588 && (mtmp2
= makemon(pm
, bypos
.x
, bypos
.y
, MM_ANGRY
)) != 0) {
590 mtmp2
->msleeping
= mtmp2
->mpeaceful
= mtmp2
->mtame
= 0;
594 newseen
= monster_census(TRUE
);
596 /* not canspotmon(), which includes unseen things sensed via warning
598 seecaster
= canseemon(mtmp
) || tp_sensemon(mtmp
) || Detect_monsters
;
602 char *arg
; /* [not const: upstart(N==1 ? an() : makeplural())] */
603 const char *what
= (let
== S_SNAKE
) ? "snake" : "insect";
605 if (newseen
<= oldseen
|| Unaware
) {
606 /* unseen caster fails or summons unseen critters,
607 or unconscious hero ("You dream that you hear...") */
608 You_hear("someone summoning %s.", makeplural(what
));
610 /* unseen caster summoned seen critter(s) */
611 arg
= (newseen
== oldseen
+ 1) ? an(what
) : makeplural(what
);
613 You_hear("someone summoning something, and %s %s.", arg
,
614 vtense(arg
, "appear"));
616 pline("%s %s.", upstart(arg
), vtense(arg
, "appear"));
619 /* seen caster, possibly producing unseen--or just one--critters;
620 hero is told what the caster is doing and doesn't necessarily
621 observe complete accuracy of that caster's results (in other
622 words, no need to fuss with visibility or singularization;
623 player is told what's happening even if hero is unconscious) */
625 fmt
= "%s casts at a clump of sticks, but nothing happens.";
626 else if (let
== S_SNAKE
)
627 fmt
= "%s transforms a clump of sticks into snakes!";
628 else if (Invisible
&& !perceives(mtmp
->data
)
629 && (mtmp
->mux
!= u
.ux
|| mtmp
->muy
!= u
.uy
))
630 fmt
= "%s summons insects around a spot near you!";
631 else if (Displaced
&& (mtmp
->mux
!= u
.ux
|| mtmp
->muy
!= u
.uy
))
632 fmt
= "%s summons insects around your displaced image!";
634 fmt
= "%s summons insects!";
636 pline(fmt
, Monnam(mtmp
));
642 /* note: resists_blnd() doesn't apply here */
644 int num_eyes
= eyecount(youmonst
.data
);
645 pline("Scales cover your %s!", (num_eyes
== 1)
647 : makeplural(body_part(EYE
)));
648 make_blinded(Half_spell_damage
? 100L : 200L, FALSE
);
650 Your1(vision_clears
);
653 impossible("no reason for monster to cast blindness spell?");
656 if (Antimagic
|| Free_action
) {
657 shieldeff(u
.ux
, u
.uy
);
659 You("stiffen briefly.");
661 multi_reason
= "paralyzed by a monster";
664 You("are frozen in place!");
665 dmg
= 4 + (int) mtmp
->m_lev
;
666 if (Half_spell_damage
)
669 multi_reason
= "paralyzed by a monster";
674 case CLC_CONFUSE_YOU
:
676 shieldeff(u
.ux
, u
.uy
);
677 You_feel("momentarily dizzy.");
679 boolean oldprop
= !!Confusion
;
681 dmg
= (int) mtmp
->m_lev
;
682 if (Half_spell_damage
)
684 make_confused(HConfusion
+ dmg
, TRUE
);
686 You_feel("%s!", oldprop
? "trippier" : "trippy");
688 You_feel("%sconfused!", oldprop
? "more " : "");
693 if (mtmp
->mhp
< mtmp
->mhpmax
) {
695 pline("%s looks better.", Monnam(mtmp
));
696 /* note: player healing does 6d4; this used to do 1d8 */
697 if ((mtmp
->mhp
+= d(3, 6)) > mtmp
->mhpmax
)
698 mtmp
->mhp
= mtmp
->mhpmax
;
702 case CLC_OPEN_WOUNDS
:
704 shieldeff(u
.ux
, u
.uy
);
708 Your("skin itches badly for a moment.");
710 pline("Wounds appear on your body!");
712 pline("Severe wounds appear on your body!");
714 Your("body is covered with painful wounds!");
717 impossible("mcastu: invalid clerical spell (%d)", spellnum
);
728 is_undirected_spell(adtyp
, spellnum
)
732 if (adtyp
== AD_SPEL
) {
735 case MGC_SUMMON_MONS
:
736 case MGC_AGGRAVATION
:
744 } else if (adtyp
== AD_CLRC
) {
756 /* Some spells are useless under some circumstances. */
759 spell_would_be_useless(mtmp
, adtyp
, spellnum
)
764 /* Some spells don't require the player to really be there and can be cast
765 * by the monster when you're invisible, yet still shouldn't be cast when
766 * the monster doesn't even think you're there.
767 * This check isn't quite right because it always uses your real position.
768 * We really want something like "if the monster could see mux, muy".
770 boolean mcouldseeu
= couldsee(mtmp
->mx
, mtmp
->my
);
772 if (adtyp
== AD_SPEL
) {
773 /* aggravate monsters, etc. won't be cast by peaceful monsters */
775 && (spellnum
== MGC_AGGRAVATION
|| spellnum
== MGC_SUMMON_MONS
776 || spellnum
== MGC_CLONE_WIZ
))
778 /* haste self when already fast */
779 if (mtmp
->permspeed
== MFAST
&& spellnum
== MGC_HASTE_SELF
)
781 /* invisibility when already invisible */
782 if ((mtmp
->minvis
|| mtmp
->invis_blkd
) && spellnum
== MGC_DISAPPEAR
)
784 /* peaceful monster won't cast invisibility if you can't see
786 same as when monsters drink potions of invisibility. This doesn't
787 really make a lot of sense, but lets the player avoid hitting
788 peaceful monsters by mistake */
789 if (mtmp
->mpeaceful
&& !See_invisible
&& spellnum
== MGC_DISAPPEAR
)
791 /* healing when already healed */
792 if (mtmp
->mhp
== mtmp
->mhpmax
&& spellnum
== MGC_CURE_SELF
)
794 /* don't summon monsters if it doesn't think you're around */
795 if (!mcouldseeu
&& (spellnum
== MGC_SUMMON_MONS
796 || (!mtmp
->iswiz
&& spellnum
== MGC_CLONE_WIZ
)))
798 if ((!mtmp
->iswiz
|| context
.no_of_wizards
> 1)
799 && spellnum
== MGC_CLONE_WIZ
)
801 /* aggravation (global wakeup) when everyone is already active */
802 if (spellnum
== MGC_AGGRAVATION
) {
803 /* if nothing needs to be awakened then this spell is useless
804 but caster might not realize that [chance to pick it then
805 must be very small otherwise caller's many retry attempts
806 will eventually end up picking it too often] */
807 if (!has_aggravatables(mtmp
))
808 return rn2(100) ? TRUE
: FALSE
;
810 } else if (adtyp
== AD_CLRC
) {
811 /* summon insects/sticks to snakes won't be cast by peaceful monsters
813 if (mtmp
->mpeaceful
&& spellnum
== CLC_INSECTS
)
815 /* healing when already healed */
816 if (mtmp
->mhp
== mtmp
->mhpmax
&& spellnum
== CLC_CURE_SELF
)
818 /* don't summon insects if it doesn't think you're around */
819 if (!mcouldseeu
&& spellnum
== CLC_INSECTS
)
821 /* blindness spell on blinded player */
822 if (Blinded
&& spellnum
== CLC_BLIND_YOU
)
828 /* convert 1..10 to 0..9; add 10 for second group (spell casting) */
829 #define ad_to_typ(k) (10 + (int) k - 1)
831 /* monster uses spell (ranged) */
834 register struct monst
*mtmp
;
835 register struct attack
*mattk
;
837 /* don't print constant stream of curse messages for 'normal'
838 spellcasting monsters at range */
839 if (mattk
->adtyp
> AD_SPC2
)
843 cursetxt(mtmp
, FALSE
);
846 if (lined_up(mtmp
) && rn2(3)) {
848 if (mattk
->adtyp
&& (mattk
->adtyp
< 11)) { /* no cf unsigned >0 */
850 pline("%s zaps you with a %s!", Monnam(mtmp
),
851 flash_types
[ad_to_typ(mattk
->adtyp
)]);
852 buzz(-ad_to_typ(mattk
->adtyp
), (int) mattk
->damn
, mtmp
->mx
,
853 mtmp
->my
, sgn(tbx
), sgn(tby
));
855 impossible("Monster spell %d cast", mattk
->adtyp
- 1);