OSDN Git Service

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