Wikia

Wikihack

Source:Mcastu.c

2,032pages on
this wiki
Talk0

Below is the full text to src/mcastu.c from NetHack 3.4.3. To link to a particular line, write [[mcastu.c#line123]], for example.

Top of file Edit

1.    /*	SCCS Id: @(#)mcastu.c	3.4	2003/01/08	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
5.    #include "hack.h"
6.    

Monster mage spells Edit

7.    /* monster mage spells */
8.    #define MGC_PSI_BOLT	 0
9.    #define MGC_CURE_SELF	 1
10.   #define MGC_HASTE_SELF	 2
11.   #define MGC_STUN_YOU	 3
12.   #define MGC_DISAPPEAR	 4
13.   #define MGC_WEAKEN_YOU	 5
14.   #define MGC_DESTRY_ARMR	 6
15.   #define MGC_CURSE_ITEMS	 7
16.   #define MGC_AGGRAVATION	 8
17.   #define MGC_SUMMON_MONS	 9
18.   #define MGC_CLONE_WIZ	10
19.   #define MGC_DEATH_TOUCH	11
20.   

Monster cleric spells Edit

21.   /* monster cleric spells */
22.   #define CLC_OPEN_WOUNDS	 0
23.   #define CLC_CURE_SELF	 1
24.   #define CLC_CONFUSE_YOU	 2
25.   #define CLC_PARALYZE	 3
26.   #define CLC_BLIND_YOU	 4
27.   #define CLC_INSECTS	 5
28.   #define CLC_CURSE_ITEMS	 6
29.   #define CLC_LIGHTNING	 7
30.   #define CLC_FIRE_PILLAR	 8
31.   #define CLC_GEYSER	 9
32.   
33.   STATIC_DCL void FDECL(cursetxt,(struct monst *,BOOLEAN_P));
34.   STATIC_DCL int FDECL(choose_magic_spell, (int));
35.   STATIC_DCL int FDECL(choose_clerical_spell, (int));
36.   STATIC_DCL void FDECL(cast_wizard_spell,(struct monst *, int,int));
37.   STATIC_DCL void FDECL(cast_cleric_spell,(struct monst *, int,int));
38.   STATIC_DCL boolean FDECL(is_undirected_spell,(unsigned int,int));
39.   STATIC_DCL boolean FDECL(spell_would_be_useless,(struct monst *,unsigned int,int));
40.   
41.   #ifdef OVL0
42.   
43.   extern const char * const flash_types[];	/* from zap.c */
44.   

cursetxt Edit

45.   /* feedback when frustrated monster couldn't cast a spell */
46.   STATIC_OVL
47.   void
48.   cursetxt(mtmp, undirected)
49.   struct monst *mtmp;
50.   boolean undirected;
51.   {
52.   	if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)) {
53.   	    const char *point_msg;  /* spellcasting monsters are impolite */
54.   
55.   	    if (undirected)
56.   		point_msg = "all around, then curses";
57.   	    else if ((Invis && !perceives(mtmp->data) &&
58.   			(mtmp->mux != u.ux || mtmp->muy != u.uy)) ||
59.   		    (youmonst.m_ap_type == M_AP_OBJECT &&
60.   			youmonst.mappearance == STRANGE_OBJECT) ||
61.   		    u.uundetected)
62.   		point_msg = "and curses in your general direction";
63.   	    else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
64.   		point_msg = "and curses at your displaced image";
65.   	    else
66.   		point_msg = "at you, then curses";
67.   
68.   	    pline("%s points %s.", Monnam(mtmp), point_msg);
69.   	} else if ((!(moves % 4) || !rn2(4))) {
70.   	    if (flags.soundok) Norep("You hear a mumbled curse.");
71.   	}
72.   }
73.   
74.   #endif /* OVL0 */

choose_magic_spell Edit

