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