Wikihack
Register
Advertisement

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

Warning! This is the source code from an old release. For the latest release, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)mcastu.c	3.3	97/11/02	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    
7.    STATIC_DCL void FDECL(cursetxt,(struct monst *));
8.    
9.    #ifdef OVL0
10.   
11.   extern const char *flash_types[];	/* from zap.c */
12.   
13.   /* feedback when frustrated monster couldn't cast a spell */
14.   STATIC_OVL
15.   void
16.   cursetxt(mtmp)
17.   struct monst *mtmp;
18.   {
19.   	if (canseemon(mtmp)) {
20.   	    const char *point_msg;  /* spellcasting monsters are impolite */
21.   
22.   	    if ((Invis && !perceives(mtmp->data) &&
23.   			(mtmp->mux != u.ux || mtmp->muy != u.uy)) ||
24.   		    (youmonst.m_ap_type == M_AP_OBJECT &&
25.   			youmonst.mappearance == STRANGE_OBJECT) ||
26.   		    u.uundetected)
27.   		point_msg = "and curses in your general direction";
28.   	    else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
29.   		point_msg = "and curses at your displaced image";
30.   	    else
31.   		point_msg = "at you, then curses";
32.   
33.   	    pline("%s points %s.", Monnam(mtmp), point_msg);
34.   	} else if ((!(moves % 4) || !rn2(4))) {
35.   	    if (flags.soundok) Norep("You hear a mumbled curse.");
36.   	}
37.   }
38.   
39.   #endif /* OVL0 */
40.   #ifdef OVLB
41.   
42.   int
43.   castmu(mtmp, mattk)	/* monster casts spell at you */
44.   	register struct monst *mtmp;
45.   	register struct attack *mattk;
46.   {
47.   	int	dmg, ml = mtmp->m_lev;
48.   
49.   	if(mtmp->mcan || mtmp->mspec_used || !ml) {  /* could not attack */
50.   	    cursetxt(mtmp);
51.   	    return(0);
52.   	} else {
53.   	    nomul(0);
54.   	    if(rn2(ml*10) < (mtmp->mconf ? 100 : 20)) {	/* fumbled attack */
55.   		if (canseemon(mtmp) && flags.soundok)
56.   		    pline_The("air crackles around %s.", mon_nam(mtmp));
57.   		return(0);
58.   	    }
59.   	}
60.   /*
61.    *	As these are spells, the damage is related to the level
62.    *	of the monster casting the spell.
63.    */
64.   	if (mattk->damd)
65.   		dmg = d((int)((ml/3) + mattk->damn), (int)mattk->damd);
66.   	else dmg = d((int)((ml/3) + 1), 6);
67.   	if (Half_spell_damage) dmg = (dmg+1) / 2;
68.   
69.   	switch(mattk->adtyp)   {
70.   
71.   	    case AD_FIRE:
72.   		pline("You're enveloped in flames.");
73.   		if(Fire_resistance) {
74.   			shieldeff(u.ux, u.uy);
75.   			pline("But you resist the effects.");
76.   			dmg = 0;
77.   		}
78.   		burn_away_slime();
79.   		break;
80.   	    case AD_COLD:
81.   		pline("You're covered in frost.");
82.   		if(Cold_resistance) {
83.   			shieldeff(u.ux, u.uy);
84.   			pline("But you resist the effects.");
85.   			dmg = 0;
86.   		}
87.   		break;
88.   	    case AD_MAGM:
89.   		You("are hit by a shower of missiles!");
90.   		if(Antimagic) {
91.   			shieldeff(u.ux, u.uy);
92.   			pline_The("missiles bounce off!");
93.   			dmg = 0;
94.   		} else dmg = d((int)mtmp->m_lev/2 + 1,6);
95.   		break;
96.   	    case AD_SPEL:	/* random spell */
97.   
98.   		mtmp->mspec_used = 10 - mtmp->m_lev;
99.   		if (mtmp->mspec_used < 2) mtmp->mspec_used = 2;
100.  		switch(rn2((int)mtmp->m_lev)) {
101.  		    case 22:
102.  		    case 21:
103.  		    case 20:
104.  			pline("Oh no, %s's using the touch of death!",
105.  			      humanoid(mtmp->data)
106.  				  ? (mtmp->female ? "she" : "he")
107.  				  : "it"
108.  			     );
109.  			if (nonliving(youmonst.data) || is_demon(youmonst.data))
110.  			    You("seem no deader than before.");
111.  			else if (!Antimagic && rn2(ml) > 12) {
112.  
113.  			    if(Hallucination)
114.  				You("have an out of body experience.");
115.  			    else  {
116.  				killer_format = KILLED_BY_AN;
117.  				killer = "touch of death";
118.  				done(DIED);
119.  			    }
120.  			} else {
121.  				if(Antimagic) shieldeff(u.ux, u.uy);
122.  				pline("Lucky for you, it didn't work!");
123.  			}
124.  			dmg = 0;
125.  			break;
126.  		    case 19:
127.  		    case 18:
128.  			if(mtmp->iswiz && flags.no_of_wizards == 1) {
129.  				pline("Double Trouble...");
130.  				clonewiz();
131.  				dmg = 0;
132.  				break;
133.  			} /* else fall into the next case */
134.  		    case 17:
135.  		    case 16:
136.  		    case 15:
137.  			if(mtmp->iswiz)
138.  			    verbalize("Destroy the thief, my pets!");
139.  			nasty(mtmp);	/* summon something nasty */
140.  			/* fall into the next case */
141.  		    case 14:		/* aggravate all monsters */
142.  		    case 13:
143.  			aggravate();
144.  			dmg = 0;
145.  			break;
146.  		    case 12:		/* curse random items */
147.  		    case 11:
148.  		    case 10:
149.  			rndcurse();
150.  			dmg = 0;
151.  			break;
152.  		    case 9:
153.  		    case 8:		/* destroy armor */
154.  			if (Antimagic) {
155.  				shieldeff(u.ux, u.uy);
156.  				pline("A field of force surrounds you!");
157.  			} else if(!destroy_arm(some_armor(&youmonst)))
158.  				Your("skin itches.");
159.  			dmg = 0;
160.  			break;
161.  		    case 7:
162.  		    case 6:		/* drain strength */
163.  			if(Antimagic) {
164.  			    shieldeff(u.ux, u.uy);
165.  			    You_feel("momentarily weakened.");
166.  			} else {
167.  			    You("suddenly feel weaker!");
168.  			    dmg = ml - 6;
169.  			    if(Half_spell_damage) dmg = (dmg+1) / 2;
170.  			    losestr(rnd(dmg));
171.  			    if(u.uhp < 1)
172.  				done_in_by(mtmp);
173.  			}
174.  			dmg = 0;
175.  			break;
176.  		    case 5:		/* make invisible if not */
177.  		    case 4:
178.  			if (!mtmp->minvis && !mtmp->invis_blkd) {
179.  			    if(canseemon(mtmp) && !See_invisible)
180.  				pline("%s suddenly disappears!", Monnam(mtmp));
181.  			    mon_set_minvis(mtmp);
182.  			    dmg = 0;
183.  			    break;
184.  			} /* else fall into the next case */
185.  		    case 3:		/* stun */
186.  			if (Antimagic || Free_action) {
187.  			    shieldeff(u.ux, u.uy);
188.  			    if(!Stunned)
189.  				You_feel("momentarily disoriented.");
190.  			    make_stunned(1L, FALSE);
191.  			} else {
192.  			    if (Stunned)
193.  				You("struggle to keep your balance.");
194.  			    else
195.  				You("reel...");
196.  			    dmg = d(ACURR(A_DEX) < 12 ? 6 : 4, 4);
197.  			    if(Half_spell_damage) dmg = (dmg+1) / 2;
198.  			    make_stunned(HStun + dmg, FALSE);
199.  			}
200.  			dmg = 0;
201.  			break;
202.  		    case 2:		/* haste self */
203.  			mon_adjust_speed(mtmp, 1);
204.  			dmg = 0;
205.  			break;
206.  		    case 1:		/* cure self */
207.  			if(mtmp->mhp < mtmp->mhpmax) {
208.  			    if((mtmp->mhp += rnd(8)) > mtmp->mhpmax)
209.  				mtmp->mhp = mtmp->mhpmax;
210.  			    dmg = 0;
211.  			    break;
212.  			} /* else fall through to default case */
213.  		    default:		/* psi bolt */
214.  			if(Antimagic) {
215.  			    shieldeff(u.ux, u.uy);
216.  			    You("get a slight %sache.",body_part(HEAD));
217.  			    dmg = 1;
218.  			} else {
219.  			    if (dmg <= 10)
220.  				Your("brain is on fire!");
221.  			    else Your("%s suddenly aches!", body_part(HEAD));
222.  			}
223.  			break;
224.  		}
225.  		break;
226.  
227.  	    case AD_CLRC:	/* clerical spell */
228.  		mtmp->mspec_used = 10 - mtmp->m_lev;
229.  		if (mtmp->mspec_used < 2) mtmp->mspec_used = 2;
230.  		switch(rn2((int)mtmp->m_lev)) {
231.  		    /* Other ideas: lightning bolts, towers of flame,
232.  				    gush of water  -3. */
233.  
234.  		    default:		/* confuse */
235.  			if(Antimagic) {
236.  			    shieldeff(u.ux, u.uy);
237.  			    You_feel("momentarily dizzy.");
238.  			} else {
239.  			    dmg = (int)mtmp->m_lev;
240.  			    if(Half_spell_damage) dmg = (dmg+1) / 2;
241.  			    make_confused(HConfusion + dmg, TRUE);
242.  			}
243.  			dmg = 0;
244.  			break;
245.  		    case 12:		/* curse random items */
246.  		    case 11:
247.  		    case 10:
248.  			rndcurse();
249.  			dmg = 0;
250.  			break;
251.  		    case 9:
252.  		    case 8:		/* insects */
253.  			/* Try for insects, and if there are none
254.  			   left, go for (sticks to) snakes.  -3. */
255.  			{
256.  			int i;
257.  			struct permonst *pm = mkclass(S_ANT,0);
258.  			struct monst *mtmp2;
259.  			char let = (pm ? S_ANT : S_SNAKE);
260.  
261.  			for (i = 0; i <= (int) mtmp->m_lev; i++)
262.  			   if ((pm = mkclass(let,0)) &&
263.  			(mtmp2 = makemon(pm, u.ux, u.uy, NO_MM_FLAGS))) {
264.  				mtmp2->msleeping = mtmp2->mpeaceful =
265.  					mtmp2->mtame = 0;
266.  				set_malign(mtmp2);
267.  			    }
268.  			}
269.  			dmg = 0;
270.  			break;
271.  		    case 6:
272.  		    case 7:		/* blindness */
273.  			/* note: resists_blnd() doesn't apply here */
274.  			if (!Blinded) {
275.  			    pline("Scales cover your eyes!");
276.  			    make_blinded(Half_spell_damage ? 100L:200L, FALSE);
277.  			    dmg = 0;
278.  			    break;
279.  			}
280.  		    case 4:
281.  		    case 5:		/* wound */
282.  			if(Antimagic) {
283.  			    shieldeff(u.ux, u.uy);
284.  			    Your("skin itches badly for a moment.");
285.  			    dmg = 0;
286.  			} else {
287.  			    pline("Wounds appear on your body!");
288.  			    dmg = d(2,8) + 1;
289.  			    if (Half_spell_damage) dmg = (dmg+1) / 2;
290.  			}
291.  			break;
292.  		    case 3:		/* hold */
293.  			if (Antimagic || Free_action) {
294.  			    shieldeff(u.ux, u.uy);
295.  			    if(multi >= 0)
296.  				You("stiffen briefly.");
297.  			    nomul(-1);
298.  			} else {
299.  			    if (multi >= 0)
300.  				You("are frozen in place!");
301.  			    dmg = 4 + (int)mtmp->m_lev;
302.  			    if (Half_spell_damage) dmg = (dmg+1) / 2;
303.  			    nomul(-dmg);
304.  			}
305.  			dmg = 0;
306.  			break;
307.  		    case 2:
308.  		    case 1:		/* cure self */
309.  			if(mtmp->mhp < mtmp->mhpmax) {
310.  			    if((mtmp->mhp += rnd(8)) > mtmp->mhpmax)
311.  				mtmp->mhp = mtmp->mhpmax;
312.  			    dmg = 0;
313.  			    break;
314.  			} /* else fall through to default case */
315.  		}
316.  	}
317.  	if(dmg) mdamageu(mtmp, dmg);
318.  	return(1);
319.  }
320.  
321.  #endif /* OVLB */
322.  #ifdef OVL0
323.  
324.  /* convert 1..10 to 0..9; add 10 for second group (spell casting) */
325.  #define ad_to_typ(k) (10 + (int)k - 1)
326.  
327.  int
328.  buzzmu(mtmp, mattk)		/* monster uses spell (ranged) */
329.  	register struct monst *mtmp;
330.  	register struct attack  *mattk;
331.  {
332.  	if(mtmp->mcan || mattk->adtyp > AD_SPC2) {
333.  	    cursetxt(mtmp);
334.  	    return(0);
335.  	}
336.  	if(lined_up(mtmp) && rn2(3)) {
337.  	    nomul(0);
338.  	    if(mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */
339.  		if(canseemon(mtmp))
340.  		    pline("%s zaps you with a %s!", Monnam(mtmp),
341.  			  flash_types[ad_to_typ(mattk->adtyp)]);
342.  		buzz(-ad_to_typ(mattk->adtyp), (int)mattk->damn,
343.  		     mtmp->mx, mtmp->my, sgn(tbx), sgn(tby));
344.  	    } else impossible("Monster spell %d cast", mattk->adtyp-1);
345.  	}
346.  	return(1);
347.  }
348.  
349.  #endif /* OVL0 */
350.  
351.  /*mcastu.c*/
Advertisement