75.   #ifdef OVLB
76.   
77.   /* convert a level based random selection into a specific mage spell;
78.      inappropriate choices will be screened out by spell_would_be_useless() */
79.   STATIC_OVL int
80.   choose_magic_spell(spellval)
81.   int spellval;
82.   {
83.       switch (spellval) {
84.       case 22:
85.       case 21:
86.       case 20:
87.   	return MGC_DEATH_TOUCH;
88.       case 19:
89.       case 18:
90.   	return MGC_CLONE_WIZ;
91.       case 17:
92.       case 16:
93.       case 15:
94.   	return MGC_SUMMON_MONS;
95.       case 14:
96.       case 13:
97.   	return MGC_AGGRAVATION;
98.       case 12:
99.       case 11:
100.      case 10:
101.  	return MGC_CURSE_ITEMS;
102.      case 9:
103.      case 8:
104.  	return MGC_DESTRY_ARMR;
105.      case 7:
106.      case 6:
107.  	return MGC_WEAKEN_YOU;
108.      case 5:
109.      case 4:
110.  	return MGC_DISAPPEAR;
111.      case 3:
112.  	return MGC_STUN_YOU;
113.      case 2:
114.  	return MGC_HASTE_SELF;
115.      case 1:
116.  	return MGC_CURE_SELF;
117.      case 0:
118.      default:
119.  	return MGC_PSI_BOLT;
120.      }
121.  }
122.  

choose_clerical_spell Edit

123.  /* convert a level based random selection into a specific cleric spell */
124.  STATIC_OVL int
125.  choose_clerical_spell(spellnum)
126.  int spellnum;
127.  {
128.      switch (spellnum) {
129.      case 13:
130.  	return CLC_GEYSER;
131.      case 12:
132.  	return CLC_FIRE_PILLAR;
133.      case 11:
134.  	return CLC_LIGHTNING;
135.      case 10:
136.      case 9:
137.  	return CLC_CURSE_ITEMS;
138.      case 8:
139.  	return CLC_INSECTS;
140.      case 7:
141.      case 6:
142.  	return CLC_BLIND_YOU;
143.      case 5:
144.      case 4:
145.  	return CLC_PARALYZE;
146.      case 3:
147.      case 2:
148.  	return CLC_CONFUSE_YOU;
149.      case 1:
150.  	return CLC_CURE_SELF;
151.      case 0:
152.      default:
153.  	return CLC_OPEN_WOUNDS;
154.      }
155.  }
156.  

castmu Edit

