1 /* NetHack 3.6 mcastu.c $NHDT-Date: 1567418129 2019/09/02 09:55:29 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.55 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
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-2023 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 /* monster mage spells */
14 enum mcast_mage_spells {
29 /* monster cleric spells */
30 enum mcast_cleric_spells {
43 STATIC_DCL void FDECL(cursetxt, (struct monst *, BOOLEAN_P));
44 STATIC_DCL int FDECL(choose_magic_spell, (int));
45 STATIC_DCL int FDECL(choose_clerical_spell, (int));
46 STATIC_DCL int FDECL(m_cure_self, (struct monst *, int));
47 STATIC_DCL void FDECL(cast_wizard_spell, (struct monst *, int, int));
48 STATIC_DCL void FDECL(cast_cleric_spell, (struct monst *, int, int));
49 STATIC_DCL boolean FDECL(is_undirected_spell, (unsigned int, int));
51 FDECL(spell_would_be_useless, (struct monst *, unsigned int, int));
53 extern const char *const flash_types[]; /* from zap.c */
55 /* feedback when frustrated monster couldn't cast a spell */
58 cursetxt(mtmp, undirected)
62 if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)) {
63 const char *point_msg; /* spellcasting monsters are impolite */
67 point_msg = "all around, then curses";
69 point_msg = "
\82 \82½
\82è
\88ê
\96Ê
\82ð";
70 else if ((Invis && !perceives(mtmp->data)
71 && (mtmp->mux != u.ux || mtmp->muy != u.uy))
72 || is_obj_mappear(&youmonst, STRANGE_OBJECT)
75 point_msg = "and curses in your general direction";
77 point_msg = "
\82 \82È
\82½
\82Ì
\82¢
\82é
\82 \82½
\82è
\82ð";
78 else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
80 point_msg = "and curses at your displaced image";
82 point_msg = "
\82 \82È
\82½
\82Ì
\8c¶
\89e
\82ð";
85 point_msg = "at you, then curses";
87 point_msg = "
\82 \82È
\82½
\82ð";
90 pline("%s points %s.", Monnam(mtmp), point_msg);
92 pline("%s
\82Í%s
\8ew
\8d·
\82µ
\81C
\8eô
\82¢
\82ð
\82©
\82¯
\82½
\81D", Monnam(mtmp), point_msg);
93 } else if ((!(moves % 4) || !rn2(4))) {
96 Norep("You hear a mumbled curse."); /* Deaf-aware */
98 /*JP:TODO:Deaf
\91Î
\89\9e*/
99 Norep("
\8eô
\82¢
\82Ì
\8c¾
\97t
\82ð
\82Â
\82Ô
\82â
\82
\90º
\82ð
\95·
\82¢
\82½
\81D");
104 /* convert a level based random selection into a specific mage spell;
105 inappropriate choices will be screened out by spell_would_be_useless() */
107 choose_magic_spell(spellval)
110 /* for 3.4.3 and earlier, val greater than 22 selected the default spell
112 while (spellval > 24 && rn2(25))
113 spellval = rn2(spellval);
118 if (Antimagic || Hallucination)
124 return MGC_DEATH_TOUCH;
127 return MGC_CLONE_WIZ;
131 return MGC_SUMMON_MONS;
134 return MGC_AGGRAVATION;
138 return MGC_CURSE_ITEMS;
141 return MGC_DESTRY_ARMR;
144 return MGC_WEAKEN_YOU;
147 return MGC_DISAPPEAR;
151 return MGC_HASTE_SELF;
153 return MGC_CURE_SELF;
160 /* convert a level based random selection into a specific cleric spell */
162 choose_clerical_spell(spellnum)
165 /* for 3.4.3 and earlier, num greater than 13 selected the default spell
167 while (spellnum > 15 && rn2(16))
168 spellnum = rn2(spellnum);
174 return CLC_OPEN_WOUNDS;
179 return CLC_FIRE_PILLAR;
181 return CLC_LIGHTNING;
184 return CLC_CURSE_ITEMS;
189 return CLC_BLIND_YOU;
195 return CLC_CONFUSE_YOU;
197 return CLC_CURE_SELF;
200 return CLC_OPEN_WOUNDS;
205 * 1: successful spell
206 * 0: unsuccessful spell
209 castmu(mtmp, mattk, thinks_it_foundyou, foundyou)
210 register struct monst *mtmp;
211 register struct attack *mattk;
212 boolean thinks_it_foundyou;
215 int dmg, ml = mtmp->m_lev;
220 * -- monster is attacking you. Search for a useful spell.
221 * -- monster thinks it's attacking you. Search for a useful spell,
222 * without checking for undirected. If the spell found is directed,
223 * it fails with cursetxt() and loss of mspec_used.
224 * -- monster isn't trying to attack. Select a spell once. Don't keep
225 * searching; if that spell is not useful (or if it's directed),
226 * return and do something else.
227 * Since most spells are directed, this means that a monster that isn't
228 * attacking casts spells only a small portion of the time that an
229 * attacking monster does.
231 if ((mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) && ml) {
236 if (mattk->adtyp == AD_SPEL)
237 spellnum = choose_magic_spell(spellnum);
239 spellnum = choose_clerical_spell(spellnum);
240 /* not trying to attack? don't allow directed spells */
241 if (!thinks_it_foundyou) {
242 if (!is_undirected_spell(mattk->adtyp, spellnum)
243 || spell_would_be_useless(mtmp, mattk->adtyp, spellnum)) {
246 "spellcasting monster found you and doesn't know it?");
252 && spell_would_be_useless(mtmp, mattk->adtyp, spellnum));
257 /* monster unable to cast spells? */
258 if (mtmp->mcan || mtmp->mspec_used || !ml) {
259 cursetxt(mtmp, is_undirected_spell(mattk->adtyp, spellnum));
263 if (mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) {
264 mtmp->mspec_used = 10 - mtmp->m_lev;
265 if (mtmp->mspec_used < 2)
266 mtmp->mspec_used = 2;
269 /* monster can cast spells, but is casting a directed spell at the
270 wrong place? If so, give a message, and return. Do this *after*
271 penalizing mspec_used. */
272 if (!foundyou && thinks_it_foundyou
273 && !is_undirected_spell(mattk->adtyp, spellnum)) {
275 pline("%s casts a spell at %s!",
276 canseemon(mtmp) ? Monnam(mtmp) : "Something",
277 levl[mtmp->mux][mtmp->muy].typ == WATER ? "empty water"
280 pline("%s
\82Í
\89½
\82à
\82È
\82¢%s
\82É
\96\82\96@
\82ð
\82©
\82¯
\82½
\81I",
281 canseemon(mtmp) ? Monnam(mtmp) : "
\89½
\8eÒ
\82©",
282 levl[mtmp->mux][mtmp->muy].typ == WATER ? "
\90\85\92\86"
289 if (rn2(ml * 10) < (mtmp->mconf ? 100 : 20)) { /* fumbled attack */
290 if (canseemon(mtmp) && !Deaf)
292 pline_The("air crackles around %s.", mon_nam(mtmp));
294 pline("%s
\82Ì
\89ñ
\82è
\82Ì
\8bó
\8bC
\82ª
\83p
\83`
\83p
\83`
\89¹
\82ð
\82½
\82Ä
\82Ä
\82¢
\82é
\81D", mon_nam(mtmp));
297 if (canspotmon(mtmp) || !is_undirected_spell(mattk->adtyp, spellnum)) {
299 pline("%s casts a spell%s!",
300 canspotmon(mtmp) ? Monnam(mtmp) : "Something",
301 is_undirected_spell(mattk->adtyp, spellnum)
303 : (Invis && !perceives(mtmp->data)
304 && (mtmp->mux != u.ux || mtmp->muy != u.uy))
305 ? " at a spot near you"
307 && (mtmp->mux != u.ux || mtmp->muy != u.uy))
308 ? " at your displaced image"
311 const char *who = (canspotmon(mtmp) ? Monnam(mtmp) : "
\89½
\8eÒ
\82©");
312 if(is_undirected_spell(mattk->adtyp, spellnum)){
313 pline("%s
\82Í
\8eô
\95¶
\82ð
\8f¥
\82¦
\82½
\81I", who);
315 pline("%s
\82Í
\82 \82È
\82½%s
\82É
\96\82\96@
\82ð
\82©
\82¯
\82½
\81I",
317 (Invisible && !perceives(mtmp->data) &&
318 (mtmp->mux != u.ux || mtmp->muy != u.uy)) ?
319 "
\82Ì
\82·
\82®
\82»
\82Î" :
320 (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) ?
328 * As these are spells, the damage is related to the level
329 * of the monster casting the spell.
333 if (mattk->adtyp != AD_SPEL && mattk->adtyp != AD_CLRC) {
335 "%s casting non-hand-to-hand version of hand-to-hand spell %d?",
336 Monnam(mtmp), mattk->adtyp);
339 } else if (mattk->damd)
340 dmg = d((int) ((ml / 2) + mattk->damn), (int) mattk->damd);
342 dmg = d((int) ((ml / 2) + 1), 6);
343 if (Half_spell_damage)
348 switch (mattk->adtyp) {
351 pline("You're enveloped in flames.");
353 You("
\89\8a\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81D");
354 if (Fire_resistance) {
355 shieldeff(u.ux, u.uy);
357 pline("But you resist the effects.");
359 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82¢
\81D");
366 pline("You're covered in frost.");
368 You("
\95X
\82É
\95¢
\82í
\82ê
\82½
\81D");
369 if (Cold_resistance) {
370 shieldeff(u.ux, u.uy);
372 pline("But you resist the effects.");
374 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82¢
\81D");
380 You("are hit by a shower of missiles!");
382 You("
\96\82\96@
\82Ì
\96î
\82ð
\82
\82ç
\82Á
\82½
\81I");
384 shieldeff(u.ux, u.uy);
386 pline_The("missiles bounce off!");
388 pline("
\96\82\96@
\82Ì
\96î
\82Í
\94½
\8eË
\82µ
\82½
\81I");
391 dmg = d((int) mtmp->m_lev / 2 + 1, 6);
393 case AD_SPEL: /* wizard spell */
394 case AD_CLRC: /* clerical spell */
396 if (mattk->adtyp == AD_SPEL)
397 cast_wizard_spell(mtmp, dmg, spellnum);
399 cast_cleric_spell(mtmp, dmg, spellnum);
400 dmg = 0; /* done by the spell casting functions */
410 m_cure_self(mtmp, dmg)
414 if (mtmp->mhp < mtmp->mhpmax) {
417 pline("%s looks better.", Monnam(mtmp));
419 pline("%s
\82Í
\8bC
\95ª
\82ª
\82æ
\82
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
420 /* note: player healing does 6d4; this used to do 1d8 */
421 if ((mtmp->mhp += d(3, 6)) > mtmp->mhpmax)
422 mtmp->mhp = mtmp->mhpmax;
428 /* monster wizard and cleric spellcasting functions */
430 If dmg is zero, then the monster is not casting at you.
431 If the monster is intentionally not casting at you, we have previously
432 called spell_would_be_useless() and spellnum should always be a valid
434 If you modify either of these, be sure to change is_undirected_spell()
435 and spell_would_be_useless().
439 cast_wizard_spell(mtmp, dmg, spellnum)
444 if (dmg == 0 && !is_undirected_spell(AD_SPEL, spellnum)) {
445 impossible("cast directed wizard spell (%d) with dmg=0?", spellnum);
450 case MGC_DEATH_TOUCH:
452 pline("Oh no, %s's using the touch of death!", mhe(mtmp));
454 pline("
\82È
\82ñ
\82Ä
\82±
\82Á
\82½
\82¢
\81C%s
\82Í
\8e\80\82Ì
\90é
\8d\90\82ð
\8eg
\82Á
\82Ä
\82¢
\82é
\81I", mhe(mtmp));
455 if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
457 You("seem no deader than before.");
459 You("
\82±
\82ê
\88È
\8fã
\8e\80\82Ë
\82È
\82¢
\82æ
\82¤
\82¾
\81D");
460 } else if (!Antimagic && rn2(mtmp->m_lev) > 12) {
463 You("have an out of body experience.");
465 You("
\97H
\91Ì
\97£
\92E
\82ð
\91Ì
\8c±
\82µ
\82½
\81D");
467 killer.format = KILLED_BY_AN;
469 Strcpy(killer.name, "touch of death");
471 Strcpy(killer.name, "
\8e\80\82Ì
\90é
\8d\90\82Å");
476 shieldeff(u.ux, u.uy);
478 pline("Lucky for you, it didn't work!");
480 pline("
\89^
\82Ì
\82æ
\82¢
\82±
\82Æ
\82É
\82È
\82ñ
\82Æ
\82à
\82È
\82©
\82Á
\82½
\81I");
485 if (mtmp->iswiz && context.no_of_wizards == 1) {
487 pline("Double Trouble...");
489 pline("
\93ñ
\8fd
\8bê
\82¾
\81D
\81D
\81D");
493 impossible("bad wizard cloning?");
495 case MGC_SUMMON_MONS: {
499 count = nasty(mtmp); /* summon something nasty */
501 nasty(mtmp); /* summon something nasty */
505 verbalize("Destroy the thief, my pet%s!", plur(count));
507 verbalize("
\93\90\91¯
\82ð
\8eE
\82¹
\81I
\89ä
\82ª
\89º
\96l
\82æ
\81I");
510 const char *mappear = (count == 1) ? "A monster appears"
514 /* messages not quite right if plural monsters created but
515 only a single monster is seen */
516 if (Invis && !perceives(mtmp->data)
517 && (mtmp->mux != u.ux || mtmp->muy != u.uy))
519 pline("%s around a spot near you!", mappear);
521 pline("
\89ö
\95¨
\82ª
\82 \82È
\82½
\82Ì
\82·
\82®
\82»
\82Î
\82É
\8c»
\82ê
\82½
\81I");
523 else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
525 pline("%s around your displaced image!", mappear);
527 pline("
\89ö
\95¨
\82ª
\82 \82È
\82½
\82Ì
\8c¶
\89e
\82Ì
\82·
\82®
\82»
\82Î
\82É
\8c»
\82ê
\82½
\81I");
531 pline("%s from nowhere!", mappear);
533 pline("
\89ö
\95¨
\82ª
\82Ç
\82±
\82©
\82ç
\82Æ
\82à
\82È
\82
\8c»
\82ê
\82½
\81I");
539 case MGC_AGGRAVATION:
541 You_feel("that monsters are aware of your presence.");
543 You_feel("
\89ö
\95¨
\82½
\82¿
\82ª
\82 \82È
\82½
\82Ì
\91¶
\8dÝ
\82É
\8bC
\95t
\82¢
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
547 case MGC_CURSE_ITEMS:
549 You_feel("as if you need some help.");
551 You_feel("
\8f\95\82¯
\82ª
\95K
\97v
\82È
\8bC
\82ª
\82µ
\82½
\81D");
555 case MGC_DESTRY_ARMR:
557 shieldeff(u.ux, u.uy);
559 pline("A field of force surrounds you!");
561 pline("
\95s
\8ev
\8bc
\82È
\97Í
\82ª
\82 \82È
\82½
\82ð
\82Æ
\82è
\82Ü
\82¢
\82½
\81I");
562 } else if (!destroy_arm(some_armor(&youmonst))) {
564 Your("skin itches.");
566 You("
\83\80\83Y
\83\80\83Y
\82µ
\82½
\81D");
570 case MGC_WEAKEN_YOU: /* drain strength */
572 shieldeff(u.ux, u.uy);
574 You_feel("momentarily weakened.");
576 You_feel("
\88ê
\8fu
\8eã
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
579 You("suddenly feel weaker!");
581 You("
\93Ë
\91R
\8eã
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
582 dmg = mtmp->m_lev - 6;
583 if (Half_spell_damage)
587 done_in_by(mtmp, DIED);
591 case MGC_DISAPPEAR: /* makes self invisible */
592 if (!mtmp->minvis && !mtmp->invis_blkd) {
595 pline("%s suddenly %s!", Monnam(mtmp),
596 !See_invisible ? "disappears" : "becomes transparent");
598 pline("%s
\82Í
\93Ë
\91R%s
\81I", Monnam(mtmp),
599 !See_invisible ? "
\8fÁ
\82¦
\82½" : "
\93§
\96¾
\82É
\82È
\82Á
\82½");
601 mon_set_minvis(mtmp);
602 if (cansee(mtmp->mx, mtmp->my) && !canspotmon(mtmp))
603 map_invisible(mtmp->mx, mtmp->my);
606 impossible("no reason for monster to cast disappear spell?");
609 if (Antimagic || Free_action) {
610 shieldeff(u.ux, u.uy);
613 You_feel("momentarily disoriented.");
615 You("
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\81D");
616 make_stunned(1L, FALSE);
619 You(Stunned ? "struggle to keep your balance." : "reel...");
621 You(Stunned ? "
\83o
\83\89\83\93\83X
\82ð
\8eæ
\82ë
\82¤
\82Æ
\82à
\82ª
\82¢
\82½
\81D" : "
\82æ
\82ë
\82ß
\82¢
\82½
\81D
\81D
\81D");
622 dmg = d(ACURR(A_DEX) < 12 ? 6 : 4, 4);
623 if (Half_spell_damage)
625 make_stunned((HStun & TIMEOUT) + (long) dmg, FALSE);
630 mon_adjust_speed(mtmp, 1, (struct obj *) 0);
634 dmg = m_cure_self(mtmp, dmg);
637 /* prior to 3.4.0 Antimagic was setting the damage to 1--this
638 made the spell virtually harmless to players with magic res. */
640 shieldeff(u.ux, u.uy);
645 You("get a slight %sache.", body_part(HEAD));
647 You("
\82¿
\82å
\82Á
\82Æ%s
\92É
\82ª
\82µ
\82½
\81D",body_part(HEAD));
650 Your("brain is on fire!");
652 You("
\93{
\82è
\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81I");
655 Your("%s suddenly aches painfully!", body_part(HEAD));
657 You("
\93Ë
\91R%s
\92É
\82É
\82¨
\82»
\82í
\82ê
\82½
\81I", body_part(HEAD));
660 Your("%s suddenly aches very painfully!", body_part(HEAD));
662 You("
\93Ë
\91R
\8c\83\82µ
\82¢%s
\92É
\82É
\82¨
\82»
\82í
\82ê
\82½
\81I", body_part(HEAD));
665 impossible("mcastu: invalid magic spell (%d)", spellnum);
676 cast_cleric_spell(mtmp, dmg, spellnum)
681 if (dmg == 0 && !is_undirected_spell(AD_CLRC, spellnum)) {
682 impossible("cast directed cleric spell (%d) with dmg=0?", spellnum);
688 /* this is physical damage (force not heat),
689 * not magical damage or fire damage
692 pline("A sudden geyser slams into you from nowhere!");
694 pline("
\91÷
\97¬
\82ª
\82Ç
\82±
\82©
\82ç
\82Æ
\82à
\82È
\82
\8c»
\82ê
\82Ä
\82 \82È
\82½
\82ð
\91Å
\82¿
\82Â
\82¯
\82½
\81I");
696 if (Half_physical_damage)
699 case CLC_FIRE_PILLAR:
701 pline("A pillar of fire strikes all around you!");
703 pline("
\82 \82È
\82½
\82Ì
\8eü
\82è
\82É
\89Î
\92\8c\82ª
\97§
\82Á
\82½
\81I");
704 if (Fire_resistance) {
705 shieldeff(u.ux, u.uy);
709 if (Half_spell_damage)
712 (void) burnarmor(&youmonst);
713 destroy_item(SCROLL_CLASS, AD_FIRE);
714 destroy_item(POTION_CLASS, AD_FIRE);
715 destroy_item(SPBOOK_CLASS, AD_FIRE);
716 (void) burn_floor_objects(u.ux, u.uy, TRUE, FALSE);
718 case CLC_LIGHTNING: {
722 pline("A bolt of lightning strikes down at you from above!");
724 pline("
\82 \82È
\82½
\82Ì
\90^
\8fã
\82©
\82ç
\88î
\8dÈ
\82ª
\8d~
\82è
\92\8d\82¢
\82¾
\81I");
726 reflects = ureflects("It bounces off your %s%s.", "");
728 reflects = ureflects("
\82»
\82ê
\82Í
\82 \82È
\82½
\82Ì%s%s
\82Å
\92µ
\82Ë
\95Ô
\82Á
\82½
\81D", "");
729 if (reflects || Shock_resistance) {
730 shieldeff(u.ux, u.uy);
736 if (Half_spell_damage)
738 destroy_item(WAND_CLASS, AD_ELEC);
739 destroy_item(RING_CLASS, AD_ELEC);
740 (void) flashburn((long) rnd(100));
743 case CLC_CURSE_ITEMS:
745 You_feel("as if you need some help.");
747 You_feel("
\8f\95\82¯
\82ª
\95K
\97v
\82È
\8bC
\82ª
\82µ
\82½
\81D");
752 /* Try for insects, and if there are none
753 left, go for (sticks to) snakes. -3. */
754 struct permonst *pm = mkclass(S_ANT, 0);
755 struct monst *mtmp2 = (struct monst *) 0;
756 char let = (pm ? S_ANT : S_SNAKE);
757 boolean success = FALSE, seecaster;
758 int i, quan, oldseen, newseen;
762 oldseen = monster_census(TRUE);
763 quan = (mtmp->m_lev < 2) ? 1 : rnd((int) mtmp->m_lev / 2);
766 for (i = 0; i <= quan; i++) {
767 if (!enexto(&bypos, mtmp->mux, mtmp->muy, mtmp->data))
769 if ((pm = mkclass(let, 0)) != 0
770 && (mtmp2 = makemon(pm, bypos.x, bypos.y, MM_ANGRY)) != 0) {
772 mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0;
776 newseen = monster_census(TRUE);
778 /* not canspotmon(), which includes unseen things sensed via warning
780 seecaster = canseemon(mtmp) || tp_sensemon(mtmp) || Detect_monsters;
784 char *arg; /* [not const: upstart(N==1 ? an() : makeplural())] */
786 const char *what = (let == S_SNAKE) ? "snake" : "insect";
788 const char *what = (let == S_SNAKE) ? "
\83w
\83r" : "
\92\8e";
790 if (newseen <= oldseen || Unaware) {
791 /* unseen caster fails or summons unseen critters,
792 or unconscious hero ("You dream that you hear...") */
794 You_hear("someone summoning %s.", makeplural(what));
796 You_hear("
\92N
\82©
\82ª%s
\82ð
\8f¢
\8a«
\82µ
\82Ä
\82¢
\82é
\82Ì
\82ð
\95·
\82¢
\82½
\81D", what);
798 /* unseen caster summoned seen critter(s) */
799 arg = (newseen == oldseen + 1) ? an(what) : makeplural(what);
802 You_hear("someone summoning something, and %s %s.", arg,
803 vtense(arg, "appear"));
805 You_hear("
\92N
\82©
\82ª
\89½
\82©
\82ð
\8f¢
\8a«
\82·
\82é
\82Ì
\82ð
\95·
\82¢
\82½
\81C
\82»
\82µ
\82Ä%s
\82ª
\8c»
\82ê
\82½
\81D",
810 pline("%s %s.", upstart(arg), vtense(arg, "appear"));
812 pline("%s
\82ª
\8c»
\82ê
\82½
\81D", arg);
815 /* seen caster, possibly producing unseen--or just one--critters;
816 hero is told what the caster is doing and doesn't necessarily
817 observe complete accuracy of that caster's results (in other
818 words, no need to fuss with visibility or singularization;
819 player is told what's happening even if hero is unconscious) */
822 fmt = "%s casts at a clump of sticks, but nothing happens.";
824 fmt = "%s
\82Í
\96_
\90Ø
\82ê
\82É
\96\82\96@
\82ð
\82©
\82¯
\82½
\82ª
\81C
\82È
\82É
\82à
\82¨
\82±
\82ç
\82È
\82©
\82Á
\82½
\81D";
825 else if (let == S_SNAKE)
827 fmt = "%s transforms a clump of sticks into snakes!";
829 fmt = "%s
\82Í
\96_
\90Ø
\82ê
\82ð
\83w
\83r
\82É
\95Ï
\82¦
\82½
\81I";
830 else if (Invis && !perceives(mtmp->data)
831 && (mtmp->mux != u.ux || mtmp->muy != u.uy))
833 fmt = "%s summons insects around a spot near you!";
835 fmt = "%s
\82Í
\92\8e\82ð
\82 \82È
\82½
\82Ì
\82·
\82®
\82»
\82Î
\82É
\8f¢
\8a«
\82µ
\82½
\81I";
836 else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
838 fmt = "%s summons insects around your displaced image!";
840 fmt = "%s
\82Í
\92\8e\82ð
\82 \82È
\82½
\82Ì
\8c¶
\89e
\82Ì
\8eü
\82è
\82É
\8f¢
\8a«
\82µ
\82½
\81I";
843 fmt = "%s summons insects!";
845 fmt = "%s
\82Í
\92\8e\82ð
\8f¢
\8a«
\82µ
\82½
\81I";
847 pline(fmt, Monnam(mtmp));
853 /* note: resists_blnd() doesn't apply here */
856 int num_eyes = eyecount(youmonst.data);
857 pline("Scales cover your %s!", (num_eyes == 1)
859 : makeplural(body_part(EYE)));
861 pline("
\97Ø
\82ª
\82 \82È
\82½
\82Ì%s
\82ð
\95¢
\82Á
\82½
\81I", body_part(EYE));
863 make_blinded(Half_spell_damage ? 100L : 200L, FALSE);
865 Your1(vision_clears);
868 impossible("no reason for monster to cast blindness spell?");
871 if (Antimagic || Free_action) {
872 shieldeff(u.ux, u.uy);
875 You("stiffen briefly.");
877 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
880 multi_reason = "paralyzed by a monster";
882 multi_reason = "
\89ö
\95¨
\82É
\96\83á
\83\82³
\82¹
\82ç
\82ê
\82½
\8c\84\82É";
886 You("are frozen in place!");
888 You("
\82»
\82Ì
\8fê
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I");
889 dmg = 4 + (int) mtmp->m_lev;
890 if (Half_spell_damage)
894 multi_reason = "paralyzed by a monster";
896 multi_reason = "
\89ö
\95¨
\82É
\96\83á
\83\82³
\82¹
\82ç
\82ê
\82½
\8c\84\82É";
901 case CLC_CONFUSE_YOU:
903 shieldeff(u.ux, u.uy);
905 You_feel("momentarily dizzy.");
907 You("
\88ê
\8fu
\82ß
\82Ü
\82¢
\82ª
\82µ
\82½
\81D");
909 boolean oldprop = !!Confusion;
911 dmg = (int) mtmp->m_lev;
912 if (Half_spell_damage)
914 make_confused(HConfusion + dmg, TRUE);
917 You_feel("%s!", oldprop ? "trippier" : "trippy");
919 You("%s
\82Ö
\82ë
\82Ö
\82ë
\82É
\82È
\82Á
\82½
\81I", oldprop ? "
\82à
\82Á
\82Æ" : "");
922 You_feel("%sconfused!", oldprop ? "more " : "");
924 You("%s
\8d¬
\97\90\82µ
\82½
\81I", oldprop ? "
\82à
\82Á
\82Æ" : "");
929 dmg = m_cure_self(mtmp, dmg);
931 case CLC_OPEN_WOUNDS:
933 shieldeff(u.ux, u.uy);
938 Your("skin itches badly for a moment.");
940 Your("
\94ç
\95\86\82Í
\88ê
\8fu
\81C
\83\80\83Y
\83\80\83Y
\82Á
\82Æ
\82µ
\82½
\81D");
943 pline("Wounds appear on your body!");
945 pline("
\8f\9d\82ª
\82 \82È
\82½
\82Ì
\91Ì
\82É
\8fo
\97\88\82½
\81I");
948 pline("Severe wounds appear on your body!");
950 pline("
\82Ð
\82Ç
\82¢
\8f\9d\82ª
\82 \82È
\82½
\82Ì
\91Ì
\82É
\8fo
\97\88\82½
\81I");
953 Your("body is covered with painful wounds!");
955 pline("
\91Ì
\82ª
\8f\9d\82¾
\82ç
\82¯
\82É
\82È
\82Á
\82½
\81I");
958 impossible("mcastu: invalid clerical spell (%d)", spellnum);
969 is_undirected_spell(adtyp, spellnum)
973 if (adtyp == AD_SPEL) {
976 case MGC_SUMMON_MONS:
977 case MGC_AGGRAVATION:
985 } else if (adtyp == AD_CLRC) {
997 /* Some spells are useless under some circumstances. */
1000 spell_would_be_useless(mtmp, adtyp, spellnum)
1005 /* Some spells don't require the player to really be there and can be cast
1006 * by the monster when you're invisible, yet still shouldn't be cast when
1007 * the monster doesn't even think you're there.
1008 * This check isn't quite right because it always uses your real position.
1009 * We really want something like "if the monster could see mux, muy".
1011 boolean mcouldseeu = couldsee(mtmp->mx, mtmp->my);
1013 if (adtyp == AD_SPEL) {
1014 /* aggravate monsters, etc. won't be cast by peaceful monsters */
1016 && (spellnum == MGC_AGGRAVATION || spellnum == MGC_SUMMON_MONS
1017 || spellnum == MGC_CLONE_WIZ))
1019 /* haste self when already fast */
1020 if (mtmp->permspeed == MFAST && spellnum == MGC_HASTE_SELF)
1022 /* invisibility when already invisible */
1023 if ((mtmp->minvis || mtmp->invis_blkd) && spellnum == MGC_DISAPPEAR)
1025 /* peaceful monster won't cast invisibility if you can't see
1027 same as when monsters drink potions of invisibility. This doesn't
1028 really make a lot of sense, but lets the player avoid hitting
1029 peaceful monsters by mistake */
1030 if (mtmp->mpeaceful && !See_invisible && spellnum == MGC_DISAPPEAR)
1032 /* healing when already healed */
1033 if (mtmp->mhp == mtmp->mhpmax && spellnum == MGC_CURE_SELF)
1035 /* don't summon monsters if it doesn't think you're around */
1036 if (!mcouldseeu && (spellnum == MGC_SUMMON_MONS
1037 || (!mtmp->iswiz && spellnum == MGC_CLONE_WIZ)))
1039 if ((!mtmp->iswiz || context.no_of_wizards > 1)
1040 && spellnum == MGC_CLONE_WIZ)
1042 /* aggravation (global wakeup) when everyone is already active */
1043 if (spellnum == MGC_AGGRAVATION) {
1044 /* if nothing needs to be awakened then this spell is useless
1045 but caster might not realize that [chance to pick it then
1046 must be very small otherwise caller's many retry attempts
1047 will eventually end up picking it too often] */
1048 if (!has_aggravatables(mtmp))
1049 return rn2(100) ? TRUE : FALSE;
1051 } else if (adtyp == AD_CLRC) {
1052 /* summon insects/sticks to snakes won't be cast by peaceful monsters
1054 if (mtmp->mpeaceful && spellnum == CLC_INSECTS)
1056 /* healing when already healed */
1057 if (mtmp->mhp == mtmp->mhpmax && spellnum == CLC_CURE_SELF)
1059 /* don't summon insects if it doesn't think you're around */
1060 if (!mcouldseeu && spellnum == CLC_INSECTS)
1062 /* blindness spell on blinded player */
1063 if (Blinded && spellnum == CLC_BLIND_YOU)
1069 /* convert 1..10 to 0..9; add 10 for second group (spell casting) */
1070 #define ad_to_typ(k) (10 + (int) k - 1)
1072 /* monster uses spell (ranged) */
1075 register struct monst *mtmp;
1076 register struct attack *mattk;
1078 /* don't print constant stream of curse messages for 'normal'
1079 spellcasting monsters at range */
1080 if (mattk->adtyp > AD_SPC2)
1084 cursetxt(mtmp, FALSE);
1087 if (lined_up(mtmp) && rn2(3)) {
1089 if (mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */
1090 if (canseemon(mtmp))
1092 pline("%s zaps you with a %s!", Monnam(mtmp),
1093 flash_types[ad_to_typ(mattk->adtyp)]);
1095 pline("%s
\82Í%s
\82ð
\82 \82È
\82½
\82É
\8cü
\82¯
\82Ä
\95ú
\82Á
\82½
\81D", Monnam(mtmp),
1096 flash_types[ad_to_typ(mattk->adtyp)]);
1098 buzz(-ad_to_typ(mattk->adtyp), (int) mattk->damn, mtmp->mx,
1099 mtmp->my, sgn(tbx), sgn(tby));
1101 impossible("Monster spell %d cast", mattk->adtyp - 1);