PropertyValue
rdfs:label
  • Source:NetHack 3.4.0/mcastu.c
rdfs:comment
  • Below is the full text to mcastu.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/mcastu.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/property/wikiPageUsesTemplate
abstract
  • Below is the full text to mcastu.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.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.4 2002/02/07 */ 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. /* 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. 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 *flash_types[]; /* from zap.c */ 44. 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 */ 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; /* also aggravates */ 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. 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. 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) { 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. 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: /* also aggravates */ 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. 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. 546. success = pm ? TRUE : FALSE; 547. for (i = 0; i <= (int) mtmp->m_lev; i++) { 548. if (!enexto(&bypos, mtmp->mux, mtmp->muy, mtmp->data)) 549. break; 550. if ((pm = mkclass(let,0)) != 0 && 551. (mtmp2 = makemon(pm, bypos.x, bypos.y, NO_MM_FLAGS)) != 0) { 552. success = TRUE; 553. mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0; 554. set_malign(mtmp2); 555. } 556. } 557. /* Not quite right: 558. * -- message doesn't always make sense for unseen caster (particularly 559. * the first message) 560. * -- message assumes plural monsters summoned (non-plural should be 561. * very rare, unlike in nasty()) 562. * -- message assumes plural monsters seen 563. */ 564. if (!success) 565. pline("%s casts at a clump of sticks, but nothing happens.", 566. Monnam(mtmp)); 567. else if (let == S_SNAKE) 568. pline("%s transforms a clump of sticks into snakes!", 569. Monnam(mtmp)); 570. else if (Invisible && !perceives(mtmp->data) && 571. (mtmp->mux != u.ux || mtmp->muy != u.uy)) 572. pline("%s summons insects around a spot near you!", 573. Monnam(mtmp)); 574. else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) 575. pline("%s summons insects around your displaced image!", 576. Monnam(mtmp)); 577. else 578. pline("%s summons insects!", Monnam(mtmp)); 579. dmg = 0; 580. break; 581. } 582. case CLC_BLIND_YOU: 583. /* note: resists_blnd() doesn't apply here */ 584. if (!Blinded) { 585. int num_eyes = eyecount(youmonst.data); 586. pline("Scales cover your %s!", 587. (num_eyes == 1) ? 588. body_part(EYE) : makeplural(body_part(EYE))); 589. make_blinded(Half_spell_damage ? 100L : 200L, FALSE); 590. if (!Blind) Your(vision_clears); 591. dmg = 0; 592. } else 593. impossible("no reason for monster to cast blindness spell?"); 594. break; 595. case CLC_PARALYZE: 596. if (Antimagic || Free_action) { 597. shieldeff(u.ux, u.uy); 598. if (multi >= 0) 599. You("stiffen briefly."); 600. nomul(-1); 601. } else { 602. if (multi >= 0) 603. You("are frozen in place!"); 604. dmg = 4 + (int)mtmp->m_lev; 605. if (Half_spell_damage) dmg = (dmg + 1) / 2; 606. nomul(-dmg); 607. } 608. dmg = 0; 609. break; 610. case CLC_CONFUSE_YOU: 611. if (Antimagic) { 612. shieldeff(u.ux, u.uy); 613. You_feel("momentarily dizzy."); 614. } else { 615. boolean oldprop = !!Confusion; 616. 617. dmg = (int)mtmp->m_lev; 618. if (Half_spell_damage) dmg = (dmg + 1) / 2; 619. make_confused(HConfusion + dmg, TRUE); 620. if (Hallucination) 621. You_feel("%s!", oldprop ? "trippier" : "trippy"); 622. else 623. You_feel("%sconfused!", oldprop ? "more " : ""); 624. } 625. dmg = 0; 626. break; 627. case CLC_CURE_SELF: 628. if (mtmp->mhp < mtmp->mhpmax) { 629. if (canseemon(mtmp)) 630. pline("%s looks better.", Monnam(mtmp)); 631. /* note: player healing does 6d4; this used to do 1d8 */ 632. if ((mtmp->mhp += d(3,6)) > mtmp->mhpmax) 633. mtmp->mhp = mtmp->mhpmax; 634. dmg = 0; 635. } 636. break; 637. case CLC_OPEN_WOUNDS: 638. if (Antimagic) { 639. shieldeff(u.ux, u.uy); 640. dmg = (dmg + 1) / 2; 641. } 642. if (dmg <= 5) 643. Your("skin itches badly for a moment."); 644. else if (dmg <= 10) 645. pline("Wounds appear on your body!"); 646. else if (dmg <= 20) 647. pline("Severe wounds appear on your body!"); 648. else 649. Your("body is covered with painful wounds!"); 650. break; 651. default: 652. impossible("mcastu: invalid clerical spell (%d)", spellnum); 653. dmg = 0; 654. break; 655. } 656. 657. if (dmg) mdamageu(mtmp, dmg); 658. } 659. 660. STATIC_DCL 661. boolean 662. is_undirected_spell(adtyp, spellnum) 663. unsigned int adtyp; 664. int spellnum; 665. { 666. if (adtyp == AD_SPEL) { 667. switch (spellnum) { 668. case MGC_CLONE_WIZ: 669. case MGC_SUMMON_MONS: 670. case MGC_AGGRAVATION: 671. case MGC_DISAPPEAR: 672. case MGC_HASTE_SELF: 673. case MGC_CURE_SELF: 674. return TRUE; 675. default: 676. break; 677. } 678. } else if (adtyp == AD_CLRC) { 679. switch (spellnum) { 680. case CLC_INSECTS: 681. case CLC_CURE_SELF: 682. return TRUE; 683. default: 684. break; 685. } 686. } 687. return FALSE; 688. } 689. 690. /* Some spells are useless under some circumstances. */ 691. STATIC_DCL 692. boolean 693. spell_would_be_useless(mtmp, adtyp, spellnum) 694. struct monst *mtmp; 695. unsigned int adtyp; 696. int spellnum; 697. { 698. /* Some spells don't require the player to really be there and can be cast 699. * by the monster when you're invisible, yet still shouldn't be cast when 700. * the monster doesn't even think you're there. 701. * This check isn't quite right because it always uses your real position. 702. * We really want something like "if the monster could see mux, muy". 703. */ 704. boolean mcouldseeu = couldsee(mtmp->mx, mtmp->my); 705. 706. if (adtyp == AD_SPEL) { 707. /* aggravate monsters, etc. won't be cast by peaceful monsters */ 708. if (mtmp->mpeaceful && (spellnum == MGC_AGGRAVATION || 709. spellnum == MGC_SUMMON_MONS || spellnum == MGC_CLONE_WIZ)) 710. return TRUE; 711. /* haste self when already fast */ 712. if (mtmp->permspeed == MFAST && spellnum == MGC_HASTE_SELF) 713. return TRUE; 714. /* invisibility when already invisible */ 715. if ((mtmp->minvis || mtmp->invis_blkd) && spellnum == MGC_DISAPPEAR) 716. return TRUE; 717. /* peaceful monster won't cast invisibility if you can't see invisible, 718. same as when monsters drink potions of invisibility. This doesn't 719. really make a lot of sense, but lets the player avoid hitting 720. peaceful monsters by mistake */ 721. if (mtmp->mpeaceful && !See_invisible && spellnum == MGC_DISAPPEAR) 722. return TRUE; 723. /* healing when already healed */ 724. if (mtmp->mhp == mtmp->mhpmax && spellnum == MGC_CURE_SELF) 725. return TRUE; 726. /* don't summon monsters if it doesn't think you're around */ 727. if (!mcouldseeu && (spellnum == MGC_SUMMON_MONS || 728. (!mtmp->iswiz && spellnum == MGC_CLONE_WIZ))) 729. return TRUE; 730. if ((!mtmp->iswiz || flags.no_of_wizards > 1) 731. && spellnum == MGC_CLONE_WIZ) 732. return TRUE; 733. } else if (adtyp == AD_CLRC) { 734. /* summon insects/sticks to snakes won't be cast by peaceful monsters */ 735. if (mtmp->mpeaceful && spellnum == CLC_INSECTS) 736. return TRUE; 737. /* healing when already healed */ 738. if (mtmp->mhp == mtmp->mhpmax && spellnum == CLC_CURE_SELF) 739. return TRUE; 740. /* don't summon insects if it doesn't think you're around */ 741. if (!mcouldseeu && spellnum == CLC_INSECTS) 742. return TRUE; 743. /* blindness spell on blinded player */ 744. if (Blinded && spellnum == CLC_BLIND_YOU) 745. return TRUE; 746. } 747. return FALSE; 748. } 749. 750. #endif /* OVLB */ 751. #ifdef OVL0 752. 753. /* convert 1..10 to 0..9; add 10 for second group (spell casting) */ 754. #define ad_to_typ(k) (10 + (int)k - 1) 755. 756. int 757. buzzmu(mtmp, mattk) /* monster uses spell (ranged) */ 758. register struct monst *mtmp; 759. register struct attack *mattk; 760. { 761. /* don't print constant stream of curse messages for 'normal' 762. spellcasting monsters at range */ 763. if (mattk->adtyp > AD_SPC2) 764. return(0); 765. 766. if (mtmp->mcan) { 767. cursetxt(mtmp, FALSE); 768. return(0); 769. } 770. if(lined_up(mtmp) && rn2(3)) { 771. nomul(0); 772. if(mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */ 773. if(canseemon(mtmp)) 774. pline("%s zaps you with a %s!", Monnam(mtmp), 775. flash_types[ad_to_typ(mattk->adtyp)]); 776. buzz(-ad_to_typ(mattk->adtyp), (int)mattk->damn, 777. mtmp->mx, mtmp->my, sgn(tbx), sgn(tby)); 778. } else impossible("Monster spell %d cast", mattk->adtyp-1); 779. } 780. return(1); 781. } 782. 783. #endif /* OVL0 */ 784. 785. /*mcastu.c*/