157.  /* return values:
158.   * 1: successful spell
159.   * 0: unsuccessful spell
160.   */
161.  int
162.  castmu(mtmp, mattk, thinks_it_foundyou, foundyou)
163.  	register struct monst *mtmp;
164.  	register struct attack *mattk;
165.  	boolean thinks_it_foundyou;
166.  	boolean foundyou;
167.  {
168.  	int	dmg, ml = mtmp->m_lev;
169.  	int ret;
170.  	int spellnum = 0;
171.  
172.  	/* Three cases:
173.  	 * -- monster is attacking you.  Search for a useful spell.
174.  	 * -- monster thinks it's attacking you.  Search for a useful spell,
175.  	 *    without checking for undirected.  If the spell found is directed,
176.  	 *    it fails with cursetxt() and loss of mspec_used.
177.  	 * -- monster isn't trying to attack.  Select a spell once.  Don't keep
178.  	 *    searching; if that spell is not useful (or if it's directed),
179.  	 *    return and do something else. 
180.  	 * Since most spells are directed, this means that a monster that isn't
181.  	 * attacking casts spells only a small portion of the time that an
182.  	 * attacking monster does.
183.  	 */
184.  	if ((mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) && ml) {
185.  	    int cnt = 40;
186.  
187.  	    do {
188.  		spellnum = rn2(ml);
189.  		if (mattk->adtyp == AD_SPEL)
190.  		    spellnum = choose_magic_spell(spellnum);
191.  		else
192.  		    spellnum = choose_clerical_spell(spellnum);
193.  		/* not trying to attack?  don't allow directed spells */
194.  		if (!thinks_it_foundyou) {
195.  		    if (!is_undirected_spell(mattk->adtyp, spellnum) ||
196.  			spell_would_be_useless(mtmp, mattk->adtyp, spellnum)) {
197.  			if (foundyou)
198.  			    impossible("spellcasting monster found you and doesn't know it?");
199.  			return 0;
200.  		    }
201.  		    break;
202.  		}
203.  	    } while(--cnt > 0 &&
204.  		    spell_would_be_useless(mtmp, mattk->adtyp, spellnum));
205.  	    if (cnt == 0) return 0;
206.  	}
207.  
208.  	/* monster unable to cast spells? */
209.  	if(mtmp->mcan || mtmp->mspec_used || !ml) {
210.  	    cursetxt(mtmp, is_undirected_spell(mattk->adtyp, spellnum));
211.  	    return(0);
212.  	}
213.  
214.  	if (mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) {
215.  	    mtmp->mspec_used = 10 - mtmp->m_lev;
216.  	    if (mtmp->mspec_used < 2) mtmp->mspec_used = 2;
217.  	}
218.  
219.  	/* monster can cast spells, but is casting a directed spell at the
220.  	   wrong place?  If so, give a message, and return.  Do this *after*
221.  	   penalizing mspec_used. */
222.  	if (!foundyou && thinks_it_foundyou &&
223.  		!is_undirected_spell(mattk->adtyp, spellnum)) {
224.  	    pline("%s casts a spell at %s!",
225.  		canseemon(mtmp) ? Monnam(mtmp) : "Something",
226.  		levl[mtmp->mux][mtmp->muy].typ == WATER
227.  		    ? "empty water" : "thin air");
228.  	    return(0);
229.  	}
230.  
231.  	nomul(0);
232.  	if(rn2(ml*10) < (mtmp->mconf ? 100 : 20)) {	/* fumbled attack */
233.  	    if (canseemon(mtmp) && flags.soundok)
234.  		pline_The("air crackles around %s.", mon_nam(mtmp));
235.  	    return(0);
236.  	}
237.  	if (canspotmon(mtmp) || !is_undirected_spell(mattk->adtyp, spellnum)) {
238.  	    pline("%s casts a spell%s!",
239.  		  canspotmon(mtmp) ? Monnam(mtmp) : "Something",
240.  		  is_undirected_spell(mattk->adtyp, spellnum) ? "" :
241.  		  (Invisible && !perceives(mtmp->data) && 
242.  		   (mtmp->mux != u.ux || mtmp->muy != u.uy)) ?
243.  		  " at a spot near you" :
244.  		  (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) ?
245.  		  " at your displaced image" :
246.  		  " at you");
247.  	}
248.  
249.  /*
250.   *	As these are spells, the damage is related to the level
251.   *	of the monster casting the spell.
252.   */
253.  	if (!foundyou) {
254.  	    dmg = 0;
255.  	    if (mattk->adtyp != AD_SPEL && mattk->adtyp != AD_CLRC) {
256.  		impossible(
257.  	      "%s casting non-hand-to-hand version of hand-to-hand spell %d?",
258.  			   Monnam(mtmp), mattk->adtyp);
259.  		return(0);
260.  	    }
261.  	} else if (mattk->damd)
262.  	    dmg = d((int)((ml/2) + mattk->damn), (int)mattk->damd);
263.  	else dmg = d((int)((ml/2) + 1), 6);
264.  	if (Half_spell_damage) dmg = (dmg+1) / 2;
265.  
266.  	ret = 1;
267.  
268.  	switch (mattk->adtyp) {
269.  
270.  	    case AD_FIRE:
271.  		pline("You're enveloped in flames.");
272.  		if(Fire_resistance) {
273.  			shieldeff(u.ux, u.uy);
274.  			pline("But you resist the effects.");
275.  			dmg = 0;
276.  		}
277.  		burn_away_slime();
278.  		break;
279.  	    case AD_COLD:
280.  		pline("You're covered in frost.");
281.  		if(Cold_resistance) {
282.  			shieldeff(u.ux, u.uy);
283.  			pline("But you resist the effects.");
284.  			dmg = 0;
285.  		}
286.  		break;
287.  	    case AD_MAGM:
288.  		You("are hit by a shower of missiles!");
289.  		if(Antimagic) {
290.  			shieldeff(u.ux, u.uy);
291.  			pline_The("missiles bounce off!");
292.  			dmg = 0;
293.  		} else dmg = d((int)mtmp->m_lev/2 + 1,6);
294.  		break;
295.  	    case AD_SPEL:	/* wizard spell */
296.  	    case AD_CLRC:       /* clerical spell */
297.  	    {
298.  		if (mattk->adtyp == AD_SPEL)
299.  		    cast_wizard_spell(mtmp, dmg, spellnum);
300.  		else
301.  		    cast_cleric_spell(mtmp, dmg, spellnum);
302.  		dmg = 0; /* done by the spell casting functions */
303.  		break;
304.  	    }
305.  	}
306.  	if(dmg) mdamageu(mtmp, dmg);
307.  	return(ret);
308.  }
309.  

