OSDN Git Service

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