OSDN Git Service

fix #48255
[jnethack/source.git] / src / mcastu.c
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. */
5
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. */
10
11 #include "hack.h"
12
13 /* monster mage spells */
14 enum mcast_mage_spells {
15     MGC_PSI_BOLT = 0,
16     MGC_CURE_SELF,
17     MGC_HASTE_SELF,
18     MGC_STUN_YOU,
19     MGC_DISAPPEAR,
20     MGC_WEAKEN_YOU,
21     MGC_DESTRY_ARMR,
22     MGC_CURSE_ITEMS,
23     MGC_AGGRAVATION,
24     MGC_SUMMON_MONS,
25     MGC_CLONE_WIZ,
26     MGC_DEATH_TOUCH
27 };
28
29 /* monster cleric spells */
30 enum mcast_cleric_spells {
31     CLC_OPEN_WOUNDS = 0,
32     CLC_CURE_SELF,
33     CLC_CONFUSE_YOU,
34     CLC_PARALYZE,
35     CLC_BLIND_YOU,
36     CLC_INSECTS,
37     CLC_CURSE_ITEMS,
38     CLC_LIGHTNING,
39     CLC_FIRE_PILLAR,
40     CLC_GEYSER
41 };
42
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));
50 STATIC_DCL boolean
51 FDECL(spell_would_be_useless, (struct monst *, unsigned int, int));
52
53 extern const char *const flash_types[]; /* from zap.c */
54
55 /* feedback when frustrated monster couldn't cast a spell */
56 STATIC_OVL
57 void
58 cursetxt(mtmp, undirected)
59 struct monst *mtmp;
60 boolean undirected;
61 {
62     if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)) {
63         const char *point_msg; /* spellcasting monsters are impolite */
64
65         if (undirected)
66 /*JP
67             point_msg = "all around, then curses";
68 */
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)
73                  || u.uundetected)
74 /*JP
75             point_msg = "and curses in your general direction";
76 */
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))
79 /*JP
80             point_msg = "and curses at your displaced image";
81 */
82             point_msg = "\82 \82È\82½\82Ì\8c\89e\82ð";
83         else
84 /*JP
85             point_msg = "at you, then curses";
86 */
87             point_msg = "\82 \82È\82½\82ð";
88
89 /*JP
90         pline("%s points %s.", Monnam(mtmp), point_msg);
91 */
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))) {
94         if (!Deaf)
95 #if 0 /*JP*/
96             Norep("You hear a mumbled curse.");   /* Deaf-aware */
97 #else
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");
100 #endif
101     }
102 }
103
104 /* convert a level based random selection into a specific mage spell;
105    inappropriate choices will be screened out by spell_would_be_useless() */
106 STATIC_OVL int
107 choose_magic_spell(spellval)
108 int spellval;
109 {
110     /* for 3.4.3 and earlier, val greater than 22 selected the default spell
111      */
112     while (spellval > 24 && rn2(25))
113         spellval = rn2(spellval);
114
115     switch (spellval) {
116     case 24:
117     case 23:
118         if (Antimagic || Hallucination)
119             return MGC_PSI_BOLT;
120         /*FALLTHRU*/
121     case 22:
122     case 21:
123     case 20:
124         return MGC_DEATH_TOUCH;
125     case 19:
126     case 18:
127         return MGC_CLONE_WIZ;
128     case 17:
129     case 16:
130     case 15:
131         return MGC_SUMMON_MONS;
132     case 14:
133     case 13:
134         return MGC_AGGRAVATION;
135     case 12:
136     case 11:
137     case 10:
138         return MGC_CURSE_ITEMS;
139     case 9:
140     case 8:
141         return MGC_DESTRY_ARMR;
142     case 7:
143     case 6:
144         return MGC_WEAKEN_YOU;
145     case 5:
146     case 4:
147         return MGC_DISAPPEAR;
148     case 3:
149         return MGC_STUN_YOU;
150     case 2:
151         return MGC_HASTE_SELF;
152     case 1:
153         return MGC_CURE_SELF;
154     case 0:
155     default:
156         return MGC_PSI_BOLT;
157     }
158 }
159
160 /* convert a level based random selection into a specific cleric spell */
161 STATIC_OVL int
162 choose_clerical_spell(spellnum)
163 int spellnum;
164 {
165     /* for 3.4.3 and earlier, num greater than 13 selected the default spell
166      */
167     while (spellnum > 15 && rn2(16))
168         spellnum = rn2(spellnum);
169
170     switch (spellnum) {
171     case 15:
172     case 14:
173         if (rn2(3))
174             return CLC_OPEN_WOUNDS;
175         /*FALLTHRU*/
176     case 13:
177         return CLC_GEYSER;
178     case 12:
179         return CLC_FIRE_PILLAR;
180     case 11:
181         return CLC_LIGHTNING;
182     case 10:
183     case 9:
184         return CLC_CURSE_ITEMS;
185     case 8:
186         return CLC_INSECTS;
187     case 7:
188     case 6:
189         return CLC_BLIND_YOU;
190     case 5:
191     case 4:
192         return CLC_PARALYZE;
193     case 3:
194     case 2:
195         return CLC_CONFUSE_YOU;
196     case 1:
197         return CLC_CURE_SELF;
198     case 0:
199     default:
200         return CLC_OPEN_WOUNDS;
201     }
202 }
203
204 /* return values:
205  * 1: successful spell
206  * 0: unsuccessful spell
207  */
208 int
209 castmu(mtmp, mattk, thinks_it_foundyou, foundyou)
210 register struct monst *mtmp;
211 register struct attack *mattk;
212 boolean thinks_it_foundyou;
213 boolean foundyou;
214 {
215     int dmg, ml = mtmp->m_lev;
216     int ret;
217     int spellnum = 0;
218
219     /* Three cases:
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.
230      */
231     if ((mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) && ml) {
232         int cnt = 40;
233
234         do {
235             spellnum = rn2(ml);
236             if (mattk->adtyp == AD_SPEL)
237                 spellnum = choose_magic_spell(spellnum);
238             else
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)) {
244                     if (foundyou)
245                         impossible(
246                        "spellcasting monster found you and doesn't know it?");
247                     return 0;
248                 }
249                 break;
250             }
251         } while (--cnt > 0
252                  && spell_would_be_useless(mtmp, mattk->adtyp, spellnum));
253         if (cnt == 0)
254             return 0;
255     }
256
257     /* monster unable to cast spells? */
258     if (mtmp->mcan || mtmp->mspec_used || !ml) {
259         cursetxt(mtmp, is_undirected_spell(mattk->adtyp, spellnum));
260         return (0);
261     }
262
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;
267     }
268
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)) {
274 #if 0 /*JP:T*/
275         pline("%s casts a spell at %s!",
276               canseemon(mtmp) ? Monnam(mtmp) : "Something",
277               levl[mtmp->mux][mtmp->muy].typ == WATER ? "empty water"
278                                                       : "thin air");
279 #else
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"
283                                                       : "\8bó\8aÔ");
284 #endif
285         return (0);
286     }
287
288     nomul(0);
289     if (rn2(ml * 10) < (mtmp->mconf ? 100 : 20)) { /* fumbled attack */
290         if (canseemon(mtmp) && !Deaf)
291 /*JP
292             pline_The("air crackles around %s.", mon_nam(mtmp));
293 */
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));
295         return (0);
296     }
297     if (canspotmon(mtmp) || !is_undirected_spell(mattk->adtyp, spellnum)) {
298 #if 0 /*JP*/
299         pline("%s casts a spell%s!",
300               canspotmon(mtmp) ? Monnam(mtmp) : "Something",
301               is_undirected_spell(mattk->adtyp, spellnum)
302                   ? ""
303                   : (Invis && !perceives(mtmp->data)
304                      && (mtmp->mux != u.ux || mtmp->muy != u.uy))
305                         ? " at a spot near you"
306                         : (Displaced
307                            && (mtmp->mux != u.ux || mtmp->muy != u.uy))
308                               ? " at your displaced image"
309                               : " at you");
310 #else
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);
314         } else {
315             pline("%s\82Í\82 \82È\82½%s\82É\96\82\96@\82ð\82©\82¯\82½\81I",
316                   who,
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)) ?
321                   "\82Ì\8c\89e" :
322                   "");
323         }
324 #endif
325     }
326
327     /*
328      * As these are spells, the damage is related to the level
329      * of the monster casting the spell.
330      */
331     if (!foundyou) {
332         dmg = 0;
333         if (mattk->adtyp != AD_SPEL && mattk->adtyp != AD_CLRC) {
334             impossible(
335               "%s casting non-hand-to-hand version of hand-to-hand spell %d?",
336                        Monnam(mtmp), mattk->adtyp);
337             return (0);
338         }
339     } else if (mattk->damd)
340         dmg = d((int) ((ml / 2) + mattk->damn), (int) mattk->damd);
341     else
342         dmg = d((int) ((ml / 2) + 1), 6);
343     if (Half_spell_damage)
344         dmg = (dmg + 1) / 2;
345
346     ret = 1;
347
348     switch (mattk->adtyp) {
349     case AD_FIRE:
350 /*JP
351         pline("You're enveloped in flames.");
352 */
353         You("\89\8a\82É\82Â\82Â\82Ü\82ê\82½\81D");
354         if (Fire_resistance) {
355             shieldeff(u.ux, u.uy);
356 /*JP
357             pline("But you resist the effects.");
358 */
359             pline("\82µ\82©\82µ\81C\82 \82È\82½\82Í\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D");
360             dmg = 0;
361         }
362         burn_away_slime();
363         break;
364     case AD_COLD:
365 /*JP
366         pline("You're covered in frost.");
367 */
368         You("\95X\82É\95¢\82í\82ê\82½\81D");
369         if (Cold_resistance) {
370             shieldeff(u.ux, u.uy);
371 /*JP
372             pline("But you resist the effects.");
373 */
374             pline("\82µ\82©\82µ\81C\82 \82È\82½\82Í\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D");
375             dmg = 0;
376         }
377         break;
378     case AD_MAGM:
379 /*JP
380         You("are hit by a shower of missiles!");
381 */
382         You("\96\82\96@\82Ì\96î\82ð\82­\82ç\82Á\82½\81I");
383         if (Antimagic) {
384             shieldeff(u.ux, u.uy);
385 /*JP
386             pline_The("missiles bounce off!");
387 */
388             pline("\96\82\96@\82Ì\96î\82Í\94½\8eË\82µ\82½\81I");
389             dmg = 0;
390         } else
391             dmg = d((int) mtmp->m_lev / 2 + 1, 6);
392         break;
393     case AD_SPEL: /* wizard spell */
394     case AD_CLRC: /* clerical spell */
395     {
396         if (mattk->adtyp == AD_SPEL)
397             cast_wizard_spell(mtmp, dmg, spellnum);
398         else
399             cast_cleric_spell(mtmp, dmg, spellnum);
400         dmg = 0; /* done by the spell casting functions */
401         break;
402     }
403     }
404     if (dmg)
405         mdamageu(mtmp, dmg);
406     return (ret);
407 }
408
409 STATIC_OVL int
410 m_cure_self(mtmp, dmg)
411 struct monst *mtmp;
412 int dmg;
413 {
414     if (mtmp->mhp < mtmp->mhpmax) {
415         if (canseemon(mtmp))
416 /*JP
417             pline("%s looks better.", Monnam(mtmp));
418 */
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;
423         dmg = 0;
424     }
425     return dmg;
426 }
427
428 /* monster wizard and cleric spellcasting functions */
429 /*
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
433    undirected spell.
434    If you modify either of these, be sure to change is_undirected_spell()
435    and spell_would_be_useless().
436  */
437 STATIC_OVL
438 void
439 cast_wizard_spell(mtmp, dmg, spellnum)
440 struct monst *mtmp;
441 int dmg;
442 int spellnum;
443 {
444     if (dmg == 0 && !is_undirected_spell(AD_SPEL, spellnum)) {
445         impossible("cast directed wizard spell (%d) with dmg=0?", spellnum);
446         return;
447     }
448
449     switch (spellnum) {
450     case MGC_DEATH_TOUCH:
451 /*JP
452         pline("Oh no, %s's using the touch of death!", mhe(mtmp));
453 */
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)) {
456 /*JP
457             You("seem no deader than before.");
458 */
459             You("\82±\82ê\88È\8fã\8e\80\82Ë\82È\82¢\82æ\82¤\82¾\81D");
460         } else if (!Antimagic && rn2(mtmp->m_lev) > 12) {
461             if (Hallucination) {
462 /*JP
463                 You("have an out of body experience.");
464 */
465                 You("\97H\91Ì\97£\92E\82ð\91Ì\8c±\82µ\82½\81D");
466             } else {
467                 killer.format = KILLED_BY_AN;
468 /*JP
469                 Strcpy(killer.name, "touch of death");
470 */
471                 Strcpy(killer.name, "\8e\80\82Ì\90é\8d\90\82Å");
472                 done(DIED);
473             }
474         } else {
475             if (Antimagic)
476                 shieldeff(u.ux, u.uy);
477 /*JP
478             pline("Lucky for you, it didn't work!");
479 */
480             pline("\89^\82Ì\82æ\82¢\82±\82Æ\82É\82È\82ñ\82Æ\82à\82È\82©\82Á\82½\81I");
481         }
482         dmg = 0;
483         break;
484     case MGC_CLONE_WIZ:
485         if (mtmp->iswiz && context.no_of_wizards == 1) {
486 /*JP
487             pline("Double Trouble...");
488 */
489             pline("\93ñ\8fd\8bê\82¾\81D\81D\81D");
490             clonewiz();
491             dmg = 0;
492         } else
493             impossible("bad wizard cloning?");
494         break;
495     case MGC_SUMMON_MONS: {
496 #if 0 /*JP*/
497         int count;
498
499         count = nasty(mtmp); /* summon something nasty */
500 #else
501         nasty(mtmp); /* summon something nasty */
502 #endif
503         if (mtmp->iswiz) {
504 /*JP
505             verbalize("Destroy the thief, my pet%s!", plur(count));
506 */
507             verbalize("\93\90\91¯\82ð\8eE\82¹\81I\89ä\82ª\89º\96l\82æ\81I");
508         } else {
509 #if 0 /*JP*/
510             const char *mappear = (count == 1) ? "A monster appears"
511                                                : "Monsters appear";
512 #endif
513
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))
518 #if 0 /*JP:T*/
519                 pline("%s around a spot near you!", mappear);
520 #else
521                 pline("\89ö\95¨\82ª\82 \82È\82½\82Ì\82·\82®\82»\82Î\82É\8c»\82ê\82½\81I");
522 #endif
523             else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
524 #if 0 /*JP:T*/
525                 pline("%s around your displaced image!", mappear);
526 #else
527                 pline("\89ö\95¨\82ª\82 \82È\82½\82Ì\8c\89e\82Ì\82·\82®\82»\82Î\82É\8c»\82ê\82½\81I");
528 #endif
529             else
530 #if 0 /*JP:T*/
531                 pline("%s from nowhere!", mappear);
532 #else
533                 pline("\89ö\95¨\82ª\82Ç\82±\82©\82ç\82Æ\82à\82È\82­\8c»\82ê\82½\81I");
534 #endif
535         }
536         dmg = 0;
537         break;
538     }
539     case MGC_AGGRAVATION:
540 /*JP
541         You_feel("that monsters are aware of your presence.");
542 */
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");
544         aggravate();
545         dmg = 0;
546         break;
547     case MGC_CURSE_ITEMS:
548 /*JP
549         You_feel("as if you need some help.");
550 */
551         You_feel("\8f\95\82¯\82ª\95K\97v\82È\8bC\82ª\82µ\82½\81D");
552         rndcurse();
553         dmg = 0;
554         break;
555     case MGC_DESTRY_ARMR:
556         if (Antimagic) {
557             shieldeff(u.ux, u.uy);
558 /*JP
559             pline("A field of force surrounds you!");
560 */
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))) {
563 /*JP
564             Your("skin itches.");
565 */
566             You("\83\80\83Y\83\80\83Y\82µ\82½\81D");
567         }
568         dmg = 0;
569         break;
570     case MGC_WEAKEN_YOU: /* drain strength */
571         if (Antimagic) {
572             shieldeff(u.ux, u.uy);
573 /*JP
574             You_feel("momentarily weakened.");
575 */
576             You_feel("\88ê\8fu\8eã\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
577         } else {
578 /*JP
579             You("suddenly feel weaker!");
580 */
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)
584                 dmg = (dmg + 1) / 2;
585             losestr(rnd(dmg));
586             if (u.uhp < 1)
587                 done_in_by(mtmp, DIED);
588         }
589         dmg = 0;
590         break;
591     case MGC_DISAPPEAR: /* makes self invisible */
592         if (!mtmp->minvis && !mtmp->invis_blkd) {
593             if (canseemon(mtmp))
594 #if 0 /*JP:T*/
595                 pline("%s suddenly %s!", Monnam(mtmp),
596                       !See_invisible ? "disappears" : "becomes transparent");
597 #else
598                 pline("%s\82Í\93Ë\91R%s\81I", Monnam(mtmp),
599                       !See_invisible ? "\8fÁ\82¦\82½" : "\93§\96¾\82É\82È\82Á\82½");
600 #endif
601             mon_set_minvis(mtmp);
602             if (cansee(mtmp->mx, mtmp->my) && !canspotmon(mtmp))
603                 map_invisible(mtmp->mx, mtmp->my);
604             dmg = 0;
605         } else
606             impossible("no reason for monster to cast disappear spell?");
607         break;
608     case MGC_STUN_YOU:
609         if (Antimagic || Free_action) {
610             shieldeff(u.ux, u.uy);
611             if (!Stunned)
612 /*JP
613                 You_feel("momentarily disoriented.");
614 */
615                 You("\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\81D");
616             make_stunned(1L, FALSE);
617         } else {
618 /*JP
619             You(Stunned ? "struggle to keep your balance." : "reel...");
620 */
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)
624                 dmg = (dmg + 1) / 2;
625             make_stunned((HStun & TIMEOUT) + (long) dmg, FALSE);
626         }
627         dmg = 0;
628         break;
629     case MGC_HASTE_SELF:
630         mon_adjust_speed(mtmp, 1, (struct obj *) 0);
631         dmg = 0;
632         break;
633     case MGC_CURE_SELF:
634         dmg = m_cure_self(mtmp, dmg);
635         break;
636     case MGC_PSI_BOLT:
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. */
639         if (Antimagic) {
640             shieldeff(u.ux, u.uy);
641             dmg = (dmg + 1) / 2;
642         }
643         if (dmg <= 5)
644 /*JP
645             You("get a slight %sache.", body_part(HEAD));
646 */
647             You("\82¿\82å\82Á\82Æ%s\92É\82ª\82µ\82½\81D",body_part(HEAD));
648         else if (dmg <= 10)
649 /*JP
650             Your("brain is on fire!");
651 */
652             You("\93{\82è\82É\82Â\82Â\82Ü\82ê\82½\81I");
653         else if (dmg <= 20)
654 /*JP
655             Your("%s suddenly aches painfully!", body_part(HEAD));
656 */
657             You("\93Ë\91R%s\92É\82É\82¨\82»\82í\82ê\82½\81I", body_part(HEAD));
658         else
659 /*JP
660             Your("%s suddenly aches very painfully!", body_part(HEAD));
661 */
662             You("\93Ë\91R\8c\83\82µ\82¢%s\92É\82É\82¨\82»\82í\82ê\82½\81I", body_part(HEAD));
663         break;
664     default:
665         impossible("mcastu: invalid magic spell (%d)", spellnum);
666         dmg = 0;
667         break;
668     }
669
670     if (dmg)
671         mdamageu(mtmp, dmg);
672 }
673
674 STATIC_OVL
675 void
676 cast_cleric_spell(mtmp, dmg, spellnum)
677 struct monst *mtmp;
678 int dmg;
679 int spellnum;
680 {
681     if (dmg == 0 && !is_undirected_spell(AD_CLRC, spellnum)) {
682         impossible("cast directed cleric spell (%d) with dmg=0?", spellnum);
683         return;
684     }
685
686     switch (spellnum) {
687     case CLC_GEYSER:
688         /* this is physical damage (force not heat),
689          * not magical damage or fire damage
690          */
691 /*JP
692         pline("A sudden geyser slams into you from nowhere!");
693 */
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");
695         dmg = d(8, 6);
696         if (Half_physical_damage)
697             dmg = (dmg + 1) / 2;
698         break;
699     case CLC_FIRE_PILLAR:
700 /*JP
701         pline("A pillar of fire strikes all around you!");
702 */
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);
706             dmg = 0;
707         } else
708             dmg = d(8, 6);
709         if (Half_spell_damage)
710             dmg = (dmg + 1) / 2;
711         burn_away_slime();
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);
717         break;
718     case CLC_LIGHTNING: {
719         boolean reflects;
720
721 /*JP
722         pline("A bolt of lightning strikes down at you from above!");
723 */
724         pline("\82 \82È\82½\82Ì\90^\8fã\82©\82ç\88î\8dÈ\82ª\8d~\82è\92\8d\82¢\82¾\81I");
725 /*JP
726         reflects = ureflects("It bounces off your %s%s.", "");
727 */
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);
731             dmg = 0;
732             if (reflects)
733                 break;
734         } else
735             dmg = d(8, 6);
736         if (Half_spell_damage)
737             dmg = (dmg + 1) / 2;
738         destroy_item(WAND_CLASS, AD_ELEC);
739         destroy_item(RING_CLASS, AD_ELEC);
740         (void) flashburn((long) rnd(100));
741         break;
742     }
743     case CLC_CURSE_ITEMS:
744 /*JP
745         You_feel("as if you need some help.");
746 */
747         You_feel("\8f\95\82¯\82ª\95K\97v\82È\8bC\82ª\82µ\82½\81D");
748         rndcurse();
749         dmg = 0;
750         break;
751     case CLC_INSECTS: {
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;
759         coord bypos;
760         const char *fmt;
761
762         oldseen = monster_census(TRUE);
763         quan = (mtmp->m_lev < 2) ? 1 : rnd((int) mtmp->m_lev / 2);
764         if (quan < 3)
765             quan = 3;
766         for (i = 0; i <= quan; i++) {
767             if (!enexto(&bypos, mtmp->mux, mtmp->muy, mtmp->data))
768                 break;
769             if ((pm = mkclass(let, 0)) != 0
770                 && (mtmp2 = makemon(pm, bypos.x, bypos.y, MM_ANGRY)) != 0) {
771                 success = TRUE;
772                 mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0;
773                 set_malign(mtmp2);
774             }
775         }
776         newseen = monster_census(TRUE);
777
778         /* not canspotmon(), which includes unseen things sensed via warning
779          */
780         seecaster = canseemon(mtmp) || tp_sensemon(mtmp) || Detect_monsters;
781
782         fmt = 0;
783         if (!seecaster) {
784             char *arg; /* [not const: upstart(N==1 ? an() : makeplural())] */
785 /*JP
786             const char *what = (let == S_SNAKE) ? "snake" : "insect";
787 */
788             const char *what = (let == S_SNAKE) ? "\83w\83r" : "\92\8e";
789
790             if (newseen <= oldseen || Unaware) {
791                 /* unseen caster fails or summons unseen critters,
792                    or unconscious hero ("You dream that you hear...") */
793 /*JP
794                 You_hear("someone summoning %s.", makeplural(what));
795 */
796                 You_hear("\92N\82©\82ª%s\82ð\8f¢\8a«\82µ\82Ä\82¢\82é\82Ì\82ð\95·\82¢\82½\81D", what);
797             } else {
798                 /* unseen caster summoned seen critter(s) */
799                 arg = (newseen == oldseen + 1) ? an(what) : makeplural(what);
800                 if (!Deaf)
801 #if 0 /*JP:T*/
802                     You_hear("someone summoning something, and %s %s.", arg,
803                              vtense(arg, "appear"));
804 #else
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",
806                              arg);
807 #endif
808                 else
809 /*JP
810                     pline("%s %s.", upstart(arg), vtense(arg, "appear"));
811 */
812                     pline("%s\82ª\8c»\82ê\82½\81D", arg);
813             }
814
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) */
820         } else if (!success)
821 /*JP
822             fmt = "%s casts at a clump of sticks, but nothing happens.";
823 */
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)
826 /*JP
827             fmt = "%s transforms a clump of sticks into snakes!";
828 */
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))
832 /*JP
833             fmt = "%s summons insects around a spot near you!";
834 */
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))
837 /*JP
838             fmt = "%s summons insects around your displaced image!";
839 */
840             fmt = "%s\82Í\92\8e\82ð\82 \82È\82½\82Ì\8c\89e\82Ì\8eü\82è\82É\8f¢\8a«\82µ\82½\81I";
841         else
842 /*JP
843             fmt = "%s summons insects!";
844 */
845             fmt = "%s\82Í\92\8e\82ð\8f¢\8a«\82µ\82½\81I";
846         if (fmt)
847             pline(fmt, Monnam(mtmp));
848
849         dmg = 0;
850         break;
851     }
852     case CLC_BLIND_YOU:
853         /* note: resists_blnd() doesn't apply here */
854         if (!Blinded) {
855 #if 0 /*JP:T*/
856             int num_eyes = eyecount(youmonst.data);
857             pline("Scales cover your %s!", (num_eyes == 1)
858                                                ? body_part(EYE)
859                                                : makeplural(body_part(EYE)));
860 #else
861             pline("\97Ø\82ª\82 \82È\82½\82Ì%s\82ð\95¢\82Á\82½\81I", body_part(EYE));
862 #endif
863             make_blinded(Half_spell_damage ? 100L : 200L, FALSE);
864             if (!Blind)
865                 Your1(vision_clears);
866             dmg = 0;
867         } else
868             impossible("no reason for monster to cast blindness spell?");
869         break;
870     case CLC_PARALYZE:
871         if (Antimagic || Free_action) {
872             shieldeff(u.ux, u.uy);
873             if (multi >= 0)
874 /*JP
875                 You("stiffen briefly.");
876 */
877                 You("\88ê\8fu\8dd\92¼\82µ\82½\81D");
878             nomul(-1);
879 /*JP
880             multi_reason = "paralyzed by a monster";
881 */
882             multi_reason = "\89ö\95¨\82É\96\83á\83\82³\82¹\82ç\82ê\82½\8c\84\82É";
883         } else {
884             if (multi >= 0)
885 /*JP
886                 You("are frozen in place!");
887 */
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)
891                 dmg = (dmg + 1) / 2;
892             nomul(-dmg);
893 /*JP
894             multi_reason = "paralyzed by a monster";
895 */
896             multi_reason = "\89ö\95¨\82É\96\83á\83\82³\82¹\82ç\82ê\82½\8c\84\82É";
897         }
898         nomovemsg = 0;
899         dmg = 0;
900         break;
901     case CLC_CONFUSE_YOU:
902         if (Antimagic) {
903             shieldeff(u.ux, u.uy);
904 /*JP
905             You_feel("momentarily dizzy.");
906 */
907             You("\88ê\8fu\82ß\82Ü\82¢\82ª\82µ\82½\81D");
908         } else {
909             boolean oldprop = !!Confusion;
910
911             dmg = (int) mtmp->m_lev;
912             if (Half_spell_damage)
913                 dmg = (dmg + 1) / 2;
914             make_confused(HConfusion + dmg, TRUE);
915             if (Hallucination)
916 /*JP
917                 You_feel("%s!", oldprop ? "trippier" : "trippy");
918 */
919                 You("%s\82Ö\82ë\82Ö\82ë\82É\82È\82Á\82½\81I", oldprop ? "\82à\82Á\82Æ" : "");
920             else
921 /*JP
922                 You_feel("%sconfused!", oldprop ? "more " : "");
923 */
924                 You("%s\8d¬\97\90\82µ\82½\81I", oldprop ? "\82à\82Á\82Æ" : "");
925         }
926         dmg = 0;
927         break;
928     case CLC_CURE_SELF:
929         dmg = m_cure_self(mtmp, dmg);
930         break;
931     case CLC_OPEN_WOUNDS:
932         if (Antimagic) {
933             shieldeff(u.ux, u.uy);
934             dmg = (dmg + 1) / 2;
935         }
936         if (dmg <= 5)
937 /*JP
938             Your("skin itches badly for a moment.");
939 */
940             Your("\94ç\95\86\82Í\88ê\8fu\81C\83\80\83Y\83\80\83Y\82Á\82Æ\82µ\82½\81D");
941         else if (dmg <= 10)
942 /*JP
943             pline("Wounds appear on your body!");
944 */
945             pline("\8f\9d\82ª\82 \82È\82½\82Ì\91Ì\82É\8fo\97\88\82½\81I");
946         else if (dmg <= 20)
947 /*JP
948             pline("Severe wounds appear on your body!");
949 */
950             pline("\82Ð\82Ç\82¢\8f\9d\82ª\82 \82È\82½\82Ì\91Ì\82É\8fo\97\88\82½\81I");
951         else
952 /*JP
953             Your("body is covered with painful wounds!");
954 */
955             pline("\91Ì\82ª\8f\9d\82¾\82ç\82¯\82É\82È\82Á\82½\81I");
956         break;
957     default:
958         impossible("mcastu: invalid clerical spell (%d)", spellnum);
959         dmg = 0;
960         break;
961     }
962
963     if (dmg)
964         mdamageu(mtmp, dmg);
965 }
966
967 STATIC_DCL
968 boolean
969 is_undirected_spell(adtyp, spellnum)
970 unsigned int adtyp;
971 int spellnum;
972 {
973     if (adtyp == AD_SPEL) {
974         switch (spellnum) {
975         case MGC_CLONE_WIZ:
976         case MGC_SUMMON_MONS:
977         case MGC_AGGRAVATION:
978         case MGC_DISAPPEAR:
979         case MGC_HASTE_SELF:
980         case MGC_CURE_SELF:
981             return TRUE;
982         default:
983             break;
984         }
985     } else if (adtyp == AD_CLRC) {
986         switch (spellnum) {
987         case CLC_INSECTS:
988         case CLC_CURE_SELF:
989             return TRUE;
990         default:
991             break;
992         }
993     }
994     return FALSE;
995 }
996
997 /* Some spells are useless under some circumstances. */
998 STATIC_DCL
999 boolean
1000 spell_would_be_useless(mtmp, adtyp, spellnum)
1001 struct monst *mtmp;
1002 unsigned int adtyp;
1003 int spellnum;
1004 {
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".
1010      */
1011     boolean mcouldseeu = couldsee(mtmp->mx, mtmp->my);
1012
1013     if (adtyp == AD_SPEL) {
1014         /* aggravate monsters, etc. won't be cast by peaceful monsters */
1015         if (mtmp->mpeaceful
1016             && (spellnum == MGC_AGGRAVATION || spellnum == MGC_SUMMON_MONS
1017                 || spellnum == MGC_CLONE_WIZ))
1018             return TRUE;
1019         /* haste self when already fast */
1020         if (mtmp->permspeed == MFAST && spellnum == MGC_HASTE_SELF)
1021             return TRUE;
1022         /* invisibility when already invisible */
1023         if ((mtmp->minvis || mtmp->invis_blkd) && spellnum == MGC_DISAPPEAR)
1024             return TRUE;
1025         /* peaceful monster won't cast invisibility if you can't see
1026            invisible,
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)
1031             return TRUE;
1032         /* healing when already healed */
1033         if (mtmp->mhp == mtmp->mhpmax && spellnum == MGC_CURE_SELF)
1034             return TRUE;
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)))
1038             return TRUE;
1039         if ((!mtmp->iswiz || context.no_of_wizards > 1)
1040             && spellnum == MGC_CLONE_WIZ)
1041             return TRUE;
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;
1050         }
1051     } else if (adtyp == AD_CLRC) {
1052         /* summon insects/sticks to snakes won't be cast by peaceful monsters
1053          */
1054         if (mtmp->mpeaceful && spellnum == CLC_INSECTS)
1055             return TRUE;
1056         /* healing when already healed */
1057         if (mtmp->mhp == mtmp->mhpmax && spellnum == CLC_CURE_SELF)
1058             return TRUE;
1059         /* don't summon insects if it doesn't think you're around */
1060         if (!mcouldseeu && spellnum == CLC_INSECTS)
1061             return TRUE;
1062         /* blindness spell on blinded player */
1063         if (Blinded && spellnum == CLC_BLIND_YOU)
1064             return TRUE;
1065     }
1066     return FALSE;
1067 }
1068
1069 /* convert 1..10 to 0..9; add 10 for second group (spell casting) */
1070 #define ad_to_typ(k) (10 + (int) k - 1)
1071
1072 /* monster uses spell (ranged) */
1073 int
1074 buzzmu(mtmp, mattk)
1075 register struct monst *mtmp;
1076 register struct attack *mattk;
1077 {
1078     /* don't print constant stream of curse messages for 'normal'
1079        spellcasting monsters at range */
1080     if (mattk->adtyp > AD_SPC2)
1081         return (0);
1082
1083     if (mtmp->mcan) {
1084         cursetxt(mtmp, FALSE);
1085         return (0);
1086     }
1087     if (lined_up(mtmp) && rn2(3)) {
1088         nomul(0);
1089         if (mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */
1090             if (canseemon(mtmp))
1091 #if 0 /*JP:T*/
1092                 pline("%s zaps you with a %s!", Monnam(mtmp),
1093                       flash_types[ad_to_typ(mattk->adtyp)]);
1094 #else
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)]);
1097 #endif
1098             buzz(-ad_to_typ(mattk->adtyp), (int) mattk->damn, mtmp->mx,
1099                  mtmp->my, sgn(tbx), sgn(tby));
1100         } else
1101             impossible("Monster spell %d cast", mattk->adtyp - 1);
1102     }
1103     return (1);
1104 }
1105
1106 /*mcastu.c*/