cast_wizard_spell Edit

310.  /* monster wizard and cleric spellcasting functions */
311.  /*
312.     If dmg is zero, then the monster is not casting at you.
313.     If the monster is intentionally not casting at you, we have previously
314.     called spell_would_be_useless() and spellnum should always be a valid
315.     undirected spell.
316.     If you modify either of these, be sure to change is_undirected_spell()
317.     and spell_would_be_useless().
318.   */
319.  STATIC_OVL
320.  void
321.  cast_wizard_spell(mtmp, dmg, spellnum)
322.  struct monst *mtmp;
323.  int dmg;
324.  int spellnum;
325.  {
326.      if (dmg == 0 && !is_undirected_spell(AD_SPEL, spellnum)) {
327.  	impossible("cast directed wizard spell (%d) with dmg=0?", spellnum);
328.  	return;
329.      }
330.  
331.      switch (spellnum) {
332.      case MGC_DEATH_TOUCH:
333.  	pline("Oh no, %s's using the touch of death!", mhe(mtmp));
334.  	if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
335.  	    You("seem no deader than before.");
336.  	} else if (!Antimagic && rn2(mtmp->m_lev) > 12) {
337.  	    if (Hallucination) {
338.  		You("have an out of body experience.");
339.  	    } else {
340.  		killer_format = KILLED_BY_AN;
341.  		killer = "touch of death";
342.  		done(DIED);
343.  	    }
344.  	} else {
345.  	    if (Antimagic) shieldeff(u.ux, u.uy);
346.  	    pline("Lucky for you, it didn't work!");
347.  	}
348.  	dmg = 0;
349.  	break;
350.      case MGC_CLONE_WIZ:
351.  	if (mtmp->iswiz && flags.no_of_wizards == 1) {
352.  	    pline("Double Trouble...");
353.  	    clonewiz();
354.  	    dmg = 0;
355.  	} else
356.  	    impossible("bad wizard cloning?");
357.  	break;
358.      case MGC_SUMMON_MONS:
359.      {
360.  	int count;
361.  
362.  	count = nasty(mtmp);	/* summon something nasty */
363.  	if (mtmp->iswiz)
364.  	    verbalize("Destroy the thief, my pet%s!", plur(count));
365.  	else {
366.  	    const char *mappear =
367.  		(count == 1) ? "A monster appears" : "Monsters appear";
368.  
369.  	    /* messages not quite right if plural monsters created but
370.  	       only a single monster is seen */
371.  	    if (Invisible && !perceives(mtmp->data) &&
372.  				    (mtmp->mux != u.ux || mtmp->muy != u.uy))
373.  		pline("%s around a spot near you!", mappear);
374.  	    else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
375.  		pline("%s around your displaced image!", mappear);
376.  	    else
377.  		pline("%s from nowhere!", mappear);
378.  	}
379.  	dmg = 0;
380.  	break;
381.      }
382.      case MGC_AGGRAVATION:
383.  	You_feel("that monsters are aware of your presence.");
384.  	aggravate();
385.  	dmg = 0;
386.  	break;
387.      case MGC_CURSE_ITEMS:
388.  	You_feel("as if you need some help.");
389.  	rndcurse();
390.  	dmg = 0;
391.  	break;
392.      case MGC_DESTRY_ARMR:
393.  	if (Antimagic) {
394.  	    shieldeff(u.ux, u.uy);
395.  	    pline("A field of force surrounds you!");
396.  	} else if (!destroy_arm(some_armor(&youmonst))) {
397.  	    Your("skin itches.");
398.  	}
399.  	dmg = 0;
400.  	break;
401.      case MGC_WEAKEN_YOU:		/* drain strength */
402.  	if (Antimagic) {
403.  	    shieldeff(u.ux, u.uy);
404.  	    You_feel("momentarily weakened.");
405.  	} else {
406.  	    You("suddenly feel weaker!");
407.  	    dmg = mtmp->m_lev - 6;
408.  	    if (Half_spell_damage) dmg = (dmg + 1) / 2;
409.  	    losestr(rnd(dmg));
410.  	    if (u.uhp < 1)
411.  		done_in_by(mtmp);
412.  	}
413.  	dmg = 0;
414.  	break;
415.      case MGC_DISAPPEAR:		/* makes self invisible */
416.  	if (!mtmp->minvis && !mtmp->invis_blkd) {
417.  	    if (canseemon(mtmp))
418.  		pline("%s suddenly %s!", Monnam(mtmp),
419.  		      !See_invisible ? "disappears" : "becomes transparent");
420.  	    mon_set_minvis(mtmp);
421.  	    dmg = 0;
422.  	} else
423.  	    impossible("no reason for monster to cast disappear spell?");
424.  	break;
425.      case MGC_STUN_YOU:
426.  	if (Antimagic || Free_action) {
427.  	    shieldeff(u.ux, u.uy);
428.  	    if (!Stunned)
429.  		You_feel("momentarily disoriented.");
430.  	    make_stunned(1L, FALSE);
431.  	} else {
432.  	    You(Stunned ? "struggle to keep your balance." : "reel...");
433.  	    dmg = d(ACURR(A_DEX) < 12 ? 6 : 4, 4);
434.  	    if (Half_spell_damage) dmg = (dmg + 1) / 2;
435.  	    make_stunned(HStun + dmg, FALSE);
436.  	}
437.  	dmg = 0;
438.  	break;
439.      case MGC_HASTE_SELF:
440.  	mon_adjust_speed(mtmp, 1, (struct obj *)0);
441.  	dmg = 0;
442.  	break;
443.      case MGC_CURE_SELF:
444.  	if (mtmp->mhp < mtmp->mhpmax) {
445.  	    if (canseemon(mtmp))
446.  		pline("%s looks better.", Monnam(mtmp));
447.  	    /* note: player healing does 6d4; this used to do 1d8 */
448.  	    if ((mtmp->mhp += d(3,6)) > mtmp->mhpmax)
449.  		mtmp->mhp = mtmp->mhpmax;
450.  	    dmg = 0;
451.  	}
452.  	break;
453.      case MGC_PSI_BOLT:
454.  	/* prior to 3.4.0 Antimagic was setting the damage to 1--this
455.  	   made the spell virtually harmless to players with magic res. */
456.  	if (Antimagic) {
457.  	    shieldeff(u.ux, u.uy);
458.  	    dmg = (dmg + 1) / 2;
459.  	}
460.  	if (dmg <= 5)
461.  	    You("get a slight %sache.", body_part(HEAD));
462.  	else if (dmg <= 10)
463.  	    Your("brain is on fire!");
464.  	else if (dmg <= 20)
465.  	    Your("%s suddenly aches painfully!", body_part(HEAD));
466.  	else
467.  	    Your("%s suddenly aches very painfully!", body_part(HEAD));
468.  	break;
469.      default:
470.  	impossible("mcastu: invalid magic spell (%d)", spellnum);
471.  	dmg = 0;
472.  	break;
473.      }
474.  
475.      if (dmg) mdamageu(mtmp, dmg);
476.  }
477.  

