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
Edit
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.
Monster mage spells
Edit
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
Edit
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
Edit
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
Edit
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
Edit
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) && 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
Edit
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
Edit
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
Edit
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
Edit
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 */
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*/