Below is the full text to mcastu.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/mcastu.c#line123]], for example.
The latest source code for vanilla NetHack is at Source code.
The NetHack General Public License applies to screenshots, source code and other content from NetHack. |
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. 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. #define MGC_CREATE_POOL 12 21. #define MGC_CALL_UNDEAD 13 22. 23. /* monster cleric spells */ 24. #define CLC_OPEN_WOUNDS 0 25. #define CLC_CURE_SELF 1 26. #define CLC_CONFUSE_YOU 2 27. #define CLC_PARALYZE 3 28. #define CLC_BLIND_YOU 4 29. #define CLC_INSECTS 5 30. #define CLC_CURSE_ITEMS 6 31. #define CLC_LIGHTNING 7 32. #define CLC_FIRE_PILLAR 8 33. #define CLC_GEYSER 9 34. 35. STATIC_DCL void FDECL(cursetxt,(struct monst *,BOOLEAN_P)); 36. STATIC_DCL int FDECL(choose_magic_spell, (int)); 37. STATIC_DCL int FDECL(choose_clerical_spell, (int)); 38. STATIC_DCL void FDECL(cast_wizard_spell,(struct monst *, int,int)); 39. STATIC_DCL void FDECL(cast_cleric_spell,(struct monst *, int,int)); 40. STATIC_DCL boolean FDECL(is_undirected_spell,(unsigned int,int)); 41. STATIC_DCL boolean FDECL(spell_would_be_useless,(struct monst *,unsigned int,int)); 42. 43. #ifdef OVL0 44. 45. extern const char * const flash_types[]; /* from zap.c */ 46. 47. /* feedback when frustrated monster couldn't cast a spell */ 48. STATIC_OVL 49. void 50. cursetxt(mtmp, undirected) 51. struct monst *mtmp; 52. boolean undirected; 53. { 54. if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)) { 55. const char *point_msg; /* spellcasting monsters are impolite */ 56. 57. if (undirected) 58. point_msg = "all around, then curses"; 59. else if ((Invis && !perceives(mtmp->data) && 60. (mtmp->mux != u.ux || mtmp->muy != u.uy)) || 61. (youmonst.m_ap_type == M_AP_OBJECT && 62. youmonst.mappearance == STRANGE_OBJECT) || 63. u.uundetected) 64. point_msg = "and curses in your general direction"; 65. else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) 66. point_msg = "and curses at your displaced image"; 67. else 68. point_msg = "at you, then curses"; 69. 70. pline("%s points %s.", Monnam(mtmp), point_msg); 71. } else if ((!(moves % 4) || !rn2(4))) { 72. if (flags.soundok) Norep("You hear a mumbled curse."); 73. } 74. } 75. 76. #endif /* OVL0 */ 77. #ifdef OVLB 78. 79. /* convert a level based random selection into a specific mage spell; 80. inappropriate choices will be screened out by spell_would_be_useless() */ 81. STATIC_OVL int 82. choose_magic_spell(spellval) 83. int spellval; 84. { 85. switch (spellval) { 86. case 22: 87. case 21: 88. case 20: 89. return MGC_DEATH_TOUCH; 90. case 19: 91. case 18: 92. return MGC_CLONE_WIZ; 93. case 17: 94. case 16: 95. case 15: 96. return MGC_SUMMON_MONS; 97. case 14: 98. case 13: 99. return MGC_AGGRAVATION; 100. case 12: 101. return MGC_CREATE_POOL; 102. case 11: 103. case 10: 104. return MGC_CURSE_ITEMS; 105. case 9: 106. return MGC_CALL_UNDEAD; 107. case 8: 108. return MGC_DESTRY_ARMR; 109. case 7: 110. case 6: 111. return MGC_WEAKEN_YOU; 112. case 5: 113. case 4: 114. return MGC_DISAPPEAR; 115. case 3: 116. return MGC_STUN_YOU; 117. case 2: 118. return MGC_HASTE_SELF; 119. case 1: 120. return MGC_CURE_SELF; 121. case 0: 122. default: 123. return MGC_PSI_BOLT; 124. } 125. } 126. 127. /* convert a level based random selection into a specific cleric spell */ 128. STATIC_OVL int 129. choose_clerical_spell(spellnum) 130. int spellnum; 131. { 132. switch (spellnum) { 133. case 13: 134. return CLC_GEYSER; 135. case 12: 136. return CLC_FIRE_PILLAR; 137. case 11: 138. return CLC_LIGHTNING; 139. case 10: 140. case 9: 141. return CLC_CURSE_ITEMS; 142. case 8: 143. return CLC_INSECTS; 144. case 7: 145. case 6: 146. return CLC_BLIND_YOU; 147. case 5: 148. case 4: 149. return CLC_PARALYZE; 150. case 3: 151. case 2: 152. return CLC_CONFUSE_YOU; 153. case 1: 154. return CLC_CURE_SELF; 155. case 0: 156. default: 157. return CLC_OPEN_WOUNDS; 158. } 159. } 160. 161. /* return values: 162. * 1: successful spell 163. * 0: unsuccessful spell 164. */ 165. int 166. castmu(mtmp, mattk, thinks_it_foundyou, foundyou) 167. register struct monst *mtmp; 168. register struct attack *mattk; 169. boolean thinks_it_foundyou; 170. boolean foundyou; 171. { 172. int dmg, ml = mtmp->m_lev; 173. int ret; 174. int spellnum = 0; 175. int spellev, chance, difficulty, splcaster, learning; 176. 177. /* Three cases: 178. * -- monster is attacking you. Search for a useful spell. 179. * -- monster thinks it's attacking you. Search for a useful spell, 180. * without checking for undirected. If the spell found is directed, 181. * it fails with cursetxt() and loss of mspec_used. 182. * -- monster isn't trying to attack. Select a spell once. Don't keep 183. * searching; if that spell is not useful (or if it's directed), 184. * return and do something else. 185. * Since most spells are directed, this means that a monster that isn't 186. * attacking casts spells only a small portion of the time that an 187. * attacking monster does. 188. */ 189. if ((mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) && ml) { 190. int cnt = 40; 191. 192. do { 193. spellnum = rn2(ml); 194. /* Casting level is limited by available energy */ 195. spellev = spellnum / 7 + 1; 196. if (spellev > 10) spellev = 10; 197. if (spellev * 5 > mtmp->m_en) { 198. spellev = mtmp->m_en / 5; 199. spellnum = (spellev - 1) * 7 + 1; 200. } 201. if (mattk->adtyp == AD_SPEL) 202. spellnum = choose_magic_spell(spellnum); 203. else 204. spellnum = choose_clerical_spell(spellnum); 205. /* not trying to attack? don't allow directed spells */ 206. if (!thinks_it_foundyou) { 207. if (!is_undirected_spell(mattk->adtyp, spellnum) || 208. spell_would_be_useless(mtmp, mattk->adtyp, spellnum)) { 209. if (foundyou) 210. impossible("spellcasting monster found you and doesn't know it?"); 211. return 0; 212. } 213. break; 214. } 215. } while(--cnt > 0 && 216. spell_would_be_useless(mtmp, mattk->adtyp, spellnum)); 217. if (cnt == 0) return 0; 218. } else { 219. /* Casting level is limited by available energy */ 220. spellev = ml / 7 + 1; 221. if (spellev > 10) spellev = 10; 222. if (spellev * 5 > mtmp->m_en) { 223. spellev = mtmp->m_en / 5; 224. ml = (spellev - 1) * 7 + 1; 225. } 226. } 227. 228. /* monster unable to cast spells? */ 229. if (mtmp->mcan || mtmp->m_en < 5 || mtmp->mspec_used || !ml) { 230. cursetxt(mtmp, is_undirected_spell(mattk->adtyp, spellnum)); 231. return(0); 232. } 233. 234. if (mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) { 235. /* 236. * Spell use (especially MGC) is more common in Slash'EM. 237. * Still using mspec_used, just so monsters don't go bonkers. 238. */ 239. #if 0 240. mtmp->mspec_used = 10 - mtmp->m_lev; 241. if (mtmp->mspec_used < 2) mtmp->mspec_used = 2; 242. #endif 243. mtmp->mspec_used = rn2(15) - mtmp->m_lev; 244. if (mattk->adtyp == AD_SPEL) 245. mtmp->mspec_used = mtmp->mspec_used > 0 ? 2 : 0; 246. else if (mtmp->mspec_used < 2) mtmp->mspec_used = 2; 247. } 248. 249. /* monster can cast spells, but is casting a directed spell at the 250. wrong place? If so, give a message, and return. Do this *after* 251. penalizing mspec_used. */ 252. if (!foundyou && thinks_it_foundyou && 253. !is_undirected_spell(mattk->adtyp, spellnum)) { 254. pline("%s casts a spell at %s!", 255. canseemon(mtmp) ? Monnam(mtmp) : "Something", 256. levl[mtmp->mux][mtmp->muy].typ == WATER 257. ? "empty water" : "thin air"); 258. return(0); 259. } 260. 261. nomul(0); 262. 263. mtmp->m_en -= spellev * 5; /* Use up the energy now */ 264. 265. /* We should probably do similar checks to what is done for 266. * the player - armor, etc. 267. * Checks for armour and other intrinsic ability change splcaster 268. * Difficulty and experience affect chance 269. * Assume that monsters only cast spells that they know well 270. */ 271. splcaster = 15 - (mtmp->m_lev / 2); /* Base for a wizard is 5...*/ 272. 273. if (splcaster < 5) splcaster = 5; 274. if (splcaster > 20) splcaster = 20; 275. 276. chance = 11 * (mtmp->m_lev > 25 ? 18 : (12 + (mtmp->m_lev / 5))); 277. chance++ ; /* Minimum chance of 1 */ 278. 279. difficulty = (spellev - 1) * 4 - (mtmp->m_lev - 1); 280. /* law of diminishing returns sets in quickly for 281. * low-level spells. That is, higher levels quickly 282. * result in almost no gain 283. */ 284. learning = 15 * (-difficulty / spellev); 285. chance += learning > 20 ? 20 : learning; 286. 287. /* clamp the chance */ 288. if (chance < 0) chance = 0; 289. if (chance > 120) chance = 120; 290. 291. /* combine */ 292. chance = chance * (20-splcaster) / 15 - splcaster; 293. 294. /* Clamp to percentile */ 295. if (chance > 100) chance = 100; 296. if (chance < 0) chance = 0; 297. 298. #if 0 299. if(rn2(ml*10) < (mtmp->mconf ? 100 : 20)) { /* fumbled attack */ 300. #else 301. if (mtmp->mconf || rnd(100) > chance) { /* fumbled attack */ 302. #endif 303. if (canseemon(mtmp) && flags.soundok) 304. pline_The("air crackles around %s.", mon_nam(mtmp)); 305. return(0); 306. } 307. if (canspotmon(mtmp) || !is_undirected_spell(mattk->adtyp, spellnum)) { 308. pline("%s casts a spell%s!", 309. canspotmon(mtmp) ? Monnam(mtmp) : "Something", 310. is_undirected_spell(mattk->adtyp, spellnum) ? "" : 311. (Invisible && !perceives(mtmp->data) && 312. (mtmp->mux != u.ux || mtmp->muy != u.uy)) ? 313. " at a spot near you" : 314. (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) ? 315. " at your displaced image" : 316. " at you"); 317. } 318. 319. /* 320. * As these are spells, the damage is related to the level 321. * of the monster casting the spell. 322. */ 323. if (!foundyou) { 324. dmg = 0; 325. if (mattk->adtyp != AD_SPEL && mattk->adtyp != AD_CLRC) { 326. impossible( 327. "%s casting non-hand-to-hand version of hand-to-hand spell %d?", 328. Monnam(mtmp), mattk->adtyp); 329. return(0); 330. } 331. } else if (mattk->damd) 332. dmg = d((int)((ml/2) + mattk->damn), (int)mattk->damd); 333. else dmg = d((int)((ml/2) + 1), 6); 334. if (Half_spell_damage) dmg = (dmg+1) / 2; 335. 336. ret = 1; 337. 338. switch (mattk->adtyp) { 339. 340. case AD_FIRE: 341. pline("You're enveloped in flames."); 342. if(Fire_resistance) { 343. shieldeff(u.ux, u.uy); 344. pline("But you resist the effects."); 345. dmg = 0; 346. } 347. if (Slimed) { 348. pline("The slime is burned away!"); 349. Slimed =0; 350. } 351. burn_away_slime(); 352. break; 353. case AD_COLD: 354. pline("You're covered in frost."); 355. if(Cold_resistance) { 356. shieldeff(u.ux, u.uy); 357. pline("But you resist the effects."); 358. dmg = 0; 359. } 360. break; 361. case AD_MAGM: 362. You("are hit by a shower of missiles!"); 363. if(Antimagic) { 364. shieldeff(u.ux, u.uy); 365. pline_The("missiles bounce off!"); 366. dmg = 0; 367. } 368. break; 369. case AD_SPEL: /* wizard spell */ 370. case AD_CLRC: /* clerical spell */ 371. { 372. if (mattk->adtyp == AD_SPEL) 373. cast_wizard_spell(mtmp, dmg, spellnum); 374. else 375. cast_cleric_spell(mtmp, dmg, spellnum); 376. dmg = 0; /* done by the spell casting functions */ 377. break; 378. } 379. } 380. if(dmg) mdamageu(mtmp, dmg); 381. return(ret); 382. } 383. 384. /* monster wizard and cleric spellcasting functions */ 385. /* 386. If dmg is zero, then the monster is not casting at you. 387. If the monster is intentionally not casting at you, we have previously 388. called spell_would_be_useless() and spellnum should always be a valid 389. undirected spell. 390. If you modify either of these, be sure to change is_undirected_spell() 391. and spell_would_be_useless(). 392. */ 393. STATIC_OVL 394. void 395. cast_wizard_spell(mtmp, dmg, spellnum) 396. struct monst *mtmp; 397. int dmg; 398. int spellnum; 399. { 400. if (dmg == 0 && !is_undirected_spell(AD_SPEL, spellnum)) { 401. impossible("cast directed wizard spell (%d) with dmg=0?", spellnum); 402. return; 403. } 404. 405. switch (spellnum) { 406. case MGC_DEATH_TOUCH: 407. pline("Oh no, %s's using the touch of death!", mhe(mtmp)); 408. if (nonliving(youmonst.data) || is_demon(youmonst.data)) { 409. You("seem no deader than before."); 410. } else if (!Antimagic && rn2(mtmp->m_lev) > 12) { 411. if (Hallucination) { 412. You("have an out of body experience."); 413. } else { 414. killer_format = KILLED_BY_AN; 415. killer = "touch of death"; 416. done(DIED); 417. } 418. } else { 419. if (Antimagic) shieldeff(u.ux, u.uy); 420. pline("Lucky for you, it didn't work!"); 421. } 422. dmg = 0; 423. break; 424. case MGC_CREATE_POOL: 425. if (levl[u.ux][u.uy].typ == ROOM || levl[u.ux][u.uy].typ == CORR) { 426. pline("A pool appears beneath you!"); 427. levl[u.ux][u.uy].typ = POOL; 428. del_engr_at(u.ux, u.uy); 429. water_damage(level.objects[u.ux][u.uy], FALSE, TRUE); 430. spoteffects(FALSE); /* possibly drown, notice objects */ 431. } 432. else 433. impossible("bad pool creation?"); 434. dmg = 0; 435. break; 436. case MGC_CLONE_WIZ: 437. if (mtmp->iswiz && flags.no_of_wizards == 1) { 438. pline("Double Trouble..."); 439. clonewiz(); 440. dmg = 0; 441. } else 442. impossible("bad wizard cloning?"); 443. break; 444. case MGC_SUMMON_MONS: 445. { 446. int count; 447. 448. count = nasty(mtmp); /* summon something nasty */ 449. if (mtmp->iswiz) 450. verbalize("Destroy the thief, my pet%s!", plur(count)); 451. else { 452. const char *mappear = 453. (count == 1) ? "A monster appears" : "Monsters appear"; 454. 455. /* messages not quite right if plural monsters created but 456. only a single monster is seen */ 457. if (Invisible && !perceives(mtmp->data) && 458. (mtmp->mux != u.ux || mtmp->muy != u.uy)) 459. pline("%s around a spot near you!", mappear); 460. else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) 461. pline("%s around your displaced image!", mappear); 462. else 463. pline("%s from nowhere!", mappear); 464. } 465. dmg = 0; 466. break; 467. } 468. case MGC_CALL_UNDEAD: 469. { 470. coord mm; 471. mm.x = u.ux; 472. mm.y = u.uy; 473. pline("Undead creatures are called forth from the grave!"); 474. mkundead(&mm, FALSE, NO_MINVENT); 475. } 476. dmg = 0; 477. break; 478. case MGC_AGGRAVATION: 479. You_feel("that monsters are aware of your presence."); 480. aggravate(); 481. dmg = 0; 482. break; 483. case MGC_CURSE_ITEMS: 484. You_feel("as if you need some help."); 485. rndcurse(); 486. dmg = 0; 487. break; 488. case MGC_DESTRY_ARMR: 489. if (Antimagic) { 490. shieldeff(u.ux, u.uy); 491. pline("A field of force surrounds you!"); 492. } else if (!destroy_arm(some_armor(&youmonst))) { 493. Your("skin itches."); 494. } 495. dmg = 0; 496. break; 497. case MGC_WEAKEN_YOU: /* drain strength */ 498. if (Antimagic) { 499. shieldeff(u.ux, u.uy); 500. You_feel("momentarily weakened."); 501. } else { 502. You("suddenly feel weaker!"); 503. dmg = mtmp->m_lev - 6; 504. if (Half_spell_damage) dmg = (dmg + 1) / 2; 505. losestr(rnd(dmg)); 506. if (u.uhp < 1) 507. done_in_by(mtmp); 508. } 509. dmg = 0; 510. break; 511. case MGC_DISAPPEAR: /* makes self invisible */ 512. if (!mtmp->minvis && !mtmp->invis_blkd) { 513. if (canseemon(mtmp)) 514. pline("%s suddenly %s!", Monnam(mtmp), 515. !See_invisible ? "disappears" : "becomes transparent"); 516. mon_set_minvis(mtmp); 517. dmg = 0; 518. } else 519. impossible("no reason for monster to cast disappear spell?"); 520. break; 521. case MGC_STUN_YOU: 522. if (Antimagic || Free_action) { 523. shieldeff(u.ux, u.uy); 524. if (!Stunned) 525. You_feel("momentarily disoriented."); 526. make_stunned(1L, FALSE); 527. } else { 528. You(Stunned ? "struggle to keep your balance." : "reel..."); 529. dmg = d(ACURR(A_DEX) < 12 ? 6 : 4, 4); 530. if (Half_spell_damage) dmg = (dmg + 1) / 2; 531. make_stunned(HStun + dmg, FALSE); 532. } 533. dmg = 0; 534. break; 535. case MGC_HASTE_SELF: 536. mon_adjust_speed(mtmp, 1, (struct obj *)0); 537. dmg = 0; 538. break; 539. case MGC_CURE_SELF: 540. if (mtmp->mhp < mtmp->mhpmax) { 541. if (canseemon(mtmp)) 542. pline("%s looks better.", Monnam(mtmp)); 543. /* note: player healing does 6d4; this used to do 1d8 */ 544. if ((mtmp->mhp += d(3,6)) > mtmp->mhpmax) 545. mtmp->mhp = mtmp->mhpmax; 546. dmg = 0; 547. } 548. break; 549. case MGC_PSI_BOLT: 550. /* prior to 3.4.0 Antimagic was setting the damage to 1--this 551. made the spell virtually harmless to players with magic res. */ 552. if (Antimagic) { 553. shieldeff(u.ux, u.uy); 554. dmg = (dmg + 1) / 2; 555. } 556. if (dmg <= 5) 557. You("get a slight %sache.", body_part(HEAD)); 558. else if (dmg <= 10) 559. Your("brain is on fire!"); 560. else if (dmg <= 20) 561. Your("%s suddenly aches painfully!", body_part(HEAD)); 562. else 563. Your("%s suddenly aches very painfully!", body_part(HEAD)); 564. break; 565. default: 566. impossible("mcastu: invalid magic spell (%d)", spellnum); 567. dmg = 0; 568. break; 569. } 570. 571. if (dmg) mdamageu(mtmp, dmg); 572. } 573. 574. STATIC_OVL 575. void 576. cast_cleric_spell(mtmp, dmg, spellnum) 577. struct monst *mtmp; 578. int dmg; 579. int spellnum; 580. { 581. if (dmg == 0 && !is_undirected_spell(AD_CLRC, spellnum)) { 582. impossible("cast directed cleric spell (%d) with dmg=0?", spellnum); 583. return; 584. } 585. 586. switch (spellnum) { 587. case CLC_GEYSER: 588. /* this is physical damage, not magical damage */ 589. pline("A sudden geyser slams into you from nowhere!"); 590. dmg = d(8, 6); 591. if (Half_physical_damage) dmg = (dmg + 1) / 2; 592. break; 593. case CLC_FIRE_PILLAR: 594. pline("A pillar of fire strikes all around you!"); 595. if (Fire_resistance) { 596. shieldeff(u.ux, u.uy); 597. dmg = 0; 598. } else 599. dmg = d(8, 6); 600. if (Half_spell_damage) dmg = (dmg + 1) / 2; 601. burn_away_slime(); 602. (void) burnarmor(&youmonst); 603. destroy_item(SCROLL_CLASS, AD_FIRE); 604. destroy_item(POTION_CLASS, AD_FIRE); 605. destroy_item(SPBOOK_CLASS, AD_FIRE); 606. (void) burn_floor_paper(u.ux, u.uy, TRUE, FALSE); 607. break; 608. case CLC_LIGHTNING: 609. { 610. boolean reflects; 611. 612. /* WAC add lightning strike effect */ 613. zap_strike_fx(u.ux, u.uy, AD_ELEC - 1); 614. pline("A bolt of lightning strikes down at you from above!"); 615. reflects = ureflects("It bounces off your %s%s.", ""); 616. if (!Blind) { 617. pline("You are blinded by the flash!"); 618. make_blinded(Half_spell_damage ? 10L : 20L, FALSE); 619. } 620. if (reflects || Shock_resistance) { 621. shieldeff(u.ux, u.uy); 622. dmg = 0; 623. if (reflects) 624. break; 625. } else 626. dmg = d(8, 6); 627. if (Half_spell_damage) dmg = (dmg + 1) / 2; 628. destroy_item(WAND_CLASS, AD_ELEC); 629. destroy_item(RING_CLASS, AD_ELEC); 630. break; 631. } 632. case CLC_CURSE_ITEMS: 633. You_feel("as if you need some help."); 634. rndcurse(); 635. dmg = 0; 636. break; 637. case CLC_INSECTS: 638. { 639. /* Try for insects, and if there are none 640. left, go for (sticks to) snakes. -3. */ 641. struct permonst *pm = mkclass(S_ANT,0); 642. struct monst *mtmp2 = (struct monst *)0; 643. char let = (pm ? S_ANT : S_SNAKE); 644. boolean success; 645. int i; 646. coord bypos; 647. int quan; 648. 649. quan = (mtmp->m_lev < 2) ? 1 : rnd((int)mtmp->m_lev / 2); 650. if (quan < 3) quan = 3; 651. success = pm ? TRUE : FALSE; 652. for (i = 0; i <= quan; i++) { 653. if (!enexto(&bypos, mtmp->mux, mtmp->muy, mtmp->data)) 654. break; 655. if ((pm = mkclass(let,0)) != 0 && 656. (mtmp2 = makemon(pm, bypos.x, bypos.y, NO_MM_FLAGS)) != 0) { 657. success = TRUE; 658. mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0; 659. set_malign(mtmp2); 660. } 661. } 662. /* Not quite right: 663. * -- message doesn't always make sense for unseen caster (particularly 664. * the first message) 665. * -- message assumes plural monsters summoned (non-plural should be 666. * very rare, unlike in nasty()) 667. * -- message assumes plural monsters seen 668. */ 669. if (!success) 670. pline("%s casts at a clump of sticks, but nothing happens.", 671. Monnam(mtmp)); 672. else if (let == S_SNAKE) 673. pline("%s transforms a clump of sticks into snakes!", 674. Monnam(mtmp)); 675. else if (Invisible && !perceives(mtmp->data) && 676. (mtmp->mux != u.ux || mtmp->muy != u.uy)) 677. pline("%s summons insects around a spot near you!", 678. Monnam(mtmp)); 679. else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) 680. pline("%s summons insects around your displaced image!", 681. Monnam(mtmp)); 682. else 683. pline("%s summons insects!", Monnam(mtmp)); 684. dmg = 0; 685. break; 686. } 687. case CLC_BLIND_YOU: 688. /* note: resists_blnd() doesn't apply here */ 689. if (!Blinded) { 690. int num_eyes = eyecount(youmonst.data); 691. pline("Scales cover your %s!", 692. (num_eyes == 1) ? 693. body_part(EYE) : makeplural(body_part(EYE))); 694. make_blinded(Half_spell_damage ? 100L : 200L, FALSE); 695. if (!Blind) Your(vision_clears); 696. dmg = 0; 697. } else 698. impossible("no reason for monster to cast blindness spell?"); 699. break; 700. case CLC_PARALYZE: 701. if (Antimagic || Free_action) { 702. shieldeff(u.ux, u.uy); 703. if (multi >= 0) 704. You("stiffen briefly."); 705. nomul(-1); 706. } else { 707. if (multi >= 0) 708. You("are frozen in place!"); 709. dmg = 4 + (int)mtmp->m_lev; 710. if (Half_spell_damage) dmg = (dmg + 1) / 2; 711. nomul(-dmg); 712. } 713. nomovemsg = 0; 714. dmg = 0; 715. break; 716. case CLC_CONFUSE_YOU: 717. if (Antimagic) { 718. shieldeff(u.ux, u.uy); 719. You_feel("momentarily dizzy."); 720. } else { 721. boolean oldprop = !!Confusion; 722. 723. dmg = (int)mtmp->m_lev; 724. if (Half_spell_damage) dmg = (dmg + 1) / 2; 725. make_confused(HConfusion + dmg, TRUE); 726. if (Hallucination) 727. You_feel("%s!", oldprop ? "trippier" : "trippy"); 728. else 729. You_feel("%sconfused!", oldprop ? "more " : ""); 730. } 731. dmg = 0; 732. break; 733. case CLC_CURE_SELF: 734. if (mtmp->mhp < mtmp->mhpmax) { 735. if (canseemon(mtmp)) 736. pline("%s looks better.", Monnam(mtmp)); 737. /* note: player healing does 6d4; this used to do 1d8 */ 738. if ((mtmp->mhp += d(3,6)) > mtmp->mhpmax) 739. mtmp->mhp = mtmp->mhpmax; 740. dmg = 0; 741. } 742. break; 743. case CLC_OPEN_WOUNDS: 744. if (Antimagic) { 745. shieldeff(u.ux, u.uy); 746. dmg = (dmg + 1) / 2; 747. } 748. if (dmg <= 5) 749. Your("skin itches badly for a moment."); 750. else if (dmg <= 10) 751. pline("Wounds appear on your body!"); 752. else if (dmg <= 20) 753. pline("Severe wounds appear on your body!"); 754. else 755. Your("body is covered with painful wounds!"); 756. break; 757. default: 758. impossible("mcastu: invalid clerical spell (%d)", spellnum); 759. dmg = 0; 760. break; 761. } 762. 763. if (dmg) mdamageu(mtmp, dmg); 764. } 765. 766. STATIC_DCL 767. boolean 768. is_undirected_spell(adtyp, spellnum) 769. unsigned int adtyp; 770. int spellnum; 771. { 772. if (adtyp == AD_SPEL) { 773. switch (spellnum) { 774. case MGC_CLONE_WIZ: 775. case MGC_SUMMON_MONS: 776. case MGC_AGGRAVATION: 777. case MGC_DISAPPEAR: 778. case MGC_HASTE_SELF: 779. case MGC_CURE_SELF: 780. case MGC_CALL_UNDEAD: 781. return TRUE; 782. default: 783. break; 784. } 785. } else if (adtyp == AD_CLRC) { 786. switch (spellnum) { 787. case CLC_INSECTS: 788. case CLC_CURE_SELF: 789. return TRUE; 790. default: 791. break; 792. } 793. } 794. return FALSE; 795. } 796. 797. /* Some spells are useless under some circumstances. */ 798. STATIC_DCL 799. boolean 800. spell_would_be_useless(mtmp, adtyp, spellnum) 801. struct monst *mtmp; 802. unsigned int adtyp; 803. int spellnum; 804. { 805. /* Some spells don't require the player to really be there and can be cast 806. * by the monster when you're invisible, yet still shouldn't be cast when 807. * the monster doesn't even think you're there. 808. * This check isn't quite right because it always uses your real position. 809. * We really want something like "if the monster could see mux, muy". 810. */ 811. boolean mcouldseeu = couldsee(mtmp->mx, mtmp->my); 812. 813. if (adtyp == AD_SPEL) { 814. /* aggravate monsters, etc. won't be cast by peaceful monsters */ 815. if (mtmp->mpeaceful && (spellnum == MGC_AGGRAVATION || 816. spellnum == MGC_SUMMON_MONS || spellnum == MGC_CLONE_WIZ || 817. spellnum == MGC_CALL_UNDEAD)) 818. return TRUE; 819. /* haste self when already fast */ 820. if (mtmp->permspeed == MFAST && spellnum == MGC_HASTE_SELF) 821. return TRUE; 822. /* invisibility when already invisible */ 823. if ((mtmp->minvis || mtmp->invis_blkd) && spellnum == MGC_DISAPPEAR) 824. return TRUE; 825. /* peaceful monster won't cast invisibility if you can't see invisible, 826. same as when monsters drink potions of invisibility. This doesn't 827. really make a lot of sense, but lets the player avoid hitting 828. peaceful monsters by mistake */ 829. if (mtmp->mpeaceful && !See_invisible && spellnum == MGC_DISAPPEAR) 830. return TRUE; 831. /* healing when already healed */ 832. if (mtmp->mhp == mtmp->mhpmax && spellnum == MGC_CURE_SELF) 833. return TRUE; 834. /* don't summon monsters if it doesn't think you're around */ 835. if (!mcouldseeu && (spellnum == MGC_SUMMON_MONS || 836. spellnum == MGC_CALL_UNDEAD || 837. (!mtmp->iswiz && spellnum == MGC_CLONE_WIZ))) 838. return TRUE; 839. /* only lichs can cast call undead */ 840. if (mtmp->data->mlet != S_LICH && spellnum == MGC_CALL_UNDEAD) 841. return TRUE; 842. /* pools can only be created in certain locations and then only 843. * rarely unless you're carrying the amulet. 844. */ 845. if ((levl[u.ux][u.uy].typ != ROOM && levl[u.ux][u.uy].typ != CORR 846. || !u.uhave.amulet && rn2(10)) && spellnum == MGC_CREATE_POOL) 847. return TRUE; 848. if ((!mtmp->iswiz || flags.no_of_wizards > 1) 849. && spellnum == MGC_CLONE_WIZ) 850. return TRUE; 851. } else if (adtyp == AD_CLRC) { 852. /* summon insects/sticks to snakes won't be cast by peaceful monsters */ 853. if (mtmp->mpeaceful && spellnum == CLC_INSECTS) 854. return TRUE; 855. /* healing when already healed */ 856. if (mtmp->mhp == mtmp->mhpmax && spellnum == CLC_CURE_SELF) 857. return TRUE; 858. /* don't summon insects if it doesn't think you're around */ 859. if (!mcouldseeu && spellnum == CLC_INSECTS) 860. return TRUE; 861. /* blindness spell on blinded player */ 862. if (Blinded && spellnum == CLC_BLIND_YOU) 863. return TRUE; 864. } 865. return FALSE; 866. } 867. 868. #endif /* OVLB */ 869. #ifdef OVL0 870. 871. /* convert 1..10 to 0..9; add 10 for second group (spell casting) */ 872. #define ad_to_typ(k) (10 + (int)k - 1) 873. 874. int 875. buzzmu(mtmp, mattk) /* monster uses spell (ranged) */ 876. register struct monst *mtmp; 877. register struct attack *mattk; 878. { 879. /* don't print constant stream of curse messages for 'normal' 880. spellcasting monsters at range */ 881. if (mattk->adtyp > AD_SPC2) 882. return(0); 883. 884. if (mtmp->mcan) { 885. cursetxt(mtmp, FALSE); 886. return(0); 887. } 888. if(lined_up(mtmp) && rn2(3)) { 889. nomul(0); 890. if(mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */ 891. if(canseemon(mtmp)) 892. pline("%s zaps you with a %s!", Monnam(mtmp), 893. flash_types[ad_to_typ(mattk->adtyp)]); 894. buzz(-ad_to_typ(mattk->adtyp), (int)mattk->damn, 895. mtmp->mx, mtmp->my, sgn(tbx), sgn(tby)); 896. } else impossible("Monster spell %d cast", mattk->adtyp-1); 897. } 898. return(1); 899. } 900. 901. #endif /* OVL0 */ 902. 903. /*mcastu.c*/