cast_cleric_spell Edit

478.  STATIC_OVL
479.  void
480.  cast_cleric_spell(mtmp, dmg, spellnum)
481.  struct monst *mtmp;
482.  int dmg;
483.  int spellnum;
484.  {
485.      if (dmg == 0 && !is_undirected_spell(AD_CLRC, spellnum)) {
486.  	impossible("cast directed cleric spell (%d) with dmg=0?", spellnum);
487.  	return;
488.      }
489.  
490.      switch (spellnum) {
491.      case CLC_GEYSER:
492.  	/* this is physical damage, not magical damage */
493.  	pline("A sudden geyser slams into you from nowhere!");
494.  	dmg = d(8, 6);
495.  	if (Half_physical_damage) dmg = (dmg + 1) / 2;
496.  	break;
497.      case CLC_FIRE_PILLAR:
498.  	pline("A pillar of fire strikes all around you!");
499.  	if (Fire_resistance) {
500.  	    shieldeff(u.ux, u.uy);
501.  	    dmg = 0;
502.  	} else
503.  	    dmg = d(8, 6);
504.  	if (Half_spell_damage) dmg = (dmg + 1) / 2;
505.  	burn_away_slime();
506.  	(void) burnarmor(&youmonst);
507.  	destroy_item(SCROLL_CLASS, AD_FIRE);
508.  	destroy_item(POTION_CLASS, AD_FIRE);
509.  	destroy_item(SPBOOK_CLASS, AD_FIRE);
510.  	(void) burn_floor_paper(u.ux, u.uy, TRUE, FALSE);
511.  	break;
512.      case CLC_LIGHTNING:
513.      {
514.  	boolean reflects;
515.  
516.  	pline("A bolt of lightning strikes down at you from above!");
517.  	reflects = ureflects("It bounces off your %s%s.", "");
518.  	if (reflects || Shock_resistance) {
519.  	    shieldeff(u.ux, u.uy);
520.  	    dmg = 0;
521.  	    if (reflects)
522.  		break;
523.  	} else
524.  	    dmg = d(8, 6);
525.  	if (Half_spell_damage) dmg = (dmg + 1) / 2;
526.  	destroy_item(WAND_CLASS, AD_ELEC);
527.  	destroy_item(RING_CLASS, AD_ELEC);
528.  	break;
529.      }
530.      case CLC_CURSE_ITEMS:
531.  	You_feel("as if you need some help.");
532.  	rndcurse();
533.  	dmg = 0;
534.  	break;
535.      case CLC_INSECTS:
536.        {
537.  	/* Try for insects, and if there are none
538.  	   left, go for (sticks to) snakes.  -3. */
539.  	struct permonst *pm = mkclass(S_ANT,0);
540.  	struct monst *mtmp2 = (struct monst *)0;
541.  	char let = (pm ? S_ANT : S_SNAKE);
542.  	boolean success;
543.  	int i;
544.  	coord bypos;
545.  	int quan;
546.  
547.  	quan = (mtmp->m_lev < 2) ? 1 : rnd((int)mtmp->m_lev / 2);
548.  	if (quan < 3) quan = 3;
549.  	success = pm ? TRUE : FALSE;
550.  	for (i = 0; i <= quan; i++) {
551.  	    if (!enexto(&bypos, mtmp->mux, mtmp->muy, mtmp->data))
552.  		break;
553.  	    if ((pm = mkclass(let,0)) != 0 &&
554.  		    (mtmp2 = makemon(pm, bypos.x, bypos.y, NO_MM_FLAGS)) != 0) {
555.  		success = TRUE;
556.  		mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0;
557.  		set_malign(mtmp2);
558.  	    }
559.  	}
560.  	/* Not quite right:
561.           * -- message doesn't always make sense for unseen caster (particularly
562.  	 *    the first message)
563.           * -- message assumes plural monsters summoned (non-plural should be
564.           *    very rare, unlike in nasty())
565.           * -- message assumes plural monsters seen
566.           */
567.  	if (!success)
568.  	    pline("%s casts at a clump of sticks, but nothing happens.",
569.  		Monnam(mtmp));
570.  	else if (let == S_SNAKE)
571.  	    pline("%s transforms a clump of sticks into snakes!",
572.  		Monnam(mtmp));
573.  	else if (Invisible && !perceives(mtmp->data) &&
574.  				(mtmp->mux != u.ux || mtmp->muy != u.uy))
575.  	    pline("%s summons insects around a spot near you!",
576.  		Monnam(mtmp));
577.  	else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
578.  	    pline("%s summons insects around your displaced image!",
579.  		Monnam(mtmp));
580.  	else
581.  	    pline("%s summons insects!", Monnam(mtmp));
582.  	dmg = 0;
583.  	break;
584.        }
585.      case CLC_BLIND_YOU:
586.  	/* note: resists_blnd() doesn't apply here */
587.  	if (!Blinded) {
588.  	    int num_eyes = eyecount(youmonst.data);
589.  	    pline("Scales cover your %s!",
590.  		  (num_eyes == 1) ?
591.  		  body_part(EYE) : makeplural(body_part(EYE)));
592.  	    make_blinded(Half_spell_damage ? 100L : 200L, FALSE);
593.  	    if (!Blind) Your(vision_clears);
594.  	    dmg = 0;
595.  	} else
596.  	    impossible("no reason for monster to cast blindness spell?");
597.  	break;
598.      case CLC_PARALYZE:
599.  	if (Antimagic || Free_action) {
600.  	    shieldeff(u.ux, u.uy);
601.  	    if (multi >= 0)
602.  		You("stiffen briefly.");
603.  	    nomul(-1);
604.  	} else {
605.  	    if (multi >= 0)
606.  		You("are frozen in place!");
607.  	    dmg = 4 + (int)mtmp->m_lev;
608.  	    if (Half_spell_damage) dmg = (dmg + 1) / 2;
609.  	    nomul(-dmg);
610.  	}
611.  	dmg = 0;
612.  	break;
613.      case CLC_CONFUSE_YOU:
614.  	if (Antimagic) {
615.  	    shieldeff(u.ux, u.uy);
616.  	    You_feel("momentarily dizzy.");
617.  	} else {
618.  	    boolean oldprop = !!Confusion;
619.  
620.  	    dmg = (int)mtmp->m_lev;
621.  	    if (Half_spell_damage) dmg = (dmg + 1) / 2;
622.  	    make_confused(HConfusion + dmg, TRUE);
623.  	    if (Hallucination)
624.  		You_feel("%s!", oldprop ? "trippier" : "trippy");
625.  	    else
626.  		You_feel("%sconfused!", oldprop ? "more " : "");
627.  	}
628.  	dmg = 0;
629.  	break;
630.      case CLC_CURE_SELF:
631.  	if (mtmp->mhp < mtmp->mhpmax) {
632.  	    if (canseemon(mtmp))
633.  		pline("%s looks better.", Monnam(mtmp));
634.  	    /* note: player healing does 6d4; this used to do 1d8 */
635.  	    if ((mtmp->mhp += d(3,6)) > mtmp->mhpmax)
636.  		mtmp->mhp = mtmp->mhpmax;
637.  	    dmg = 0;
638.  	}
639.  	break;
640.      case CLC_OPEN_WOUNDS:
641.  	if (Antimagic) {
642.  	    shieldeff(u.ux, u.uy);
643.  	    dmg = (dmg + 1) / 2;
644.  	}
645.  	if (dmg <= 5)
646.  	    Your("skin itches badly for a moment.");
647.  	else if (dmg <= 10)
648.  	    pline("Wounds appear on your body!");
649.  	else if (dmg <= 20)
650.  	    pline("Severe wounds appear on your body!");
651.  	else
652.  	    Your("body is covered with painful wounds!");
653.  	break;
654.      default:
655.  	impossible("mcastu: invalid clerical spell (%d)", spellnum);
656.  	dmg = 0;
657.  	break;
658.      }
659.  
660.      if (dmg) mdamageu(mtmp, dmg);
661.  }
662.  

