OSDN Git Service

update year to 2020
[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-2020            */
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 #endif
501         if (mtmp->iswiz) {
502 /*JP
503             verbalize("Destroy the thief, my pet%s!", plur(count));
504 */
505             verbalize("\93\90\91¯\82ð\8eE\82¹\81I\89ä\82ª\89º\96l\82æ\81I");
506         } else {
507 #if 0 /*JP*/
508             const char *mappear = (count == 1) ? "A monster appears"
509                                                : "Monsters appear";
510 #endif
511
512             /* messages not quite right if plural monsters created but
513                only a single monster is seen */
514             if (Invis && !perceives(mtmp->data)
515                 && (mtmp->mux != u.ux || mtmp->muy != u.uy))
516 #if 0 /*JP:T*/
517                 pline("%s around a spot near you!", mappear);
518 #else
519                 pline("\89ö\95¨\82ª\82 \82È\82½\82Ì\82·\82®\82»\82Î\82É\8c»\82ê\82½\81I");
520 #endif
521             else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
522 #if 0 /*JP:T*/
523                 pline("%s around your displaced image!", mappear);
524 #else
525                 pline("\89ö\95¨\82ª\82 \82È\82½\82Ì\8c\89e\82Ì\82·\82®\82»\82Î\82É\8c»\82ê\82½\81I");
526 #endif
527             else
528 #if 0 /*JP:T*/
529                 pline("%s from nowhere!", mappear);
530 #else
531                 pline("\89ö\95¨\82ª\82Ç\82±\82©\82ç\82Æ\82à\82È\82­\8c»\82ê\82½\81I");
532 #endif
533         }
534         dmg = 0;
535         break;
536     }
537     case MGC_AGGRAVATION:
538 /*JP
539         You_feel("that monsters are aware of your presence.");
540 */
541         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");
542         aggravate();
543         dmg = 0;
544         break;
545     case MGC_CURSE_ITEMS:
546 /*JP
547         You_feel("as if you need some help.");
548 */
549         You_feel("\8f\95\82¯\82ª\95K\97v\82È\8bC\82ª\82µ\82½\81D");
550         rndcurse();
551         dmg = 0;
552         break;
553     case MGC_DESTRY_ARMR:
554         if (Antimagic) {
555             shieldeff(u.ux, u.uy);
556 /*JP
557             pline("A field of force surrounds you!");
558 */
559             pline("\95s\8ev\8bc\82È\97Í\82ª\82 \82È\82½\82ð\82Æ\82è\82Ü\82¢\82½\81I");
560         } else if (!destroy_arm(some_armor(&youmonst))) {
561 /*JP
562             Your("skin itches.");
563 */
564             You("\83\80\83Y\83\80\83Y\82µ\82½\81D");
565         }
566         dmg = 0;
567         break;
568     case MGC_WEAKEN_YOU: /* drain strength */
569         if (Antimagic) {
570             shieldeff(u.ux, u.uy);
571 /*JP
572             You_feel("momentarily weakened.");
573 */
574             You_feel("\88ê\8fu\8eã\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
575         } else {
576 /*JP
577             You("suddenly feel weaker!");
578 */
579             You("\93Ë\91R\8eã\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
580             dmg = mtmp->m_lev - 6;
581             if (Half_spell_damage)
582                 dmg = (dmg + 1) / 2;
583             losestr(rnd(dmg));
584             if (u.uhp < 1)
585                 done_in_by(mtmp, DIED);
586         }
587         dmg = 0;
588         break;
589     case MGC_DISAPPEAR: /* makes self invisible */
590         if (!mtmp->minvis && !mtmp->invis_blkd) {
591             if (canseemon(mtmp))
592 #if 0 /*JP:T*/
593                 pline("%s suddenly %s!", Monnam(mtmp),
594                       !See_invisible ? "disappears" : "becomes transparent");
595 #else
596                 pline("%s\82Í\93Ë\91R%s\81I", Monnam(mtmp),
597                       !See_invisible ? "\8fÁ\82¦\82½" : "\93§\96¾\82É\82È\82Á\82½");
598 #endif
599             mon_set_minvis(mtmp);
600             if (cansee(mtmp->mx, mtmp->my) && !canspotmon(mtmp))
601                 map_invisible(mtmp->mx, mtmp->my);
602             dmg = 0;
603         } else
604             impossible("no reason for monster to cast disappear spell?");
605         break;
606     case MGC_STUN_YOU:
607         if (Antimagic || Free_action) {
608             shieldeff(u.ux, u.uy);
609             if (!Stunned)
610 /*JP
611                 You_feel("momentarily disoriented.");
612 */
613                 You("\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\81D");
614             make_stunned(1L, FALSE);
615         } else {
616 /*JP
617             You(Stunned ? "struggle to keep your balance." : "reel...");
618 */
619             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");
620             dmg = d(ACURR(A_DEX) < 12 ? 6 : 4, 4);
621             if (Half_spell_damage)
622                 dmg = (dmg + 1) / 2;
623             make_stunned((HStun & TIMEOUT) + (long) dmg, FALSE);
624         }
625         dmg = 0;
626         break;
627     case MGC_HASTE_SELF:
628         mon_adjust_speed(mtmp, 1, (struct obj *) 0);
629         dmg = 0;
630         break;
631     case MGC_CURE_SELF:
632         dmg = m_cure_self(mtmp, dmg);
633         break;
634     case MGC_PSI_BOLT:
635         /* prior to 3.4.0 Antimagic was setting the damage to 1--this
636            made the spell virtually harmless to players with magic res. */
637         if (Antimagic) {
638             shieldeff(u.ux, u.uy);
639             dmg = (dmg + 1) / 2;
640         }
641         if (dmg <= 5)
642 /*JP
643             You("get a slight %sache.", body_part(HEAD));
644 */
645             You("\82¿\82å\82Á\82Æ%s\92É\82ª\82µ\82½\81D",body_part(HEAD));
646         else if (dmg <= 10)
647 /*JP
648             Your("brain is on fire!");
649 */
650             You("\93{\82è\82É\82Â\82Â\82Ü\82ê\82½\81I");
651         else if (dmg <= 20)
652 /*JP
653             Your("%s suddenly aches painfully!", body_part(HEAD));
654 */
655             You("\93Ë\91R%s\92É\82É\82¨\82»\82í\82ê\82½\81I", body_part(HEAD));
656         else
657 /*JP
658             Your("%s suddenly aches very painfully!", body_part(HEAD));
659 */
660             You("\93Ë\91R\8c\83\82µ\82¢%s\92É\82É\82¨\82»\82í\82ê\82½\81I", body_part(HEAD));
661         break;
662     default:
663         impossible("mcastu: invalid magic spell (%d)", spellnum);
664         dmg = 0;
665         break;
666     }
667
668     if (dmg)
669         mdamageu(mtmp, dmg);
670 }
671
672 STATIC_OVL
673 void
674 cast_cleric_spell(mtmp, dmg, spellnum)
675 struct monst *mtmp;
676 int dmg;
677 int spellnum;
678 {
679     if (dmg == 0 && !is_undirected_spell(AD_CLRC, spellnum)) {
680         impossible("cast directed cleric spell (%d) with dmg=0?", spellnum);
681         return;
682     }
683
684     switch (spellnum) {
685     case CLC_GEYSER:
686         /* this is physical damage (force not heat),
687          * not magical damage or fire damage
688          */
689 /*JP
690         pline("A sudden geyser slams into you from nowhere!");
691 */
692         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");
693         dmg = d(8, 6);
694         if (Half_physical_damage)
695             dmg = (dmg + 1) / 2;
696         break;
697     case CLC_FIRE_PILLAR:
698 /*JP
699         pline("A pillar of fire strikes all around you!");
700 */
701         pline("\82 \82È\82½\82Ì\8eü\82è\82É\89Î\92\8c\82ª\97§\82Á\82½\81I");
702         if (Fire_resistance) {
703             shieldeff(u.ux, u.uy);
704             dmg = 0;
705         } else
706             dmg = d(8, 6);
707         if (Half_spell_damage)
708             dmg = (dmg + 1) / 2;
709         burn_away_slime();
710         (void) burnarmor(&youmonst);
711         destroy_item(SCROLL_CLASS, AD_FIRE);
712         destroy_item(POTION_CLASS, AD_FIRE);
713         destroy_item(SPBOOK_CLASS, AD_FIRE);
714         (void) burn_floor_objects(u.ux, u.uy, TRUE, FALSE);
715         break;
716     case CLC_LIGHTNING: {
717         boolean reflects;
718
719 /*JP
720         pline("A bolt of lightning strikes down at you from above!");
721 */
722         pline("\82 \82È\82½\82Ì\90^\8fã\82©\82ç\88î\8dÈ\82ª\8d~\82è\92\8d\82¢\82¾\81I");
723 /*JP
724         reflects = ureflects("It bounces off your %s%s.", "");
725 */
726         reflects = ureflects("\82»\82ê\82Í\82 \82È\82½\82Ì%s%s\82Å\92µ\82Ë\95Ô\82Á\82½\81D", "");
727         if (reflects || Shock_resistance) {
728             shieldeff(u.ux, u.uy);
729             dmg = 0;
730             if (reflects)
731                 break;
732         } else
733             dmg = d(8, 6);
734         if (Half_spell_damage)
735             dmg = (dmg + 1) / 2;
736         destroy_item(WAND_CLASS, AD_ELEC);
737         destroy_item(RING_CLASS, AD_ELEC);
738         (void) flashburn((long) rnd(100));
739         break;
740     }
741     case CLC_CURSE_ITEMS:
742 /*JP
743         You_feel("as if you need some help.");
744 */
745         You_feel("\8f\95\82¯\82ª\95K\97v\82È\8bC\82ª\82µ\82½\81D");
746         rndcurse();
747         dmg = 0;
748         break;
749     case CLC_INSECTS: {
750         /* Try for insects, and if there are none
751            left, go for (sticks to) snakes.  -3. */
752         struct permonst *pm = mkclass(S_ANT, 0);
753         struct monst *mtmp2 = (struct monst *) 0;
754         char let = (pm ? S_ANT : S_SNAKE);
755         boolean success = FALSE, seecaster;
756         int i, quan, oldseen, newseen;
757         coord bypos;
758         const char *fmt;
759
760         oldseen = monster_census(TRUE);
761         quan = (mtmp->m_lev < 2) ? 1 : rnd((int) mtmp->m_lev / 2);
762         if (quan < 3)
763             quan = 3;
764         for (i = 0; i <= quan; i++) {
765             if (!enexto(&bypos, mtmp->mux, mtmp->muy, mtmp->data))
766                 break;
767             if ((pm = mkclass(let, 0)) != 0
768                 && (mtmp2 = makemon(pm, bypos.x, bypos.y, MM_ANGRY)) != 0) {
769                 success = TRUE;
770                 mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0;
771                 set_malign(mtmp2);
772             }
773         }
774         newseen = monster_census(TRUE);
775
776         /* not canspotmon(), which includes unseen things sensed via warning
777          */
778         seecaster = canseemon(mtmp) || tp_sensemon(mtmp) || Detect_monsters;
779
780         fmt = 0;
781         if (!seecaster) {
782             char *arg; /* [not const: upstart(N==1 ? an() : makeplural())] */
783 /*JP
784             const char *what = (let == S_SNAKE) ? "snake" : "insect";
785 */
786             const char *what = (let == S_SNAKE) ? "\83w\83r" : "\92\8e";
787
788             if (newseen <= oldseen || Unaware) {
789                 /* unseen caster fails or summons unseen critters,
790                    or unconscious hero ("You dream that you hear...") */
791 /*JP
792                 You_hear("someone summoning %s.", makeplural(what));
793 */
794                 You_hear("\92N\82©\82ª%s\82ð\8f¢\8a«\82µ\82Ä\82¢\82é\82Ì\82ð\95·\82¢\82½\81D", what);
795             } else {
796                 /* unseen caster summoned seen critter(s) */
797                 arg = (newseen == oldseen + 1) ? an(what) : makeplural(what);
798                 if (!Deaf)
799 #if 0 /*JP:T*/
800                     You_hear("someone summoning something, and %s %s.", arg,
801                              vtense(arg, "appear"));
802 #else
803                     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",
804                              arg);
805 #endif
806                 else
807 /*JP
808                     pline("%s %s.", upstart(arg), vtense(arg, "appear"));
809 */
810                     pline("%s\82ª\8c»\82ê\82½\81D", arg);
811             }
812
813         /* seen caster, possibly producing unseen--or just one--critters;
814            hero is told what the caster is doing and doesn't necessarily
815            observe complete accuracy of that caster's results (in other
816            words, no need to fuss with visibility or singularization;
817            player is told what's happening even if hero is unconscious) */
818         } else if (!success)
819 /*JP
820             fmt = "%s casts at a clump of sticks, but nothing happens.";
821 */
822             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";
823         else if (let == S_SNAKE)
824 /*JP
825             fmt = "%s transforms a clump of sticks into snakes!";
826 */
827             fmt = "%s\82Í\96_\90Ø\82ê\82ð\83w\83r\82É\95Ï\82¦\82½\81I";
828         else if (Invis && !perceives(mtmp->data)
829                  && (mtmp->mux != u.ux || mtmp->muy != u.uy))
830 /*JP
831             fmt = "%s summons insects around a spot near you!";
832 */
833             fmt = "%s\82Í\92\8e\82ð\82 \82È\82½\82Ì\82·\82®\82»\82Î\82É\8f¢\8a«\82µ\82½\81I";
834         else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
835 /*JP
836             fmt = "%s summons insects around your displaced image!";
837 */
838             fmt = "%s\82Í\92\8e\82ð\82 \82È\82½\82Ì\8c\89e\82Ì\8eü\82è\82É\8f¢\8a«\82µ\82½\81I";
839         else
840 /*JP
841             fmt = "%s summons insects!";
842 */
843             fmt = "%s\82Í\92\8e\82ð\8f¢\8a«\82µ\82½\81I";
844         if (fmt)
845             pline(fmt, Monnam(mtmp));
846
847         dmg = 0;
848         break;
849     }
850     case CLC_BLIND_YOU:
851         /* note: resists_blnd() doesn't apply here */
852         if (!Blinded) {
853 #if 0 /*JP:T*/
854             int num_eyes = eyecount(youmonst.data);
855             pline("Scales cover your %s!", (num_eyes == 1)
856                                                ? body_part(EYE)
857                                                : makeplural(body_part(EYE)));
858 #else
859             pline("\97Ø\82ª\82 \82È\82½\82Ì%s\82ð\95¢\82Á\82½\81I", body_part(EYE));
860 #endif
861             make_blinded(Half_spell_damage ? 100L : 200L, FALSE);
862             if (!Blind)
863                 Your1(vision_clears);
864             dmg = 0;
865         } else
866             impossible("no reason for monster to cast blindness spell?");
867         break;
868     case CLC_PARALYZE:
869         if (Antimagic || Free_action) {
870             shieldeff(u.ux, u.uy);
871             if (multi >= 0)
872 /*JP
873                 You("stiffen briefly.");
874 */
875                 You("\88ê\8fu\8dd\92¼\82µ\82½\81D");
876             nomul(-1);
877 /*JP
878             multi_reason = "paralyzed by a monster";
879 */
880             multi_reason = "\89ö\95¨\82É\96\83á\83\82³\82¹\82ç\82ê\82½\8c\84\82É";
881         } else {
882             if (multi >= 0)
883 /*JP
884                 You("are frozen in place!");
885 */
886                 You("\82»\82Ì\8fê\82Å\93®\82¯\82È\82­\82È\82Á\82½\81I");
887             dmg = 4 + (int) mtmp->m_lev;
888             if (Half_spell_damage)
889                 dmg = (dmg + 1) / 2;
890             nomul(-dmg);
891 /*JP
892             multi_reason = "paralyzed by a monster";
893 */
894             multi_reason = "\89ö\95¨\82É\96\83á\83\82³\82¹\82ç\82ê\82½\8c\84\82É";
895         }
896         nomovemsg = 0;
897         dmg = 0;
898         break;
899     case CLC_CONFUSE_YOU:
900         if (Antimagic) {
901             shieldeff(u.ux, u.uy);
902 /*JP
903             You_feel("momentarily dizzy.");
904 */
905             You("\88ê\8fu\82ß\82Ü\82¢\82ª\82µ\82½\81D");
906         } else {
907             boolean oldprop = !!Confusion;
908
909             dmg = (int) mtmp->m_lev;
910             if (Half_spell_damage)
911                 dmg = (dmg + 1) / 2;
912             make_confused(HConfusion + dmg, TRUE);
913             if (Hallucination)
914 /*JP
915                 You_feel("%s!", oldprop ? "trippier" : "trippy");
916 */
917                 You("%s\82Ö\82ë\82Ö\82ë\82É\82È\82Á\82½\81I", oldprop ? "\82à\82Á\82Æ" : "");
918             else
919 /*JP
920                 You_feel("%sconfused!", oldprop ? "more " : "");
921 */
922                 You("%s\8d¬\97\90\82µ\82½\81I", oldprop ? "\82à\82Á\82Æ" : "");
923         }
924         dmg = 0;
925         break;
926     case CLC_CURE_SELF:
927         dmg = m_cure_self(mtmp, dmg);
928         break;
929     case CLC_OPEN_WOUNDS:
930         if (Antimagic) {
931             shieldeff(u.ux, u.uy);
932             dmg = (dmg + 1) / 2;
933         }
934         if (dmg <= 5)
935 /*JP
936             Your("skin itches badly for a moment.");
937 */
938             Your("\94ç\95\86\82Í\88ê\8fu\81C\83\80\83Y\83\80\83Y\82Á\82Æ\82µ\82½\81D");
939         else if (dmg <= 10)
940 /*JP
941             pline("Wounds appear on your body!");
942 */
943             pline("\8f\9d\82ª\82 \82È\82½\82Ì\91Ì\82É\8fo\97\88\82½\81I");
944         else if (dmg <= 20)
945 /*JP
946             pline("Severe wounds appear on your body!");
947 */
948             pline("\82Ð\82Ç\82¢\8f\9d\82ª\82 \82È\82½\82Ì\91Ì\82É\8fo\97\88\82½\81I");
949         else
950 /*JP
951             Your("body is covered with painful wounds!");
952 */
953             pline("\91Ì\82ª\8f\9d\82¾\82ç\82¯\82É\82È\82Á\82½\81I");
954         break;
955     default:
956         impossible("mcastu: invalid clerical spell (%d)", spellnum);
957         dmg = 0;
958         break;
959     }
960
961     if (dmg)
962         mdamageu(mtmp, dmg);
963 }
964
965 STATIC_DCL
966 boolean
967 is_undirected_spell(adtyp, spellnum)
968 unsigned int adtyp;
969 int spellnum;
970 {
971     if (adtyp == AD_SPEL) {
972         switch (spellnum) {
973         case MGC_CLONE_WIZ:
974         case MGC_SUMMON_MONS:
975         case MGC_AGGRAVATION:
976         case MGC_DISAPPEAR:
977         case MGC_HASTE_SELF:
978         case MGC_CURE_SELF:
979             return TRUE;
980         default:
981             break;
982         }
983     } else if (adtyp == AD_CLRC) {
984         switch (spellnum) {
985         case CLC_INSECTS:
986         case CLC_CURE_SELF:
987             return TRUE;
988         default:
989             break;
990         }
991     }
992     return FALSE;
993 }
994
995 /* Some spells are useless under some circumstances. */
996 STATIC_DCL
997 boolean
998 spell_would_be_useless(mtmp, adtyp, spellnum)
999 struct monst *mtmp;
1000 unsigned int adtyp;
1001 int spellnum;
1002 {
1003     /* Some spells don't require the player to really be there and can be cast
1004      * by the monster when you're invisible, yet still shouldn't be cast when
1005      * the monster doesn't even think you're there.
1006      * This check isn't quite right because it always uses your real position.
1007      * We really want something like "if the monster could see mux, muy".
1008      */
1009     boolean mcouldseeu = couldsee(mtmp->mx, mtmp->my);
1010
1011     if (adtyp == AD_SPEL) {
1012         /* aggravate monsters, etc. won't be cast by peaceful monsters */
1013         if (mtmp->mpeaceful
1014             && (spellnum == MGC_AGGRAVATION || spellnum == MGC_SUMMON_MONS
1015                 || spellnum == MGC_CLONE_WIZ))
1016             return TRUE;
1017         /* haste self when already fast */
1018         if (mtmp->permspeed == MFAST && spellnum == MGC_HASTE_SELF)
1019             return TRUE;
1020         /* invisibility when already invisible */
1021         if ((mtmp->minvis || mtmp->invis_blkd) && spellnum == MGC_DISAPPEAR)
1022             return TRUE;
1023         /* peaceful monster won't cast invisibility if you can't see
1024            invisible,
1025            same as when monsters drink potions of invisibility.  This doesn't
1026            really make a lot of sense, but lets the player avoid hitting
1027            peaceful monsters by mistake */
1028         if (mtmp->mpeaceful && !See_invisible && spellnum == MGC_DISAPPEAR)
1029             return TRUE;
1030         /* healing when already healed */
1031         if (mtmp->mhp == mtmp->mhpmax && spellnum == MGC_CURE_SELF)
1032             return TRUE;
1033         /* don't summon monsters if it doesn't think you're around */
1034         if (!mcouldseeu && (spellnum == MGC_SUMMON_MONS
1035                             || (!mtmp->iswiz && spellnum == MGC_CLONE_WIZ)))
1036             return TRUE;
1037         if ((!mtmp->iswiz || context.no_of_wizards > 1)
1038             && spellnum == MGC_CLONE_WIZ)
1039             return TRUE;
1040         /* aggravation (global wakeup) when everyone is already active */
1041         if (spellnum == MGC_AGGRAVATION) {
1042             /* if nothing needs to be awakened then this spell is useless
1043                but caster might not realize that [chance to pick it then
1044                must be very small otherwise caller's many retry attempts
1045                will eventually end up picking it too often] */
1046             if (!has_aggravatables(mtmp))
1047                 return rn2(100) ? TRUE : FALSE;
1048         }
1049     } else if (adtyp == AD_CLRC) {
1050         /* summon insects/sticks to snakes won't be cast by peaceful monsters
1051          */
1052         if (mtmp->mpeaceful && spellnum == CLC_INSECTS)
1053             return TRUE;
1054         /* healing when already healed */
1055         if (mtmp->mhp == mtmp->mhpmax && spellnum == CLC_CURE_SELF)
1056             return TRUE;
1057         /* don't summon insects if it doesn't think you're around */
1058         if (!mcouldseeu && spellnum == CLC_INSECTS)
1059             return TRUE;
1060         /* blindness spell on blinded player */
1061         if (Blinded && spellnum == CLC_BLIND_YOU)
1062             return TRUE;
1063     }
1064     return FALSE;
1065 }
1066
1067 /* convert 1..10 to 0..9; add 10 for second group (spell casting) */
1068 #define ad_to_typ(k) (10 + (int) k - 1)
1069
1070 /* monster uses spell (ranged) */
1071 int
1072 buzzmu(mtmp, mattk)
1073 register struct monst *mtmp;
1074 register struct attack *mattk;
1075 {
1076     /* don't print constant stream of curse messages for 'normal'
1077        spellcasting monsters at range */
1078     if (mattk->adtyp > AD_SPC2)
1079         return (0);
1080
1081     if (mtmp->mcan) {
1082         cursetxt(mtmp, FALSE);
1083         return (0);
1084     }
1085     if (lined_up(mtmp) && rn2(3)) {
1086         nomul(0);
1087         if (mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */
1088             if (canseemon(mtmp))
1089 #if 0 /*JP:T*/
1090                 pline("%s zaps you with a %s!", Monnam(mtmp),
1091                       flash_types[ad_to_typ(mattk->adtyp)]);
1092 #else
1093                 pline("%s\82Í%s\82ð\82 \82È\82½\82É\8cü\82¯\82Ä\95ú\82Á\82½\81D", Monnam(mtmp),
1094                       flash_types[ad_to_typ(mattk->adtyp)]);
1095 #endif
1096             buzz(-ad_to_typ(mattk->adtyp), (int) mattk->damn, mtmp->mx,
1097                  mtmp->my, sgn(tbx), sgn(tby));
1098         } else
1099             impossible("Monster spell %d cast", mattk->adtyp - 1);
1100     }
1101     return (1);
1102 }
1103
1104 /*mcastu.c*/