Source:NetHack 3.3.0/mcastu.c

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

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*/