is_undirected_spell Edit

663.  STATIC_DCL
664.  boolean
665.  is_undirected_spell(adtyp, spellnum)
666.  unsigned int adtyp;
667.  int spellnum;
668.  {
669.      if (adtyp == AD_SPEL) {
670.  	switch (spellnum) {
671.  	case MGC_CLONE_WIZ:
672.  	case MGC_SUMMON_MONS:
673.  	case MGC_AGGRAVATION:
674.  	case MGC_DISAPPEAR:
675.  	case MGC_HASTE_SELF:
676.  	case MGC_CURE_SELF:
677.  	    return TRUE;
678.  	default:
679.  	    break;
680.  	}
681.      } else if (adtyp == AD_CLRC) {
682.  	switch (spellnum) {
683.  	case CLC_INSECTS:
684.  	case CLC_CURE_SELF:
685.  	    return TRUE;
686.  	default:
687.  	    break;
688.  	}
689.      }
690.      return FALSE;
691.  }
692.  

spell_would_be_useless Edit

693.  /* Some spells are useless under some circumstances. */
694.  STATIC_DCL
695.  boolean
696.  spell_would_be_useless(mtmp, adtyp, spellnum)
697.  struct monst *mtmp;
698.  unsigned int adtyp;
699.  int spellnum;
700.  {
701.      /* Some spells don't require the player to really be there and can be cast
702.       * by the monster when you're invisible, yet still shouldn't be cast when
703.       * the monster doesn't even think you're there.
704.       * This check isn't quite right because it always uses your real position.
705.       * We really want something like "if the monster could see mux, muy".
706.       */
707.      boolean mcouldseeu = couldsee(mtmp->mx, mtmp->my);
708.  
709.      if (adtyp == AD_SPEL) {
710.  	/* aggravate monsters, etc. won't be cast by peaceful monsters */
711.  	if (mtmp->mpeaceful && (spellnum == MGC_AGGRAVATION ||
712.  		spellnum == MGC_SUMMON_MONS || spellnum == MGC_CLONE_WIZ))
713.  	    return TRUE;
714.  	/* haste self when already fast */
715.  	if (mtmp->permspeed == MFAST && spellnum == MGC_HASTE_SELF)
716.  	    return TRUE;
717.  	/* invisibility when already invisible */
718.  	if ((mtmp->minvis || mtmp->invis_blkd) && spellnum == MGC_DISAPPEAR)
719.  	    return TRUE;
720.  	/* peaceful monster won't cast invisibility if you can't see invisible,
721.  	   same as when monsters drink potions of invisibility.  This doesn't
722.  	   really make a lot of sense, but lets the player avoid hitting
723.  	   peaceful monsters by mistake */
724.  	if (mtmp->mpeaceful && !See_invisible && spellnum == MGC_DISAPPEAR)
725.  	    return TRUE;
726.  	/* healing when already healed */
727.  	if (mtmp->mhp == mtmp->mhpmax && spellnum == MGC_CURE_SELF)
728.  	    return TRUE;
729.  	/* don't summon monsters if it doesn't think you're around */
730.  	if (!mcouldseeu && (spellnum == MGC_SUMMON_MONS ||
731.  		(!mtmp->iswiz && spellnum == MGC_CLONE_WIZ)))
732.  	    return TRUE;
733.  	if ((!mtmp->iswiz || flags.no_of_wizards > 1)
734.  						&& spellnum == MGC_CLONE_WIZ)
735.  	    return TRUE;
736.      } else if (adtyp == AD_CLRC) {
737.  	/* summon insects/sticks to snakes won't be cast by peaceful monsters */
738.  	if (mtmp->mpeaceful && spellnum == CLC_INSECTS)
739.  	    return TRUE;
740.  	/* healing when already healed */
741.  	if (mtmp->mhp == mtmp->mhpmax && spellnum == CLC_CURE_SELF)
742.  	    return TRUE;
743.  	/* don't summon insects if it doesn't think you're around */
744.  	if (!mcouldseeu && spellnum == CLC_INSECTS)
745.  	    return TRUE;
746.  	/* blindness spell on blinded player */
747.  	if (Blinded && spellnum == CLC_BLIND_YOU)
748.  	    return TRUE;
749.      }
750.      return FALSE;
751.  }
752.  
753.  #endif /* OVLB */

buzzmu Edit

754.  #ifdef OVL0
755.  
756.  /* convert 1..10 to 0..9; add 10 for second group (spell casting) */
757.  #define ad_to_typ(k) (10 + (int)k - 1)
758.  
759.  int
760.  buzzmu(mtmp, mattk)		/* monster uses spell (ranged) */
761.  	register struct monst *mtmp;
762.  	register struct attack  *mattk;
763.  {
764.  	/* don't print constant stream of curse messages for 'normal'
765.  	   spellcasting monsters at range */
766.  	if (mattk->adtyp > AD_SPC2)
767.  	    return(0);
768.  
769.  	if (mtmp->mcan) {
770.  	    cursetxt(mtmp, FALSE);
771.  	    return(0);
772.  	}
773.  	if(lined_up(mtmp) && rn2(3)) {
774.  	    nomul(0);
775.  	    if(mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */
776.  		if(canseemon(mtmp))
777.  		    pline("%s zaps you with a %s!", Monnam(mtmp),
778.  			  flash_types[ad_to_typ(mattk->adtyp)]);
779.  		buzz(-ad_to_typ(mattk->adtyp), (int)mattk->damn,
780.  		     mtmp->mx, mtmp->my, sgn(tbx), sgn(tby));
781.  	    } else impossible("Monster spell %d cast", mattk->adtyp-1);
782.  	}
783.  	return(1);
784.  }
785.  
786.  #endif /* OVL0 */
787.  
788.  /*mcastu.c*/

Around Wikia's network

Random Wiki