Blindfold removal fix
[slashemextended.git] / src / mcastu.c
blob01c0c2df83b757b6733a0063eb9142b96c2ce95b
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. */
5 #include "hack.h"
6 #include "edog.h" /* sporkhack MGC_ENRAGE needs this */
8 /* monster mage spells */
9 #define MGC_PSI_BOLT 0
10 #define MGC_CURE_SELF 1
11 #define MGC_HASTE_SELF 2
12 #define MGC_STUN_YOU 3
13 #define MGC_DISAPPEAR 4
14 #define MGC_WEAKEN_YOU 5
15 #define MGC_DESTRY_ARMR 6
16 #define MGC_CURSE_ITEMS 7
17 #define MGC_AGGRAVATION 8
18 #define MGC_SUMMON_MONS 9
19 #define MGC_CLONE_WIZ 10
20 #define MGC_DEATH_TOUCH 11
21 #define MGC_CREATE_POOL 12
22 #define MGC_CALL_UNDEAD 13
23 #define MGC_WITHER 14
24 #define MGC_DAMAGE_ARMR 15
25 #define MGC_ENRAGE 16
26 #define MGC_DIVINE_WRATH 17
27 #define MGC_SUMMON_GHOST 18
28 #define MGC_MEGALOAD 19
29 #define MGC_LEVITATE 20
30 #define MGC_NUMB_YOU 21
31 #define MGC_BURN_YOU 22
32 #define MGC_ESCALATION 23
34 /* monster cleric spells */
35 #define CLC_OPEN_WOUNDS 0
36 #define CLC_CURE_SELF 1
37 #define CLC_CONFUSE_YOU 2
38 #define CLC_PARALYZE 3
39 #define CLC_BLIND_YOU 4
40 #define CLC_INSECTS 5
41 #define CLC_CURSE_ITEMS 6
42 #define CLC_LIGHTNING 7
43 #define CLC_FIRE_PILLAR 8
44 #define CLC_GEYSER 9
45 #define CLC_AGGRAVATION 10
46 #define CLC_PETRIFY 11 /* currently unused */
47 #define CLC_RANDOM 12
48 #define CLC_VULN_YOU 13
49 #define CLC_SEPARATION 14
50 #define CLC_FEAR_YOU 15
51 #define CLC_FREEZE_YOU 16
52 #define CLC_STAT_DRAIN 17
54 STATIC_DCL void cursetxt(struct monst *,BOOLEAN_P);
55 STATIC_DCL int choose_magic_spell(int);
56 STATIC_DCL int choose_clerical_spell(int);
57 STATIC_DCL void cast_wizard_spell(struct monst *, int,int);
58 STATIC_DCL void cast_cleric_spell(struct monst *, int,int);
59 STATIC_DCL boolean is_undirected_spell(unsigned int,int);
60 STATIC_DCL boolean is_melee_spell(unsigned int,int);
61 STATIC_DCL boolean spell_would_be_useless(struct monst *,unsigned int,int);
62 STATIC_PTR void set_litZ(int,int,void *);
63 STATIC_DCL boolean arcaniumfail(void);
65 #ifdef OVL0
67 extern const char * const flash_types[]; /* from zap.c */
69 /* feedback when frustrated monster couldn't cast a spell */
70 STATIC_OVL
71 void
72 cursetxt(mtmp, undirected)
73 struct monst *mtmp;
74 boolean undirected;
76 if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)) {
77 const char *point_msg; /* spellcasting monsters are impolite */
79 if (undirected)
80 point_msg = "all around, then curses";
81 else if ((Invis && !perceives(mtmp->data) && (StrongInvis || !rn2(3)) &&
82 (mtmp->mux != u.ux || mtmp->muy != u.uy)) ||
83 (youmonst.m_ap_type == M_AP_OBJECT &&
84 youmonst.mappearance == STRANGE_OBJECT) ||
85 u.uundetected)
86 point_msg = "and curses in your general direction";
87 else if (Displaced && (StrongDisplaced || !rn2(3)) && (mtmp->mux != u.ux || mtmp->muy != u.uy))
88 point_msg = "and curses at your displaced image";
89 else
90 point_msg = "at you, then curses";
92 pline("%s points %s.", Monnam(mtmp), point_msg);
93 } else if ((!(moves % 4) || !rn2(4))) {
94 if (flags.soundok && !issoviet) Norep("You hear a mumbled curse.");
98 #endif /* OVL0 */
99 #ifdef OVLB
101 /* will a monster fail to cast a spell? this happens if you wear arcanium equipment --Amy
102 * it's not a bug that this can also affect spellcasting pets; returns TRUE if the monster actually fails to cast */
103 STATIC_OVL boolean
104 arcaniumfail()
106 if (uwep && objects[uwep->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
107 return TRUE;
109 if (u.twoweap && uswapwep && objects[uswapwep->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
110 return TRUE;
112 if (uarm && objects[uarm->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
113 return TRUE;
115 if (uarmc && objects[uarmc->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
116 return TRUE;
118 if (uarmh && objects[uarmh->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
119 return TRUE;
121 if (uarms && objects[uarms->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
122 return TRUE;
124 if (uarmg && objects[uarmg->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
125 return TRUE;
127 if (uarmf && objects[uarmf->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
128 return TRUE;
130 if (uarmu && objects[uarmu->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
131 return TRUE;
133 if (uamul && objects[uamul->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
134 return TRUE;
136 if (uimplant && objects[uimplant->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
137 return TRUE;
139 if (uleft && objects[uleft->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
140 return TRUE;
142 if (uright && objects[uright->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
143 return TRUE;
145 if (ublindf && objects[ublindf->otyp].oc_material == MT_ARCANIUM && !rn2(20)) {
146 return TRUE;
149 return FALSE;
152 /* convert a level based random selection into a specific mage spell;
153 inappropriate choices will be screened out by spell_would_be_useless() */
154 STATIC_OVL int
155 choose_magic_spell(spellval)
156 int spellval;
158 if (EnthuActive) spellval = rnd(45);
160 switch (spellval) {
161 case 45:
162 if (!rn2(25)) return MGC_DIVINE_WRATH; /* waaaay too overpowered, so this will appear much more rarely --Amy */
163 else return MGC_ENRAGE;
164 case 44:
165 return MGC_ENRAGE; /* we reduce the risk of getting a touch of death */
166 case 43:
167 return MGC_DEATH_TOUCH;
168 case 42:
169 return MGC_ESCALATION;
170 case 41:
171 if (!rn2(25)) return MGC_SUMMON_GHOST; /* Should be rare --Amy */
172 else return MGC_CLONE_WIZ;
173 case 40:
174 case 39:
175 return MGC_HASTE_SELF;
176 case 38:
177 return MGC_SUMMON_MONS;
178 case 37:
179 case 36:
180 return MGC_AGGRAVATION;
181 case 35:
182 if (!rn2(2)) return MGC_LEVITATE;
183 else if (!rn2(5)) return MGC_MEGALOAD;
184 else return MGC_CREATE_POOL;
185 case 34:
186 return MGC_NUMB_YOU;
187 case 33:
188 return MGC_CURSE_ITEMS;
189 case 32:
190 return MGC_CALL_UNDEAD;
191 case 31:
192 if (!rn2(4)) return MGC_WITHER;
193 else if (!rn2(2)) return MGC_DAMAGE_ARMR;
194 else return MGC_DESTRY_ARMR;
195 case 30:
196 return MGC_BURN_YOU;
197 case 29:
198 return MGC_WEAKEN_YOU;
199 case 28:
200 return MGC_NUMB_YOU;
201 case 27:
202 return MGC_DISAPPEAR;
203 case 26:
204 return MGC_STUN_YOU;
205 case 25:
206 return MGC_HASTE_SELF;
207 case 24:
208 return MGC_CURE_SELF;
209 case 23:
210 return MGC_PSI_BOLT;
211 case 22:
212 if (!rn2(25)) return MGC_DIVINE_WRATH; /* waaaay too overpowered, so this will appear much more rarely --Amy */
213 else return MGC_ENRAGE;
214 case 21:
215 return MGC_ENRAGE; /* we reduce the risk of getting a touch of death */
216 case 20:
217 return MGC_DEATH_TOUCH;
218 case 19:
219 return MGC_ESCALATION;
220 case 18:
221 if (!rn2(25)) return MGC_SUMMON_GHOST; /* Should be rare --Amy */
222 else return MGC_CLONE_WIZ;
223 case 17:
224 case 16:
225 return MGC_HASTE_SELF;
226 case 15:
227 return MGC_SUMMON_MONS;
228 case 14:
229 case 13:
230 return MGC_AGGRAVATION;
231 case 12:
232 if (!rn2(2)) return MGC_LEVITATE;
233 else if (!rn2(5)) return MGC_MEGALOAD;
234 else return MGC_CREATE_POOL;
235 case 11:
236 return MGC_NUMB_YOU;
237 case 10:
238 return MGC_CURSE_ITEMS;
239 case 9:
240 return MGC_CALL_UNDEAD;
241 case 8:
242 if (!rn2(4)) return MGC_WITHER;
243 else if (!rn2(2)) return MGC_DAMAGE_ARMR;
244 else return MGC_DESTRY_ARMR;
245 case 7:
246 return MGC_BURN_YOU;
247 case 6:
248 return MGC_WEAKEN_YOU;
249 case 5:
250 return MGC_NUMB_YOU;
251 case 4:
252 return MGC_DISAPPEAR;
253 case 3:
254 return MGC_STUN_YOU;
255 case 2:
256 return MGC_HASTE_SELF;
257 case 1:
258 return MGC_CURE_SELF;
259 case 0:
260 default:
261 return MGC_PSI_BOLT;
265 /* convert a level based random selection into a specific cleric spell */
266 STATIC_OVL int
267 choose_clerical_spell(spellnum)
268 int spellnum;
270 if (EnthuActive) spellnum = rnd(41);
272 switch (spellnum) {
273 case 41:
274 return CLC_GEYSER;
275 case 40:
276 return CLC_FIRE_PILLAR;
277 case 39:
278 return CLC_LIGHTNING;
279 case 38:
280 return CLC_STAT_DRAIN;
281 case 37:
282 return CLC_CURSE_ITEMS;
283 case 36:
284 if (rn2(2)) return CLC_RANDOM;
285 else if (!rn2(50)) return CLC_AGGRAVATION;
286 else return CLC_INSECTS;
287 case 35:
288 return CLC_FREEZE_YOU;
289 case 34:
290 return CLC_BLIND_YOU;
291 case 33:
292 return CLC_FEAR_YOU;
293 case 32:
294 return CLC_PARALYZE;
295 case 31:
296 return CLC_SEPARATION;
297 case 30:
298 return CLC_CONFUSE_YOU;
299 case 29:
300 return CLC_CURE_SELF;
301 case 28:
302 return (rn2(10) ? CLC_OPEN_WOUNDS : CLC_VULN_YOU);
303 case 27:
304 return CLC_GEYSER;
305 case 26:
306 return CLC_FIRE_PILLAR;
307 case 25:
308 return CLC_LIGHTNING;
309 case 24:
310 return CLC_STAT_DRAIN;
311 case 23:
312 return CLC_CURSE_ITEMS;
313 case 22:
314 if (rn2(2)) return CLC_RANDOM;
315 else if (!rn2(50)) return CLC_AGGRAVATION;
316 else return CLC_INSECTS;
317 case 21:
318 return CLC_FREEZE_YOU;
319 case 20:
320 return CLC_BLIND_YOU;
321 case 19:
322 return CLC_FEAR_YOU;
323 case 18:
324 return CLC_PARALYZE;
325 case 17:
326 return CLC_SEPARATION;
327 case 16:
328 return CLC_CONFUSE_YOU;
329 case 15:
330 return CLC_CURE_SELF;
331 case 14:
332 return (rn2(10) ? CLC_OPEN_WOUNDS : CLC_VULN_YOU);
333 case 13:
334 return CLC_GEYSER;
335 case 12:
336 return CLC_FIRE_PILLAR;
337 case 11:
338 return CLC_LIGHTNING;
339 case 10:
340 return CLC_STAT_DRAIN;
341 case 9:
342 return CLC_CURSE_ITEMS;
343 case 8:
344 if (rn2(2)) return CLC_RANDOM;
345 else if (!rn2(50)) return CLC_AGGRAVATION;
346 else return CLC_INSECTS;
347 case 7:
348 return CLC_FREEZE_YOU;
349 case 6:
350 return CLC_BLIND_YOU;
351 case 5:
352 return CLC_FEAR_YOU;
353 case 4:
354 return CLC_PARALYZE;
355 case 3:
356 return CLC_SEPARATION;
357 case 2:
358 return CLC_CONFUSE_YOU;
359 case 1:
360 return CLC_CURE_SELF;
361 case 0:
362 default:
363 return (rn2(10) ? CLC_OPEN_WOUNDS : CLC_VULN_YOU);
367 /* return values:
368 * 1: successful spell
369 * 0: unsuccessful spell
372 castmu(mtmp, mattk, thinks_it_foundyou, foundyou)
373 register struct monst *mtmp;
374 register struct attack *mattk;
375 boolean thinks_it_foundyou;
376 boolean foundyou;
378 int dmg, ml = mtmp->m_lev;
379 int ret;
380 int spellnum = 0;
381 int spellev, chance, difficulty, splcaster, learning;
382 boolean monsterniman = FALSE;
384 if (MON_WEP(mtmp)) { /* niman monster lightsaber form */
385 struct obj *monweapon;
386 monweapon = MON_WEP(mtmp);
387 if (monweapon) {
388 if (is_lightsaber(monweapon) && monweapon->lamplit) {
389 ml += 5;
390 if (mtmp->data->geno & G_UNIQ) ml += 5;
391 monsterniman = TRUE;
397 int spellcasttype = mattk->adtyp;
398 if (EnthuActive && !rn2(10)) {
399 if (!rn2(3)) spellcasttype = AD_SPEL;
400 else if (!rn2(2)) spellcasttype = AD_CLRC;
401 else if (!rn2(100)) spellcasttype = AD_DISN;
402 else {
403 switch (rnd(9)) {
404 case 1:
405 spellcasttype = AD_MAGM; break;
406 case 2:
407 spellcasttype = AD_FIRE; break;
408 case 3:
409 spellcasttype = AD_COLD; break;
410 case 4:
411 spellcasttype = AD_ELEC; break;
412 case 5:
413 spellcasttype = AD_SLEE; break;
414 case 6:
415 spellcasttype = AD_DRST; break;
416 case 7:
417 spellcasttype = AD_ACID; break;
418 case 8:
419 spellcasttype = AD_LITE; break;
420 case 9:
421 spellcasttype = AD_SPC2; break;
426 /* Three cases:
427 * -- monster is attacking you. Search for a useful spell.
428 * -- monster thinks it's attacking you. Search for a useful spell,
429 * without checking for undirected. If the spell found is directed,
430 * it fails with cursetxt() and loss of mspec_used.
431 * -- monster isn't trying to attack. Select a spell once. Don't keep
432 * searching; if that spell is not useful (or if it's directed),
433 * return and do something else.
434 * Since most spells are directed, this means that a monster that isn't
435 * attacking casts spells only a small portion of the time that an
436 * attacking monster does.
438 if ((spellcasttype == AD_SPEL || spellcasttype == AD_CLRC || spellcasttype == AD_CAST) && ml) {
439 int cnt = 40;
441 do {
442 spellnum = (issoviet ? rn2(ml) : rn3(ml));
443 /* Casting level is limited by available energy */
444 spellev = spellnum / 7 + 1;
445 if (spellev > 10) spellev = 10;
446 if (spellev * 5 > mtmp->m_en) {
447 spellev = mtmp->m_en / 5;
448 spellnum = (spellev - 1) * 7 + 1;
450 if (EnthuActive) {
451 spellnum = rn2(2) ? choose_magic_spell(spellnum) : choose_clerical_spell(spellnum);
452 while (rn2(7) && !spellnum) {
453 spellnum = rn2(2) ? choose_magic_spell(spellnum) : choose_clerical_spell(spellnum);
455 } if (spellcasttype == AD_SPEL)
456 spellnum = choose_magic_spell(spellnum);
457 else if (spellcasttype == AD_CLRC)
458 spellnum = choose_clerical_spell(spellnum);
459 else { /* AD_CAST - often reroll when psybolt or open wounds is chosen --Amy */
461 if ((moves % 4 == 0) || ((moves + 1) % 4 == 0)) {
462 spellnum = choose_clerical_spell(spellnum);
463 spellcasttype = AD_CLRC;
464 } else {
465 spellnum = choose_magic_spell(spellnum);
466 spellcasttype = AD_SPEL;
469 while (rn2(7) && !spellnum) {
471 if ((moves % 4 == 0) || ((moves + 1) % 4 == 0)) {
472 spellnum = choose_clerical_spell(spellnum);
473 spellcasttype = AD_CLRC;
474 } else {
475 spellnum = choose_magic_spell(spellnum);
476 spellcasttype = AD_SPEL;
482 /* not trying to attack? don't allow directed spells */
483 if (!thinks_it_foundyou) {
484 if ( (!is_undirected_spell(spellcasttype, spellnum) && rn2(250) ) || is_melee_spell(spellcasttype, spellnum) || spell_would_be_useless(mtmp, spellcasttype, spellnum)) {
485 if (foundyou)
486 impossible("spellcasting monster found you and doesn't know it?");
487 return 0;
489 break;
491 } while(--cnt > 0 &&
492 spell_would_be_useless(mtmp, spellcasttype, spellnum));
493 if (cnt == 0) return 0;
494 } else {
495 /* Casting level is limited by available energy */
496 spellev = ml / 7 + 1;
497 if (spellev > 10) spellev = 10;
498 if (spellev * 5 > mtmp->m_en) {
499 spellev = mtmp->m_en / 5;
500 ml = (spellev - 1) * 7 + 1;
504 /* monster unable to cast spells?
505 * Amy note: it is not a bug that we're not using "autismweaponcheck" here - weapon has to be main one */
506 if (mtmp->mcan || arcaniumfail() || (mtmp->data == &mons[PM_KLAPPTNIX]) || (RngeAntimagicA && !rn2(10)) || (RngeAntimagicB && !rn2(5)) || (RngeAntimagicC && !rn2(2)) || (RngeAntimagicD) || (RngeSpellDisruption && !rn2(5)) || mtmp->m_en < 5 || (mtmp->mspec_used && !(mtmp->data == &mons[PM_MAND_PENDING__MAGIC_SPELL___])) || !ml || u.antimagicshell || (uarmh && uarmh->otyp == HELM_OF_ANTI_MAGIC) || (uarmc && uarmc->oartifact == ART_SHELLY && (moves % 3 == 0)) || (uarmc && uarmc->oartifact == ART_BLACK_VEIL_OF_BLACKNESS) || (uarmc && uarmc->oartifact == ART_ARABELLA_S_WAND_BOOSTER) || (uarmu && uarmu->oartifact == ART_ANTIMAGIC_SHELL) || (uwep && uwep->oartifact == ART_WINCHESTER_PREMIUM) || (uarmu && uarmu->oartifact == ART_ANTIMAGIC_FIELD) || Role_if(PM_UNBELIEVER) || (uwep && uwep->oartifact == ART_ARK_OF_THE_COVENANT) || (uwep && uwep->oartifact == ART_LONG_SWORD_OF_ETERNITY) || (uwep && uwep->oartifact == ART_HEAVY_CROSSBOW_OF_ETERNITY) || (uarmc && uarmc->oartifact == ART_SPELL_WARDED_WRAPPINGS_OF_) || (uwep && uwep->oartifact == ART_ANTIMAGICBANE) || (uarmc && (itemhasappearance(uarmc, APP_VOID_CLOAK) || itemhasappearance(uarmc, APP_SHELL_CLOAK)) && !rn2(5)) ) {
507 cursetxt(mtmp, is_undirected_spell(spellcasttype, spellnum));
508 return(0);
511 if (spellcasttype == AD_SPEL || spellcasttype == AD_CLRC || spellcasttype == AD_CAST) {
513 * Spell use (especially MGC) is more common in Slash'EM.
514 * Still using mspec_used, just so monsters don't go bonkers.
516 #if 0
517 mtmp->mspec_used = 10 - mtmp->m_lev;
518 if (mtmp->mspec_used < 2) mtmp->mspec_used = 2;
519 #endif
520 mtmp->mspec_used = rn2(15) - mtmp->m_lev;
521 if (spellcasttype == AD_SPEL)
522 mtmp->mspec_used = mtmp->mspec_used > 0 ? 2 : 0;
523 else if (mtmp->mspec_used < 2) mtmp->mspec_used = 2;
526 /* monster can cast spells, but is casting a directed spell at the
527 wrong place? If so, give a message, and return. Do this *after*
528 penalizing mspec_used. */
529 if (!foundyou && thinks_it_foundyou &&
530 !is_undirected_spell(spellcasttype, spellnum)) {
531 pline("%s casts a spell at %s!",
532 canseemon(mtmp) ? Monnam(mtmp) : "Something",
533 levl[mtmp->mux][mtmp->muy].typ == WATER
534 ? "empty water" : "thin air");
535 return(0);
538 nomul(0, 0, FALSE);
540 mtmp->m_en -= spellev * 5; /* Use up the energy now */
542 /* We should probably do similar checks to what is done for
543 * the player - armor, etc.
544 * Checks for armour and other intrinsic ability change splcaster
545 * Difficulty and experience affect chance
546 * Assume that monsters only cast spells that they know well
548 splcaster = 15 - (mtmp->m_lev / 2); /* Base for a wizard is 5...*/
550 if (splcaster < 5) splcaster = 5;
551 if (splcaster > 20) splcaster = 20;
553 chance = 11 * (mtmp->m_lev > 25 ? 18 : (12 + (mtmp->m_lev / 5)));
554 chance++ ; /* Minimum chance of 1 */
556 difficulty = (spellev - 1) * 4 - (mtmp->m_lev - 1);
557 /* law of diminishing returns sets in quickly for
558 * low-level spells. That is, higher levels quickly
559 * result in almost no gain
561 learning = 15 * (-difficulty / spellev);
562 chance += learning > 20 ? 20 : learning;
564 if (monsterniman) {
565 chance += 25;
566 if (mtmp->data->geno & G_UNIQ) chance += 25;
569 /* clamp the chance */
570 if (chance < 0) chance = 0;
571 if (chance > 120) chance = 120;
573 /* combine */
574 chance = chance * (20-splcaster) / 15 - splcaster;
576 /* Clamp to percentile */
577 if (chance > 100) chance = 100;
578 if (chance < 0) chance = 0;
580 #if 0
581 if(rn2(ml*10) < (mtmp->mconf ? 100 : 20)) { /* fumbled attack */
582 #else
583 if (mtmp->mconf || rnd(100) > chance) { /* fumbled attack */
584 #endif
585 if (canseemon(mtmp) && flags.soundok)
586 pline_The("air crackles around %s.", mon_nam(mtmp));
587 return(0);
589 if (canspotmon(mtmp) || !is_undirected_spell(spellcasttype, spellnum)) {
590 pline("%s casts a spell%s!",
591 canspotmon(mtmp) ? Monnam(mtmp) : "Something",
592 is_undirected_spell(spellcasttype, spellnum) ? "" :
593 (Invisible && !perceives(mtmp->data) && (StrongInvis || !rn2(3)) &&
594 (mtmp->mux != u.ux || mtmp->muy != u.uy)) ?
595 " at a spot near you" :
596 (Displaced && (StrongDisplaced || !rn2(3)) && (mtmp->mux != u.ux || mtmp->muy != u.uy)) ?
597 " at your displaced image" :
598 " at you");
599 } else if (flags.soundok && !issoviet) You_hear("a mumbled incantation.");
602 * As these are spells, the damage is related to the level
603 * of the monster casting the spell.
605 if (!foundyou) {
606 /*dmg = 0;*/
607 if (spellcasttype != AD_SPEL && spellcasttype != AD_CLRC && spellcasttype != AD_CAST) {
608 impossible(
609 "%s casting non-hand-to-hand version of hand-to-hand spell %d?",
610 Monnam(mtmp), spellcasttype);
611 return(0);
613 } /*else*/ if (mattk->damd)
614 dmg = d((int)((ml/2) + mattk->damn), (int)mattk->damd);
615 else dmg = d((int)((ml/2) + 1), 6);
616 if (Half_spell_damage && rn2(2) ) dmg = (dmg+1) / 2;
617 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg+1) / 2;
619 ret = 1;
621 switch (spellcasttype) {
623 case AD_FIRE:
624 pline("You're enveloped in flames.");
626 if (Race_if(PM_LOWER_ENT)) dmg *= 2;
628 if((Fire_resistance && rn2(StrongFire_resistance ? 20 : 5)) || FireImmunity) {
629 shieldeff(u.ux, u.uy);
630 pline("But you resist the effects.");
631 dmg = 0;
633 if (Slimed) {
634 pline("The slime is burned away!");
635 Slimed =0;
637 burn_away_slime();
638 break;
639 case AD_COLD:
640 pline("You're covered in frost.");
641 if((Cold_resistance && rn2(StrongCold_resistance ? 20 : 5)) || ColdImmunity ) {
642 shieldeff(u.ux, u.uy);
643 pline("But you resist the effects.");
644 dmg = 0;
646 break;
647 case AD_ACID:
648 pline("You're covered in acid.");
649 if((Acid_resistance && rn2(StrongAcid_resistance ? 20 : 5)) || AcidImmunity) {
650 shieldeff(u.ux, u.uy);
651 pline("But you resist the effects.");
652 dmg = 0;
654 break;
655 case AD_ELEC:
656 pline("You're shocked.");
657 if((Shock_resistance && rn2(StrongShock_resistance ? 20 : 5)) || ShockImmunity ) {
658 shieldeff(u.ux, u.uy);
659 pline("But you resist the effects.");
660 dmg = 0;
662 break;
663 case AD_DRST:
664 pline("You're poisoned.");
665 if(Poison_resistance && rn2(StrongPoison_resistance ? 20 : 5) ) {
666 shieldeff(u.ux, u.uy);
667 pline("But you resist the effects.");
668 dmg = 0;
670 break;
671 case AD_LITE:
672 pline("You're irradiated by light.");
674 if (uarmh && uarmh->oartifact == ART_SECURE_BATHMASTER && rn2(20) ) {
675 shieldeff(u.ux, u.uy);
676 pline("But you resist the effects.");
677 dmg = 0;
678 } else if (maybe_polyd(is_vampire(youmonst.data), Race_if(PM_VAMPIRE)) || Role_if(PM_GOFF) ) {
679 dmg *= 2; /* vampires are susceptible to sunlight --Amy */
680 pline("Your pale skin is seared!");
682 break;
683 case AD_SPC2:
684 if ((Psi_resist && rn2(StrongPsi_resist ? 100 : 20)) || obsidianprotection()) {
685 shieldeff(u.ux, u.uy);
686 pline("Something focuses on your mind, but you resist the effects.");
687 dmg = 0;
688 break;
691 pline("Your %s spins wildly.", body_part(HEAD) );
693 switch (rnd(10)) {
695 case 1:
696 case 2:
697 case 3:
698 make_confused(HConfusion + dmg, FALSE);
699 break;
700 case 4:
701 case 5:
702 case 6:
703 make_stunned(HStun + dmg, FALSE);
704 break;
705 case 7:
706 make_confused(HConfusion + dmg, FALSE);
707 make_stunned(HStun + dmg, FALSE);
708 break;
709 case 8:
710 make_hallucinated(HHallucination + dmg, FALSE, 0L);
711 break;
712 case 9:
713 make_feared(HFeared + dmg, FALSE);
714 break;
715 case 10:
716 make_numbed(HNumbed + dmg, FALSE);
717 break;
720 if (!rn2(200)) {
721 forget(rnd(5), FALSE);
722 pline("You forget some important things...");
724 if (!rn2(200)) {
725 losexp("psionic drain", FALSE, TRUE);
727 if (!rn2(200)) {
728 adjattrib(A_INT, -1, 1, TRUE);
729 adjattrib(A_WIS, -1, 1, TRUE);
731 if (!rn2(200)) {
732 pline("You scream in pain!");
733 wake_nearby();
735 if (!rn2(200)) {
736 badeffect();
738 if (!rn2(5)) increasesanity(rnz(5));
740 break;
741 case AD_DISN:
742 verbalize("Avada Kedavra!");
743 if((Antimagic && rn2(StrongAntimagic ? 20 : 5) ) || nonliving(youmonst.data) || is_demon(youmonst.data) || Death_resistance || Invulnerable || ((PlayerInBlockHeels || PlayerInWedgeHeels) && tech_inuse(T_EXTREME_STURDINESS) && !rn2(2) ) || (StrongWonderlegs && !rn2(10) && Wounded_legs) || (Stoned_chiller && Stoned && !(u.stonedchilltimer) && !rn2(3)) ) {
744 shieldeff(u.ux, u.uy);
745 pline("But you resist the effects.");
746 dmg = 0;
748 else if (!PlayerResistsDeathRays && !rn2(20)) {
749 u.youaredead = 1;
750 killer_format = KILLED_BY_AN;
751 killer = "Avada Kedavra curse";
752 done(DIED);
753 u.youaredead = 0;
754 return 1; /* lifesaved */
756 break;
757 case AD_MAGM:
758 You("are hit by a shower of missiles!");
759 if(Antimagic && !Race_if(PM_KUTAR) && rn2(StrongAntimagic ? 20 : 5) ) {
760 shieldeff(u.ux, u.uy);
761 pline_The("missiles bounce off!");
762 dmg = 0;
764 break;
765 case AD_SPEL: /* wizard spell */
766 case AD_CLRC: /* clerical spell */
768 if (spellcasttype == AD_SPEL)
769 cast_wizard_spell(mtmp, dmg, spellnum);
770 else
771 cast_cleric_spell(mtmp, dmg, spellnum);
772 dmg = 0; /* done by the spell casting functions */
773 break;
775 case AD_CAST: /* clerical spell */
777 if ((moves % 4 == 0) || ((moves + 1) % 4 == 0))
778 cast_cleric_spell(mtmp, dmg, spellnum);
779 else
780 cast_wizard_spell(mtmp, dmg, spellnum);
781 dmg = 0; /* done by the spell casting functions */
782 break;
785 if(dmg) mdamageu(mtmp, dmg);
786 return(ret);
790 /* monster wizard and cleric spellcasting functions */
792 If dmg is zero, then the monster is not casting at you.
793 If the monster is intentionally not casting at you, we have previously
794 called spell_would_be_useless() and spellnum should always be a valid
795 undirected spell.
796 If you modify either of these, be sure to change is_undirected_spell()
797 and spell_would_be_useless().
799 STATIC_OVL
800 void
801 cast_wizard_spell(mtmp, dmg, spellnum)
802 struct monst *mtmp;
803 int dmg;
804 int spellnum;
807 struct monst* mtmp2;
808 int seen,count;
809 struct edog* edog;
810 struct obj *otmp;
812 if (dmg == 0 && !is_undirected_spell(AD_SPEL, spellnum)) {
813 impossible("cast directed wizard spell (%d) with dmg=0?", spellnum);
814 return;
817 switch (spellnum) {
818 case MGC_DEATH_TOUCH:
819 pline("Oh no, %s's using the touch of death!", mhe(mtmp));
820 if (nonliving(youmonst.data) || is_demon(youmonst.data) || Death_resistance) {
821 You("seem no deader than before.");
822 } else if ((!Antimagic || rn2(StrongAntimagic ? 20 : 5)) && rn2(mtmp->m_lev) > 12) {
823 if (Hallucination) {
824 You("have an out of body experience.");
825 } else if (!rnd(50) && !Antimagic) {
826 u.youaredead = 1;
827 killer_format = KILLED_BY_AN;
828 killer = "touch of death";
829 done(DIED);
830 u.youaredead = 0;
831 } else {
832 dmg = d(8,6);
833 /* Magic resistance or half spell damage will cut this in half... */
834 /* and also prevent a reduction of maximum hit points */
835 if (Antimagic || (Half_spell_damage && rn2(2)) || (StrongHalf_spell_damage && rn2(2)) ) {
836 shieldeff(u.ux, u.uy);
837 dmg /= 2;
838 u.uhpmax -= dmg/2;
839 if (u.uhp > u.uhpmax) u.uhp = u.uhpmax;
840 You_feel("a loss of life.");
841 losehp(dmg,"touch of death",KILLED_BY_AN);
843 else {
844 You_feel("drained...");
845 if (PlayerHearsSoundEffects) pline(issoviet ? "Vy odin shag blizhe k provalu v nastoyashcheye vremya. Pozdravleniya." : "Doaing!");
846 u.uhpmax -= dmg/2;
847 if (u.uhp > u.uhpmax) u.uhp = u.uhpmax;
848 losehp(dmg,"touch of death",KILLED_BY_AN); }
850 /*{pline("Whew! That could have been your demise.");*/
852 } else {
853 if (Antimagic) shieldeff(u.ux, u.uy);
854 pline("Lucky for you, it didn't work!");
856 dmg = 0;
857 break;
858 case MGC_CREATE_POOL:
859 if (levl[u.ux][u.uy].typ == ROOM || levl[u.ux][u.uy].typ == CORR) {
860 pline(FunnyHallu ? "Huh - the ground suddenly turned into a swimming pool!" : "A pool appears beneath you!");
861 levl[u.ux][u.uy].typ = POOL;
862 del_engr_at(u.ux, u.uy);
863 water_damage(level.objects[u.ux][u.uy], FALSE, TRUE);
864 spoteffects(FALSE); /* possibly drown, notice objects */
866 else
867 impossible("bad pool creation?");
868 dmg = 0;
869 break;
871 case MGC_MEGALOAD:
872 if (MysteryResist && rn2(2)) {
873 dmg = 0;
874 You("resist the megaload spell!");
875 break;
877 if (chitinprotection() && rn2(2)) {
878 dmg = 0;
879 You("resist the megaload spell!");
880 break;
882 if (StrongMysteryResist && rn2(2)) {
883 dmg = 0;
884 You("resist the megaload spell!");
885 break;
888 if ((otmp = mksobj(LOADSTONE, TRUE, FALSE, FALSE)) != (struct obj *)0) {
889 pline(FunnyHallu ? "Aww, something's killing your good feelings!" : "You feel burdened");
890 otmp->quan = 1;
891 otmp->owt = weight(otmp);
892 if (pickup_object(otmp, 1, FALSE, TRUE) <= 0) {
893 obj_extract_self(otmp);
894 place_object(otmp, u.ux, u.uy);
895 newsym(u.ux, u.uy); }
898 dmg = 0;
899 break;
901 case MGC_LEVITATE:
902 pline(FunnyHallu ? "Wow... you're suddenly walking on air!" : "You float up!");
903 HLevitation &= ~I_SPECIAL;
904 incr_itimeout(&HLevitation, rnz(50));
906 dmg = 0;
907 break;
909 case MGC_CLONE_WIZ:
910 if (mtmp->iswiz && (flags.no_of_wizards == 1 || !rn2(20)) ) { /* let's have a small chance of triple trouble --Amy */
911 if (flags.no_of_wizards == 1) pline(FunnyHallu ? "Doublevision!" : "Double Trouble...");
912 else pline(FunnyHallu ? "Triplevision!" : "Triple Trouble...");
913 clonewiz();
914 dmg = 0;
915 } else
916 pline(FunnyHallu ? "For a moment you had triplevision, but seeing double is funny enough." : "For a moment you saw another Wizard, but it disappeared.");
917 break;
918 case MGC_SUMMON_MONS:
920 int count;
922 count = nasty(mtmp); /* summon something nasty */
923 if (mtmp->iswiz)
924 verbalize("Destroy the thief, my pet%s!", plur(count));
925 else {
926 const char *mappear =
927 (count == 1) ? "A monster appears" : "Monsters appear";
929 /* messages not quite right if plural monsters created but
930 only a single monster is seen */
931 if (Invisible && !perceives(mtmp->data) && (StrongInvis || !rn2(3)) &&
932 (mtmp->mux != u.ux || mtmp->muy != u.uy))
933 pline("%s around a spot near you!", mappear);
934 else if (Displaced && (StrongDisplaced || !rn2(3)) && (mtmp->mux != u.ux || mtmp->muy != u.uy))
935 pline("%s around your displaced image!", mappear);
936 else
937 pline("%s from nowhere!", mappear);
940 if (mtmp->data == &mons[PM_WOK]) {
941 int attempts = 0;
942 struct permonst *pm = 0;
944 if (Aggravate_monster) {
945 u.aggravation = 1;
946 reset_rndmonst(NON_PM);
949 newbossRLL:
950 do {
951 pm = rndmonst();
952 attempts++;
953 if (attempts && (attempts % 10000 == 0)) u.mondiffhack++;
954 if (!rn2(2000)) reset_rndmonst(NON_PM);
956 } while ( (!pm || (pm && !(pm->msound == MS_SUPERMAN ))) && attempts < 50000);
958 if (!pm && rn2(50) ) {
959 attempts = 0;
960 goto newbossRLL;
962 if (pm && !(pm->msound == MS_SUPERMAN) && rn2(50) ) {
963 attempts = 0;
964 goto newbossRLL;
967 if (pm) (void) makemon(pm, 0, 0, MM_ANGRY|MM_FRENZIED);
969 u.mondiffhack = 0;
970 u.aggravation = 0;
974 dmg = 0;
975 break;
977 case MGC_SUMMON_GHOST:
979 coord mm;
980 mm.x = u.ux;
981 mm.y = u.uy;
983 tt_mname(&mm, FALSE, 0); /* create player-monster ghosts */
984 if (mtmp->iswiz)
985 verbalize("Destroy the thief, my pets!");
986 else {
987 const char *mappear =
988 "Ghosts appear";
990 /* messages not quite right if plural monsters created but
991 only a single monster is seen */
992 if (Invisible && !perceives(mtmp->data) && (StrongInvis || !rn2(3)) &&
993 (mtmp->mux != u.ux || mtmp->muy != u.uy))
994 pline("%s around a spot near you!", mappear);
995 else if (Displaced && (StrongDisplaced || !rn2(3)) && (mtmp->mux != u.ux || mtmp->muy != u.uy))
996 pline("%s around your displaced image!", mappear);
997 else
998 pline("%s from nowhere!", mappear);
1000 dmg = 0;
1002 if (mtmp->data == &mons[PM_WOK]) {
1003 int attempts = 0;
1004 struct permonst *pm = 0;
1006 if (Aggravate_monster) {
1007 u.aggravation = 1;
1008 reset_rndmonst(NON_PM);
1011 newbossRLM:
1012 do {
1013 pm = rndmonst();
1014 attempts++;
1015 if (attempts && (attempts % 10000 == 0)) u.mondiffhack++;
1016 if (!rn2(2000)) reset_rndmonst(NON_PM);
1018 } while ( (!pm || (pm && !(pm->msound == MS_SUPERMAN ))) && attempts < 50000);
1020 if (!pm && rn2(50) ) {
1021 attempts = 0;
1022 goto newbossRLM;
1024 if (pm && !(pm->msound == MS_SUPERMAN) && rn2(50) ) {
1025 attempts = 0;
1026 goto newbossRLM;
1029 if (pm) (void) makemon(pm, 0, 0, MM_ANGRY|MM_FRENZIED);
1031 u.mondiffhack = 0;
1032 u.aggravation = 0;
1036 break;
1040 case MGC_CALL_UNDEAD:
1042 coord mm;
1043 mm.x = u.ux;
1044 mm.y = u.uy;
1045 pline("Undead creatures are called forth from the grave!");
1046 mkundead(&mm, FALSE, 0, FALSE);
1049 if (mtmp->data == &mons[PM_WOK]) {
1050 int attempts = 0;
1051 struct permonst *pm = 0;
1053 if (Aggravate_monster) {
1054 u.aggravation = 1;
1055 reset_rndmonst(NON_PM);
1058 newbossRLN:
1059 do {
1060 pm = rndmonst();
1061 attempts++;
1062 if (attempts && (attempts % 10000 == 0)) u.mondiffhack++;
1063 if (!rn2(2000)) reset_rndmonst(NON_PM);
1065 } while ( (!pm || (pm && !(pm->msound == MS_SUPERMAN ))) && attempts < 50000);
1067 if (!pm && rn2(50) ) {
1068 attempts = 0;
1069 goto newbossRLN;
1071 if (pm && !(pm->msound == MS_SUPERMAN) && rn2(50) ) {
1072 attempts = 0;
1073 goto newbossRLN;
1076 if (pm) (void) makemon(pm, 0, 0, MM_ANGRY|MM_FRENZIED);
1078 u.aggravation = 0;
1079 u.mondiffhack = 0;
1083 dmg = 0;
1084 break;
1085 case MGC_AGGRAVATION:
1086 You_feel("that monsters are aware of your presence.");
1087 if (PlayerHearsSoundEffects) pline(issoviet ? "Dazhe sovetskaya Pyat' Lo obostryayetsya v vashem nizkom igrovom masterstve." : "Woaaaaaah!");
1088 aggravate();
1089 dmg = 0;
1090 break;
1091 case MGC_CURSE_ITEMS:
1092 if (MysteryResist && !rn2(3)) {
1093 dmg = 0;
1094 You("resist the itemcursing spell!");
1095 break;
1097 if (chitinprotection() && !rn2(3)) {
1098 dmg = 0;
1099 You("resist the itemcursing spell!");
1100 break;
1102 if (StrongMysteryResist && !rn2(3)) {
1103 dmg = 0;
1104 You("resist the itemcursing spell!");
1105 break;
1107 You_feel("as if you need some help.");
1108 if (PlayerHearsSoundEffects) pline(issoviet ? "Vashe der'mo tol'ko chto proklinal." : "Woaaaaaa-AAAH!");
1109 rndcurse();
1110 dmg = 0;
1111 break;
1112 case MGC_DESTRY_ARMR:
1113 if (chitinprotection() && rn2(3)) {
1114 shieldeff(u.ux, u.uy);
1115 pline("A field of force surrounds you!");
1116 } else if (MysteryResist && rn2(StrongMysteryResist ? 9 : 3)) {
1117 shieldeff(u.ux, u.uy);
1118 pline("A field of force surrounds you!");
1119 } else if (Antimagic && rn2(StrongAntimagic ? 20 : 5)) {
1120 shieldeff(u.ux, u.uy);
1121 pline("A field of force surrounds you!");
1122 } else {
1124 struct obj *otmp2;
1126 otmp2 = some_armor(&youmonst);
1128 if (otmp2 && otmp2->blessed && rn2(5)) pline("Your body shakes violently!");
1129 else if (otmp2 && (otmp2->spe > 1) && (rn2(otmp2->spe)) ) pline("Your body shakes violently!");
1130 else if (otmp2 && otmp2->oartifact && rn2(20)) pline("Your body shakes violently!");
1131 else if (otmp2 && otmp2->greased) {
1132 pline("Your body shakes violently!");
1133 if (!rn2(2) || (isfriday && !rn2(2))) {
1134 pline_The("grease wears off.");
1135 otmp2->greased -= 1;
1136 update_inventory();
1140 else if (!otmp2) pline("Your skin itches.");
1141 else if(!destroy_arm(otmp2)) pline("Your skin itches.");
1143 dmg = 0;
1144 break;
1146 /* from Sporkhack */
1147 /* Inspire critters to fight a little more vigorously...
1149 * -- Peaceful critters may become hostile.
1150 * -- Hostile critters may become berserk.
1151 * -- Borderline tame critters, or tame critters
1152 * who have been treated poorly may ALSO become hostile!
1154 case MGC_ENRAGE:
1156 for (mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
1157 if (m_cansee(mtmp,mtmp2->mx,mtmp2->my) && rn2(3) &&
1158 mtmp2 != mtmp && distu(mtmp2->mx,mtmp2->my) < 16) {
1159 seen++;
1160 if (mtmp2->mtame) {
1161 edog = (mtmp2->isminion) ? 0 : EDOG(mtmp2);
1162 if (mtmp2->mtame <= /*3*/rnd(21) || (edog && edog->abuse >= /*5*/ rn2(6) )) {
1164 int untamingchance = 10;
1166 if (!(PlayerCannotUseSkills)) {
1167 switch (P_SKILL(P_PETKEEPING)) {
1168 default: untamingchance = 10; break;
1169 case P_BASIC: untamingchance = 9; break;
1170 case P_SKILLED: untamingchance = 8; break;
1171 case P_EXPERT: untamingchance = 7; break;
1172 case P_MASTER: untamingchance = 6; break;
1173 case P_GRAND_MASTER: untamingchance = 5; break;
1174 case P_SUPREME_MASTER: untamingchance = 4; break;
1178 if (untamingchance > rnd(10) && !(Role_if(PM_DRAGONMASTER) && uarms && Is_dragon_shield(uarms) && mtmp2->data->mlet == S_DRAGON) && !((rnd(30 - ACURR(A_CHA))) < 4) ) {
1180 mtmp2->mtame = mtmp2->mpeaceful = 0;
1181 if (mtmp2->mleashed) { m_unleash(mtmp2,FALSE); }
1182 count++;
1186 } else if (mtmp2->mpeaceful && !is_infrastructure_monster(mtmp2)) {
1187 mtmp2->mpeaceful = 0;
1188 count++;
1189 } else {
1190 if (!is_infrastructure_monster(mtmp2)) {
1191 /*mtmp2->mberserk = 1;*/ /* removed because berserk doesn't exist in this fork */
1192 if (!rn2(5)) mtmp2->mfrenzied = 1; /* but we have something else instead now :D */
1193 mtmp2->mhp = mtmp2->mhpmax; /* let's heal them instead --Amy */
1194 count++;
1199 /* Don't yell if we didn't see anyone to yell at. */
1200 if (seen && (!rn2(3) || mtmp->iswiz)) {
1201 verbalize("Get %s, you fools, or I'll have your figgin on a stick!",uhim());
1203 if (count) {
1204 pline("It seems a little more dangerous here now...");
1205 if (!(InterfaceScrewed || u.uprops[INTERFACE_SCREW].extrinsic || have_interfacescrewstone())) doredraw();
1207 dmg = 0;
1208 break;
1210 case MGC_DIVINE_WRATH: /* new idea by Amy. Yes, this is very evil. :D */
1212 if (chitinprotection() && !rn2(2)) {
1213 dmg = 0;
1214 You("resist the divine wrath spell!");
1215 break;
1217 if (MysteryResist && !rn2(2)) {
1218 dmg = 0;
1219 You("resist the divine wrath spell!");
1220 break;
1222 if (StrongMysteryResist && !rn2(2)) {
1223 dmg = 0;
1224 You("resist the divine wrath spell!");
1225 break;
1228 u.ugangr++;
1229 if (!rn2(5)) u.ugangr++;
1230 if (!rn2(25)) u.ugangr++;
1231 prayer_done();
1233 dmg = 0;
1234 break;
1236 case MGC_WITHER:
1237 if (chitinprotection() && rn2(3)) {
1238 shieldeff(u.ux, u.uy);
1239 pline("A field of force surrounds you!");
1240 } else if (MysteryResist && rn2(StrongMysteryResist ? 5 : 3)) {
1241 shieldeff(u.ux, u.uy);
1242 pline("A field of force surrounds you!");
1243 } else if (Antimagic && rn2(StrongAntimagic ? 5 : 3)) {
1244 shieldeff(u.ux, u.uy);
1245 pline("A field of force surrounds you!");
1246 } else {
1247 pline("You sense a sinister feeling of loss!");
1249 while (1) {
1250 switch(rn2(5)) {
1251 case 0:
1252 if (!uarmh || !wither_dmg(uarmh, xname(uarmh), rn2(4), FALSE, &youmonst))
1253 continue;
1254 break;
1255 case 1:
1256 if (uarmc) {
1257 (void)wither_dmg(uarmc, xname(uarmc), rn2(4), TRUE, &youmonst);
1258 break;
1260 /* Note the difference between break and continue;
1261 * break means it was hit and didn't rust; continue
1262 * means it wasn't a target and though it didn't rust
1263 * something else did.
1265 if (uarm)
1266 (void)wither_dmg(uarm, xname(uarm), rn2(4), TRUE, &youmonst);
1267 else if (uarmu)
1268 (void)wither_dmg(uarmu, xname(uarmu), rn2(4), TRUE, &youmonst);
1269 break;
1270 case 2:
1271 if (!uarms || !wither_dmg(uarms, xname(uarms), rn2(4), FALSE, &youmonst))
1272 continue;
1273 break;
1274 case 3:
1275 if (!uarmg || !wither_dmg(uarmg, xname(uarmg), rn2(4), FALSE, &youmonst))
1276 continue;
1277 break;
1278 case 4:
1279 if (!uarmf || !wither_dmg(uarmf, xname(uarmf), rn2(4), FALSE, &youmonst))
1280 continue;
1281 break;
1283 break; /* Out of while loop */
1286 dmg = 0;
1287 break;
1288 case MGC_DAMAGE_ARMR:
1289 if (chitinprotection() && rn2(3)) {
1290 shieldeff(u.ux, u.uy);
1291 pline("A field of force surrounds you!");
1292 } else if (MysteryResist && rn2(StrongMysteryResist ? 5 : 3)) {
1293 shieldeff(u.ux, u.uy);
1294 pline("A field of force surrounds you!");
1295 } else if (Antimagic && rn2(StrongAntimagic ? 5 : 3)) {
1296 shieldeff(u.ux, u.uy);
1297 pline("A field of force surrounds you!");
1298 } else {
1299 pline("Your body shakes!");
1301 while (1) {
1302 switch(rn2(5)) {
1303 case 0:
1305 if (evilfriday && uarmh && uarmh->oerodeproof) {
1306 uarmh->oerodeproof = 0;
1307 pline("Harharhar, your helmet is no longer erosionproof!");
1310 if (!uarmh || !rust_dmg(uarmh, xname(uarmh), rn2(4), FALSE, &youmonst))
1311 continue;
1312 break;
1313 case 1:
1314 if (uarmc) {
1316 if (evilfriday && uarmc && uarmc->oerodeproof) {
1317 uarmc->oerodeproof = 0;
1318 pline("Harharhar, your cloak is no longer erosionproof!");
1321 (void)rust_dmg(uarmc, xname(uarmc), rn2(4), TRUE, &youmonst);
1322 break;
1324 /* Note the difference between break and continue;
1325 * break means it was hit and didn't rust; continue
1326 * means it wasn't a target and though it didn't rust
1327 * something else did.
1329 if (uarm) {
1331 if (evilfriday && uarm && uarm->oerodeproof) {
1332 uarm->oerodeproof = 0;
1333 pline("Harharhar, your armor is no longer erosionproof!");
1336 (void)rust_dmg(uarm, xname(uarm), rn2(4), TRUE, &youmonst);
1337 } else if (uarmu) {
1339 if (evilfriday && uarmu && uarmu->oerodeproof) {
1340 uarmu->oerodeproof = 0;
1341 pline("Harharhar, your shirt is no longer erosionproof!");
1344 (void)rust_dmg(uarmu, xname(uarmu), rn2(4), TRUE, &youmonst);
1346 break;
1347 case 2:
1349 if (evilfriday && uarms && uarms->oerodeproof) {
1350 uarms->oerodeproof = 0;
1351 pline("Harharhar, your shield is no longer erosionproof!");
1354 if (!uarms || !rust_dmg(uarms, xname(uarms), rn2(4), FALSE, &youmonst))
1355 continue;
1356 break;
1357 case 3:
1359 if (evilfriday && uarmg && uarmg->oerodeproof) {
1360 uarmg->oerodeproof = 0;
1361 pline("Harharhar, your gloves are no longer erosionproof!");
1364 if (!uarmg || !rust_dmg(uarmg, xname(uarmg), rn2(4), FALSE, &youmonst))
1365 continue;
1366 break;
1367 case 4:
1369 if (evilfriday && uarmf && uarmf->oerodeproof) {
1370 uarmf->oerodeproof = 0;
1371 pline("Harharhar, your boots are no longer erosionproof!");
1374 if (!uarmf || !rust_dmg(uarmf, xname(uarmf), rn2(4), FALSE, &youmonst))
1375 continue;
1376 break;
1378 break; /* Out of while loop */
1381 dmg = 0;
1382 break;
1383 case MGC_WEAKEN_YOU: /* drain strength */
1384 if (chitinprotection() && rn2(3)) {
1385 shieldeff(u.ux, u.uy);
1386 You_feel("momentarily weakened.");
1387 } else if (MysteryResist && rn2(StrongMysteryResist ? 9 : 3)) {
1388 shieldeff(u.ux, u.uy);
1389 You_feel("momentarily weakened.");
1390 } else if (Antimagic && rn2(StrongAntimagic ? 20 : 5)) {
1391 shieldeff(u.ux, u.uy);
1392 You_feel("momentarily weakened.");
1393 } else {
1394 if (issoviet) pline("Vy chuvstvuyete sebya slabeye! Iosif Putin reshil, chto lyudi boryutsya protiv rezhima, dolzhny byt' nakazany i sovetskiy Pyat' Lo soglasilsya s nim!");
1395 else You("suddenly feel weaker!");
1396 if (PlayerHearsSoundEffects) pline(issoviet ? "Pochemu vy ne sledite luchshe dlya vashikh atributov, tak ili inache?" : "Due-l-ue-l-ue-l!");
1397 dmg = rnd(mtmp->m_lev - 5); /* nerf by Amy - why did this always do the maximum amount??? */
1398 if (issoviet) dmg = mtmp->m_lev - rnd(5);
1399 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1400 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1401 losestr(rnd(dmg), TRUE);
1402 if (u.uhp < 1)
1403 done_in_by(mtmp);
1405 dmg = 0;
1406 break;
1407 case MGC_DISAPPEAR: /* makes self invisible */
1408 if (!mtmp->minvis && !mtmp->invis_blkd) {
1409 if (canseemon(mtmp))
1410 pline("%s suddenly %s!", Monnam(mtmp), !See_invisible ? "disappears" : "becomes transparent");
1411 mon_set_minvis(mtmp);
1412 dmg = 0;
1413 } else
1414 impossible("no reason for monster to cast disappear spell?");
1415 break;
1416 case MGC_NUMB_YOU:
1417 if (Antimagic && rn2(StrongAntimagic ? 3 : 2)) {
1418 shieldeff(u.ux, u.uy);
1419 if (!Numbed)
1420 You_feel("numb for a moment.");
1421 make_numbed(1L, FALSE);
1422 } else {
1423 You(Numbed ? "feel even more numb!" : "feel numb!");
1424 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1425 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1426 make_numbed(HNumbed + dmg, FALSE);
1428 dmg = 0;
1429 break;
1430 case MGC_BURN_YOU:
1431 if (Antimagic && rn2(StrongAntimagic ? 3 : 2)) {
1432 shieldeff(u.ux, u.uy);
1433 if (!Burned)
1434 You_feel("ablaze for a moment.");
1435 make_burned(1L, FALSE);
1436 } else {
1437 You(Burned ? "are burning more strongly!" : "are burning!");
1438 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1439 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1440 make_burned(HBurned + dmg, FALSE);
1442 dmg = 0;
1443 break;
1444 case MGC_STUN_YOU:
1445 if ((Antimagic || Free_action) && rn2((StrongAntimagic || StrongFree_action) ? 20 : 5)) {
1446 shieldeff(u.ux, u.uy);
1447 if (!Stunned)
1448 You_feel("momentarily disoriented.");
1449 make_stunned(1L, FALSE);
1450 } else {
1451 You(Stunned ? "struggle to keep your balance." : "reel...");
1452 dmg = d(ACURR(A_DEX) < 12 ? 6 : 4, 4);
1453 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1454 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1455 make_stunned(HStun + dmg, FALSE);
1457 dmg = 0;
1458 break;
1459 case MGC_HASTE_SELF:
1460 mon_adjust_speed(mtmp, 1, (struct obj *)0);
1461 dmg = 0;
1462 break;
1463 case MGC_CURE_SELF:
1464 if (mtmp->mhp < mtmp->mhpmax) {
1465 int healamount;
1466 if (canseemon(mtmp))
1467 pline("%s looks better.", Monnam(mtmp));
1468 /* note: player healing does 6d4; this used to do 1d8 */
1469 /* Amy note: boosted it so that it's no longer completely useless */
1470 healamount = d(3,6) + rnz(1 + mtmp->m_lev);
1471 if ((mtmp->mhp += healamount) > mtmp->mhpmax)
1472 mtmp->mhp = mtmp->mhpmax;
1474 if (mtmp->bleedout && mtmp->bleedout <= healamount) {
1475 mtmp->bleedout = 0;
1476 pline("%s's bleeding stops.", Monnam(mtmp));
1477 } else if (mtmp->bleedout) {
1478 mtmp->bleedout -= healamount;
1479 if (mtmp->bleedout < 0) mtmp->bleedout = 0; /* should never happen */
1480 pline("%s's bleeding diminishes.", Monnam(mtmp));
1483 dmg = 0;
1485 break;
1486 case MGC_PSI_BOLT:
1488 if (!rn2(500 - (mtmp->m_lev * 2) )) { /* wishing */
1490 switch (rnd(6)) {
1491 case 1:
1492 (void) mongets(mtmp, rnd_defensive_item(mtmp));
1493 break;
1494 case 2:
1495 (void) mongets(mtmp, rnd_offensive_item(mtmp));
1496 break;
1497 case 3:
1498 (void) mongets(mtmp, rnd_misc_item(mtmp));
1499 break;
1500 case 4:
1501 (void) mongets(mtmp, rnd_defensive_item_new(mtmp));
1502 break;
1503 case 5:
1504 (void) mongets(mtmp, rnd_offensive_item_new(mtmp));
1505 break;
1506 case 6:
1507 (void) mongets(mtmp, rnd_misc_item_new(mtmp));
1508 break;
1510 pline("%s wishes for an object.", Monnam(mtmp) );
1512 break;
1515 if (!rn2(400 - (mtmp->m_lev * 2) )) { /* summon boss */
1517 if (Aggravate_monster) {
1518 u.aggravation = 1;
1519 reset_rndmonst(NON_PM);
1522 { coord cc;
1523 struct permonst *pm = 0;
1524 struct monst *mon;
1525 int attempts = 0;
1527 if (!enexto(&cc, mtmp->mx, mtmp->my, 0)) break;
1529 newboss:
1530 do {
1531 pm = rndmonst();
1532 attempts++;
1533 if (attempts && (attempts % 10000 == 0)) u.mondiffhack++;
1534 if (!rn2(2000)) reset_rndmonst(NON_PM);
1536 } while ( (!pm || (pm && !(pm->geno & G_UNIQ))) && attempts < 50000);
1538 if (!pm && rn2(50) ) {
1539 attempts = 0;
1540 goto newboss;
1542 if (pm && !(pm->geno & G_UNIQ) && rn2(50) ) {
1543 attempts = 0;
1544 goto newboss;
1547 if (pm) mon = makemon(pm, cc.x, cc.y, NO_MM_FLAGS);
1550 pline("A boss monster appears from nowhere!");
1552 u.mondiffhack = 0;
1553 u.aggravation = 0;
1555 break;
1558 if (!rn2(300 - (mtmp->m_lev * 2) )) { /* bad effect */
1560 badeffect();
1562 break;
1565 /* prior to 3.4.0 Antimagic was setting the damage to 1--this
1566 made the spell virtually harmless to players with magic res. */
1567 if (Antimagic && !Race_if(PM_KUTAR) && rn2(StrongAntimagic ? 20 : 5)) {
1568 shieldeff(u.ux, u.uy);
1569 dmg = (dmg + 1) / 2;
1572 /* Amy change: half damage, but also increase sanity */
1573 if (dmg > 1) dmg /= 2;
1575 if (dmg <= 5)
1576 You("get a slight %sache.", body_part(HEAD));
1577 else if (dmg <= 10)
1578 Your("brain is on fire!");
1579 else if (dmg <= 20)
1580 Your("%s suddenly aches painfully!", body_part(HEAD));
1581 else
1582 Your("%s suddenly aches very painfully!", body_part(HEAD));
1584 if (!Psi_resist || !rn2(StrongPsi_resist ? 20 : 5) ) increasesanity(dmg);
1586 break;
1587 case MGC_ESCALATION:
1589 if (Antimagic && !Race_if(PM_KUTAR) && rn2(StrongAntimagic ? 20 : 5)) {
1590 shieldeff(u.ux, u.uy);
1591 dmg = (dmg + 1) / 2;
1593 dmg += u.chokhmahdamage;
1595 u.chokhmahdamage++;
1597 if (dmg <= 5)
1598 You("get a %sache.", body_part(HEAD));
1599 else if (dmg <= 10)
1600 Your("brain is on fire, and the pain seems to be getting stronger!");
1601 else if (dmg <= 20)
1602 Your("%s suddenly aches really painfully!", body_part(HEAD));
1603 else
1604 Your("%s suddenly aches extremely painfully!", body_part(HEAD));
1605 break;
1607 break;
1609 default:
1610 impossible("mcastu: invalid magic spell (%d)", spellnum);
1611 dmg = 0;
1612 break;
1615 if (dmg) mdamageu(mtmp, dmg);
1618 STATIC_OVL
1619 void
1620 cast_cleric_spell(mtmp, dmg, spellnum)
1621 struct monst *mtmp;
1622 int dmg;
1623 int spellnum;
1625 int aligntype;
1626 int oldhp, oldmp, oldhpmax, oldmpmax;
1628 if (dmg == 0 && !is_undirected_spell(AD_CLRC, spellnum)) {
1629 impossible("cast directed cleric spell (%d) with dmg=0?", spellnum);
1630 return;
1633 switch (spellnum) {
1634 case CLC_GEYSER:
1636 switch (rnd(40) ) {
1637 case 1:
1638 case 2:
1639 case 3:
1640 case 4:
1641 case 5:
1642 case 6:
1643 case 7:
1644 case 8:
1645 case 9:
1646 case 10:
1647 case 11:
1648 case 12:
1649 case 13:
1650 case 14:
1651 case 15:
1652 case 16:
1653 case 17:
1654 case 18:
1655 case 19:
1657 /* this is physical damage, not magical damage */
1658 pline("A sudden geyser slams into you from nowhere!");
1659 if (PlayerHearsSoundEffects) pline(issoviet ? "Teper' vse promokli. Vy zhe pomnite, chtoby polozhit' vodu chuvstvitel'nyy material v konteyner, ne tak li?" : "Schwatschhhhhh!");
1660 if (uwep && uwep->otyp == UMBRELLA && rn2(2)) {
1661 pline("But your umbrella protects you from it.");
1662 break;
1664 dmg = d(8, 6);
1665 if ((!StrongSwimming || !rn2(10)) && (!StrongMagical_breathing || !rn2(10))) {
1666 water_damage(invent, FALSE, FALSE); /* Come on, every other source of water rusts your stuff. --Amy */
1667 if (level.flags.lethe) lethe_damage(invent, FALSE, FALSE);
1669 if (Burned) make_burned(0L, TRUE); /* you're enveloped in water, so the burn disappears */
1670 if (Half_physical_damage && (rn2(2) || (uwep && uwep->oartifact == ART_SOOTHE_)) ) dmg = (dmg + 1) / 2;
1671 if (StrongHalf_physical_damage && (rn2(2) || (uwep && uwep->oartifact == ART_SOOTHE_)) ) dmg = (dmg + 1) / 2;
1672 break;
1674 case 20:
1675 /* antimatter storm --Amy */
1677 if (chitinprotection() && rn2(2)) {
1678 dmg = 0;
1679 You("resist the antimatter spell!");
1680 break;
1682 if (MysteryResist && rn2(2)) {
1683 dmg = 0;
1684 You("resist the antimatter spell!");
1685 break;
1687 if (StrongMysteryResist && rn2(2)) {
1688 dmg = 0;
1689 You("resist the antimatter spell!");
1690 break;
1693 pline("You are caught in an antimatter storm!");
1694 dmg = d(8, 6);
1695 withering_damage(invent, FALSE, FALSE); /* This can potentially damage all of your inventory items. --Amy */
1696 if (Half_physical_damage && (rn2(2) || (uwep && uwep->oartifact == ART_SOOTHE_)) ) dmg = (dmg + 1) / 2;
1697 if (StrongHalf_physical_damage && (rn2(2) || (uwep && uwep->oartifact == ART_SOOTHE_)) ) dmg = (dmg + 1) / 2;
1699 break;
1701 case 21:
1702 case 22:
1703 case 23:
1704 case 24:
1705 case 25:
1707 if (chitinprotection() && rn2(2)) {
1708 dmg = 0;
1709 You("resist the petrify spell!");
1710 break;
1712 if (MysteryResist && rn2(2)) {
1713 dmg = 0;
1714 You("resist the petrify spell!");
1715 break;
1717 if (StrongMysteryResist && rn2(2)) {
1718 dmg = 0;
1719 You("resist the petrify spell!");
1720 break;
1723 /* petrify - similar to cockatrice hissing --Amy */
1724 You_feel("a massive burden on your chest!");
1725 if (!Stoned && (!Stone_resistance || (!IntStone_resistance && !rn2(20)) ) && !(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) ) {
1726 if (Hallucination && rn2(10)) pline("Good thing you are already stoned.");
1727 else {
1728 You("start turning to stone!");
1729 Stoned = Race_if(PM_EROSATOR) ? 3 : 7;
1730 u.cnd_stoningcount++;
1731 stop_occupation();
1732 delayed_killer = "petrify spell";
1735 dmg = 0;
1736 break;
1738 case 26:
1739 case 27:
1740 case 28:
1741 case 29:
1742 case 30:
1744 if (chitinprotection() && rn2(2)) {
1745 dmg = 0;
1746 You("resist the sliming spell!");
1747 break;
1749 if (MysteryResist && rn2(2)) {
1750 dmg = 0;
1751 You("resist the sliming spell!");
1752 break;
1754 if (StrongMysteryResist && rn2(2)) {
1755 dmg = 0;
1756 You("resist the sliming spell!");
1757 break;
1760 /* sliming - similar to green slime attack --Amy */
1761 if (!Slimed && !flaming(youmonst.data) && !Unchanging && !slime_on_touch(youmonst.data) ) {
1762 You("don't feel very well.");
1763 stop_occupation();
1764 make_slimed(100);
1765 killer_format = KILLED_BY_AN;
1766 delayed_killer = "slimed by a monster spell";
1768 dmg = 0;
1769 break;
1771 case 31:
1772 case 32:
1773 case 33:
1774 case 34:
1775 case 35:
1776 case 36:
1777 case 37:
1779 /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
1780 aligntype = rn2((int)A_LAWFUL+2) - 1;
1781 pline("A servant of %s appears!",aligns[1 - aligntype].noun); /* summon elm, from sporkhack */
1782 summon_minion(aligntype, TRUE);
1783 dmg = 0;
1784 break;
1786 case 38:
1788 if (chitinprotection() && rn2(2)) {
1789 dmg = 0;
1790 You("resist the amnesia spell!");
1791 break;
1793 if (MysteryResist && rn2(2)) {
1794 dmg = 0;
1795 You("resist the amnesia spell!");
1796 break;
1798 if (StrongMysteryResist && rn2(2)) {
1799 dmg = 0;
1800 You("resist the amnesia spell!");
1801 break;
1804 /* amnesia - evil patch idea by jonadab */
1805 forget(3, FALSE);
1807 if (!strncmpi(plname, "Maud", 4) || !strncmpi(plalias, "Maud", 4))
1808 pline("As your mind turns inward on itself, you forget everything else.");
1809 else if (rn2(2))
1810 pline("Who was that Maud person anyway?");
1811 else
1812 pline("Thinking of Maud you forget everything else.");
1815 break;
1817 case 39:
1819 /* wraparound - evil patch idea */
1820 oldhp = u.uhp;
1821 oldmp = u.uen;
1822 oldhpmax = u.uhpmax;
1823 oldmpmax = u.uenmax;
1825 u.uen = oldhp;
1826 u.uhp = oldmp;
1827 u.uenmax = oldhpmax;
1828 u.uhpmax = oldmpmax;
1829 You_feel("a wraparound!");
1830 break;
1832 case 40:
1834 /* translucency - makes the player's items visible */
1835 pline("You are surrounded by a translucent glow!");
1837 register struct obj *objX, *objX2;
1838 for (objX = invent; objX; objX = objX2) {
1839 objX2 = objX->nobj;
1840 if (!rn2(5)) objX->oinvis = objX->oinvisreal = FALSE;
1844 break;
1846 default: /*failsafe*/
1847 You_feel("that monsters are aware of your presence."); /* aggravate monster */
1848 aggravate();
1849 dmg = 0;
1850 break;
1852 break;
1854 case CLC_FIRE_PILLAR:
1855 pline("A pillar of fire strikes all around you!");
1856 if (PlayerHearsSoundEffects) pline(issoviet ? "Gori detka gori!" : "Tschack-tschack-tschack-tschack-tschack");
1857 if ((Fire_resistance && rn2(StrongFire_resistance ? 20 : 5)) || FireImmunity) {
1858 shieldeff(u.ux, u.uy);
1859 dmg = 0;
1860 } else {
1861 dmg = d(8, 6);
1862 if (Race_if(PM_LOWER_ENT)) dmg *= 2;
1864 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1865 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1866 burn_away_slime();
1867 if (isevilvariant || !rn2(Race_if(PM_SEA_ELF) ? 1 : issoviet ? 2 : 33)) (void) burnarmor(&youmonst);
1868 if (isevilvariant || !rn2(Race_if(PM_SEA_ELF) ? 1 : issoviet ? 3 : 15)) /* new calculations --Amy */ destroy_item(SCROLL_CLASS, AD_FIRE);
1869 if (isevilvariant || !rn2(Race_if(PM_SEA_ELF) ? 1 : issoviet ? 3 : 15)) /* new calculations --Amy */ destroy_item(POTION_CLASS, AD_FIRE);
1870 if (isevilvariant || !rn2(Race_if(PM_SEA_ELF) ? 1 : issoviet ? 3 : 15)) /* new calculations --Amy */ destroy_item(SPBOOK_CLASS, AD_FIRE);
1871 (void) burn_floor_paper(u.ux, u.uy, TRUE, FALSE);
1872 break;
1873 case CLC_LIGHTNING:
1875 boolean reflects;
1877 /* WAC add lightning strike effect */
1878 zap_strike_fx(u.ux, u.uy, AD_ELEC - 1);
1879 pline("A bolt of lightning strikes down at you from above!");
1880 reflects = ureflects("It bounces off your %s%s.", "");
1881 if (!Blind) {
1882 pline("You are blinded by the flash!");
1883 make_blinded(StrongHalf_spell_damage ? 5L : Half_spell_damage ? 10L : 20L, FALSE);
1885 if (reflects || ShockImmunity || (Shock_resistance && (StrongShock_resistance || rn2(10))) ) {
1886 shieldeff(u.ux, u.uy);
1887 dmg = 0;
1888 if (reflects)
1889 break;
1890 } else
1891 dmg = d(8, 6);
1892 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1893 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
1894 if (isevilvariant || !rn2(issoviet ? 3 : 15)) /* new calculations --Amy */ destroy_item(WAND_CLASS, AD_ELEC);
1895 if (isevilvariant || !rn2(issoviet ? 3 : 15)) /* new calculations --Amy */ destroy_item(RING_CLASS, AD_ELEC);
1896 if (isevilvariant || !rn2(issoviet ? 15 : 75)) /* new calculations --Amy */ destroy_item(AMULET_CLASS, AD_ELEC);
1897 break;
1899 case CLC_CURSE_ITEMS:
1901 if (chitinprotection() && !rn2(3)) {
1902 dmg = 0;
1903 You("resist the itemcursing spell!");
1904 break;
1906 if (MysteryResist && !rn2(3)) {
1907 dmg = 0;
1908 You("resist the itemcursing spell!");
1909 break;
1911 if (StrongMysteryResist && !rn2(3)) {
1912 dmg = 0;
1913 You("resist the itemcursing spell!");
1914 break;
1917 You_feel("as if you need some help.");
1918 if (PlayerHearsSoundEffects) pline(issoviet ? "Vashe der'mo tol'ko chto proklinal." : "Woaaaaaa-AAAH!");
1919 rndcurse();
1920 dmg = 0;
1921 break;
1923 case CLC_AGGRAVATION: /* aggravate monster */
1924 You_feel("that monsters are aware of your presence."); /* aggravate monster */
1925 aggravate();
1926 if (PlayerHearsSoundEffects) pline(issoviet ? "Dazhe sovetskaya Pyat' Lo obostryayetsya v vashem nizkom igrovom masterstve." : "Woaaaaaah!");
1927 dmg = 0;
1928 break;
1930 case CLC_RANDOM: /* inofficial names see below */
1931 switch (rnd(40) ) {
1933 case 1:
1934 case 2:
1935 case 3:
1936 case 4:
1937 case 5:
1938 case 6:
1939 case 7:
1940 case 8:
1941 case 9:
1942 case 10:
1943 You_feel("a sense of intrinsic loss."); /* intrinsic loss */
1944 attrcurse();
1945 dmg = 0;
1946 break;
1947 case 11:
1948 case 12:
1949 case 13:
1950 case 14:
1951 case 15:
1952 case 16:
1953 case 17:
1954 case 18:
1955 case 19:
1956 case 20:
1957 You_feel("a dark aura."); /* dark aura */
1958 int rangeX;
1960 rangeX = (rnz(1 + mtmp->m_lev)) / 2;
1961 if (rn2(4)) rangeX = rangeX / 2;
1963 if (rangeX < 1) rangeX = 1; if (rangeX > 15) rangeX = 15;
1965 do_clear_areaX(u.ux,u.uy, /* darkness around player's position */
1966 /*15*/rangeX, set_litZ, (void *)((char *)0));
1967 wake_nearby();
1968 dmg = 0;
1969 break;
1970 case 21:
1971 case 22:
1972 case 23:
1973 You_feel("very trippy all of a sudden!"); /* acid trip */
1974 int duratX;
1975 duratX = (rnz(1 + mtmp->m_lev));
1976 make_hallucinated(HHallucination + duratX,FALSE,0L);
1977 dmg = 0;
1978 break;
1979 case 24:
1980 case 25:
1981 You_feel("endangered!!"); /* create traps */
1983 int rtrap;
1984 int i, j, bd;
1985 bd = 1;
1986 if (!rn2(5)) bd += rnz(1);
1987 boolean canbeinawall = FALSE;
1988 if (!rn2(Passes_walls ? 5 : 25)) canbeinawall = TRUE;
1990 for (i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) {
1991 if (!isok(u.ux + i, u.uy + j)) continue;
1992 if ((levl[u.ux + i][u.uy + j].typ <= DBWALL) && !canbeinawall) continue;
1993 if (t_at(u.ux + i, u.uy + j)) continue;
1995 rtrap = rndtrap();
1997 (void) maketrap(u.ux + i, u.uy + j, rtrap, 100, TRUE);
1999 dmg = 0;
2000 break;
2001 case 26:
2002 You_feel("yanked in a new direction!"); /* relocation */
2003 (void) safe_teleds_normalterrain(FALSE);
2004 dmg = 0;
2005 break;
2006 case 27:
2007 case 28:
2008 case 29:
2009 pline("Your mana is sapped!"); /* mana drain */
2010 int manastealX;
2011 manastealX = (rnz(1 + mtmp->m_lev));
2012 drain_en(manastealX);
2013 dmg = 0;
2014 break;
2015 case 30:
2016 You_feel("an ominous droning wind!"); /* disengrave */
2017 register struct engr *ep = engr_at(u.ux,u.uy);
2018 if (ep && sengr_at("Elbereth", u.ux, u.uy) ) {
2019 pline("Suddenly, the engraving beneath your feet smudges and dissolves!");
2020 del_engr(ep);
2021 ep = (struct engr *)0;
2023 dmg = 0;
2024 break;
2025 case 31:
2026 case 32:
2027 case 33:
2028 pline(FunnyHallu ? "You suddenly feel like you're on cold turkey!" : "Your hands start trembling!"); /* disarm */
2029 int glibberX;
2030 glibberX = (rnz(1 + mtmp->m_lev));
2031 incr_itimeout(&Glib, glibberX);
2032 dmg = 0;
2033 break;
2034 case 34:
2035 case 35:
2036 case 36:
2037 You_feel("pulsating winds!"); /* slow */
2038 u_slow_down();
2039 dmg = 0;
2040 break;
2041 case 37:
2042 pline(FunnyHallu ? "You feel like you just got dumped by your girlfriend!" : "You feel out of luck!"); /* dementor force */
2043 change_luck(-1);
2044 if (!rn2(10)) change_luck(-5);
2045 adjalign(-10);
2046 if (!rn2(10)) adjalign(-50);
2047 dmg = 0;
2048 break;
2049 case 38:
2050 You_feel("burdened"); /* punishment - message is from Castle of the Winds */
2051 punishx();
2052 dmg = 0;
2053 break;
2054 case 39:
2055 case 40:
2056 pushplayer(FALSE); /* use the force */
2057 break;
2058 default: /*failsafe*/
2059 You_feel("that monsters are aware of your presence."); /* aggravate monster */
2060 aggravate();
2061 if (PlayerHearsSoundEffects) pline(issoviet ? "Dazhe sovetskaya Pyat' Lo obostryayetsya v vashem nizkom igrovom masterstve." : "Woaaaaaah!");
2062 dmg = 0;
2063 break;
2067 break;
2069 case CLC_INSECTS:
2071 /* Try for insects, and if there are none
2072 left, go for (sticks to) snakes. -3. */
2073 struct permonst *pm = mkclass(S_ANT,0);
2074 struct monst *mtmp2 = (struct monst *)0;
2075 char let = (pm ? S_ANT : S_SNAKE);
2076 boolean success;
2077 int i;
2078 coord bypos;
2079 int quan;
2081 /* Let's allow some variation. Unofficial spell names for each type of creature see below. --Amy */
2083 if (!rn2(3)) { switch (rnd(54)) {
2085 case 1:
2086 case 2:
2087 case 3:
2088 case 4:
2089 case 5:
2090 case 6:
2091 case 7:
2092 case 8:
2093 case 9:
2094 case 10:
2095 let = S_SNAKE;
2096 break;
2097 case 11:
2098 case 12:
2099 case 13:
2100 case 14:
2101 case 15:
2102 let = S_MIMIC;
2103 break;
2104 case 16:
2105 case 17:
2106 case 18:
2107 case 19:
2108 case 20:
2109 let = S_NYMPH;
2110 break;
2111 case 21:
2112 case 22:
2113 case 23:
2114 let = S_PIERCER;
2115 break;
2116 case 24:
2117 case 25:
2118 case 26:
2119 case 27:
2120 case 28:
2121 let = S_RODENT;
2122 break;
2123 case 29:
2124 case 30:
2125 case 31:
2126 case 32:
2127 case 33:
2128 let = S_SPIDER;
2129 break;
2130 case 34:
2131 case 35:
2132 case 36:
2133 case 37:
2134 case 38:
2135 let = S_WORM;
2136 break;
2137 case 39:
2138 case 40:
2139 case 41:
2140 case 42:
2141 case 43:
2142 let = S_BAT;
2143 break;
2144 case 44:
2145 let = S_UMBER;
2146 break;
2147 case 45:
2148 case 46:
2149 let = S_HUMAN;
2150 break;
2151 case 47:
2152 case 48:
2153 let = S_GOLEM;
2154 break;
2155 case 49:
2156 case 50:
2157 case 51:
2158 let = S_EEL;
2159 break;
2160 case 52:
2161 case 53:
2162 case 54:
2163 let = S_BAD_FOOD;
2164 break;
2165 default: /* failsafe */
2166 let = S_ANT;
2167 break;
2173 quan = (mtmp->m_lev < 2) ? 1 : rnd((int)mtmp->m_lev / 2);
2174 if (rn2(3)) quan = (quan / 2);
2175 if (quan < 1) quan = 1;
2176 success = pm ? TRUE : FALSE;
2178 if (Aggravate_monster) {
2179 u.aggravation = 1;
2180 reset_rndmonst(NON_PM);
2183 for (i = 0; i <= quan; i++) {
2184 if (!enexto(&bypos, mtmp->mux, mtmp->muy, mtmp->data))
2185 break;
2186 if ((pm = mkclass(let,0)) != 0 &&
2187 (mtmp2 = makemon(pm, bypos.x, bypos.y, NO_MM_FLAGS)) != 0) {
2188 success = TRUE;
2189 mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0;
2190 set_malign(mtmp2);
2194 u.aggravation = 0;
2196 /* Not quite right:
2197 * -- message doesn't always make sense for unseen caster (particularly
2198 * the first message)
2199 * -- message assumes plural monsters summoned (non-plural should be
2200 * very rare, unlike in nasty())
2201 * -- message assumes plural monsters seen
2203 if (!success)
2204 pline("%s casts at a clump of sticks, but nothing happens.",
2205 Monnam(mtmp));
2206 else if (let == S_SNAKE) /* sticks to snakes */
2207 pline("%s transforms a clump of sticks into snakes!",
2208 Monnam(mtmp));
2209 else if (let == S_MIMIC) /* garbage spam */
2210 pline("%s conjures up random garbage!",
2211 Monnam(mtmp));
2212 else if (let == S_NYMPH) /* charming seduction */
2213 pline("%s summons some beautiful ladies!",
2214 Monnam(mtmp));
2215 else if (let == S_PIERCER) /* piercing ceiling */ {
2216 if (flags.soundok) You_hear("a shrill ringing sound.");
2217 } else if (let == S_RODENT) /* rat swarm */
2218 pline("%s summons rats!",
2219 Monnam(mtmp));
2220 else if (let == S_SPIDER) /* demonic spiders */
2221 pline("%s summons spiders!",
2222 Monnam(mtmp));
2223 else if (let == S_WORM) /* can of worms */
2224 pline("%s opens up a can of worms!",
2225 Monnam(mtmp));
2226 else if (let == S_BAT) /* flapping bats */
2227 pline("%s summons a bat swarm!",
2228 Monnam(mtmp));
2229 else if (let == S_UMBER) /* hulking brutes */
2230 pline("%s summons terrifying creatures!",
2231 Monnam(mtmp));
2232 else if (let == S_HUMAN) /* court summoning */
2233 pline("%s summons interesting people from around the world!",
2234 Monnam(mtmp));
2235 else if (let == S_GOLEM) /* golem mastery */
2236 pline("%s transforms a heap of junk into animated beings!",
2237 Monnam(mtmp));
2238 else if (let == S_EEL) /* deep sea trouble */
2239 pline("%s opens up a can of whoop-ass!",
2240 Monnam(mtmp));
2241 else if (let == S_BAD_FOOD) /* mystic nature */
2242 pline("%s summons mystic natures!",
2243 Monnam(mtmp));
2244 else if (Invisible && !perceives(mtmp->data) && (StrongInvis || !rn2(3)) &&
2245 (mtmp->mux != u.ux || mtmp->muy != u.uy))
2246 pline("%s summons insects around a spot near you!",
2247 Monnam(mtmp));
2248 else if (Displaced && (StrongDisplaced || !rn2(3)) && (mtmp->mux != u.ux || mtmp->muy != u.uy))
2249 pline("%s summons insects around your displaced image!",
2250 Monnam(mtmp));
2251 else
2252 pline("%s summons insects!", Monnam(mtmp));
2253 dmg = 0;
2254 break;
2256 case CLC_BLIND_YOU:
2257 /* note: resists_blnd() doesn't apply here */
2258 if (!Blinded) {
2259 int num_eyes = eyecount(youmonst.data);
2260 pline("Scales cover your %s!",
2261 (num_eyes == 1) ?
2262 body_part(EYE) : makeplural(body_part(EYE)));
2263 make_blinded(StrongHalf_spell_damage ? 50L : Half_spell_damage ? 100L : 200L, FALSE);
2264 if (!Blind) Your("%s", vision_clears);
2265 dmg = 0;
2266 } else
2267 impossible("no reason for monster to cast blindness spell?");
2268 break;
2269 case CLC_PARALYZE:
2270 if ((Antimagic || Free_action) && rn2((StrongAntimagic || StrongFree_action) ? 20 : 5)) {
2271 shieldeff(u.ux, u.uy);
2272 if (multi >= 0)
2273 You("stiffen briefly.");
2274 nomul(-1, "paralyzed by a monster spell", TRUE);
2275 } else {
2276 if (multi >= 0)
2277 You("are frozen in place!");
2278 if (PlayerHearsSoundEffects) pline(issoviet ? "Teper' vy ne mozhete dvigat'sya. Nadeyus', chto-to ubivayet vas, prezhde chem vash paralich zakonchitsya." : "Klltsch-tsch-tsch-tsch-tsch!");
2279 /* new calculations by Amy because otherwise this spell would be uber imba */
2280 if (!issoviet) dmg = rnd( 2 + (rn2(3) ? ((int)mtmp->m_lev / 2) : rn2(2) ? ((int)mtmp->m_lev / 4) : (int)mtmp->m_lev) ) ;
2281 else dmg = 4 + (int)mtmp->m_lev;;
2282 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
2283 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
2284 if (chitinprotection() && rn2(2) ) dmg = (dmg + 1) / 2;
2285 if (MysteryResist && rn2(2) ) dmg = (dmg + 1) / 2;
2286 if (StrongMysteryResist && rn2(2) ) dmg = (dmg + 1) / 2;
2287 if (issoviet) pline("Teper' vy mertvy. Sovetskaya smeyetsya, potomu chto vy, veroyatno, vlozhili dvesti chasov v etot kharakter.");
2288 nomul(-dmg, "paralyzed by a monster spell", TRUE);
2290 nomovemsg = 0;
2291 dmg = 0;
2292 break;
2293 case CLC_CONFUSE_YOU:
2294 if (Antimagic && rn2(StrongAntimagic ? 20 : 5)) {
2295 shieldeff(u.ux, u.uy);
2296 You_feel("momentarily dizzy.");
2297 } else {
2298 boolean oldprop = !!Confusion;
2300 dmg = (int)mtmp->m_lev;
2301 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
2302 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
2303 make_confused(HConfusion + dmg, TRUE);
2304 if (FunnyHallu)
2305 You_feel("%s!", oldprop ? "trippier" : "trippy");
2306 else
2307 You_feel("%sconfused!", oldprop ? "more " : "");
2309 dmg = 0;
2310 break;
2311 case CLC_FEAR_YOU:
2312 if (Antimagic && rn2(StrongAntimagic ? 3 : 2)) {
2313 shieldeff(u.ux, u.uy);
2314 if (!Feared)
2315 You_feel("afraid for a moment.");
2316 make_feared(1L, FALSE);
2317 } else {
2318 You(Feared ? "are even more scared!" : "are scared!");
2319 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
2320 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
2321 make_feared(HFeared + dmg, FALSE);
2323 dmg = 0;
2324 break;
2325 case CLC_FREEZE_YOU:
2326 if (Antimagic && rn2(StrongAntimagic ? 3 : 2)) {
2327 shieldeff(u.ux, u.uy);
2328 if (!Frozen)
2329 You_feel("frozen for a moment.");
2330 make_frozen(1L, FALSE);
2331 } else {
2332 You(Frozen ? "are freezing even more!" : "are freezing!");
2333 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
2334 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
2335 make_frozen(HFrozen + dmg, FALSE);
2337 dmg = 0;
2338 break;
2339 case CLC_SEPARATION:
2340 u.ublesscnt += (dmg * 10);
2341 pline(FunnyHallu ? "You feel sinful... but do you really care?" : "You have a feeling of separation.");
2342 dmg = 0;
2343 break;
2344 case CLC_STAT_DRAIN: /* drain a random stat */
2345 if (chitinprotection() && rn2(3)) {
2346 shieldeff(u.ux, u.uy);
2347 pline("A field of force surrounds you!");
2348 } else if (MysteryResist && rn2(StrongMysteryResist ? 10 : 3)) {
2349 shieldeff(u.ux, u.uy);
2350 pline("A field of force surrounds you!");
2351 } else if (Antimagic && rn2(StrongAntimagic ? 10 : 3)) {
2352 shieldeff(u.ux, u.uy);
2353 You_feel("less powerful for a moment, but the feeling passes.");
2354 } else {
2355 if (issoviet) pline("Pravitel'stvo prinimayet resheniye umen'shit' vashi ochki statusa, potomu chto vy stanovites' opasnost'.");
2356 else You_feel("less powerful!");
2357 dmg = rnd(mtmp->m_lev - 7);
2358 if (issoviet) dmg = mtmp->m_lev - rnd(7);
2359 if (Half_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
2360 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg + 1) / 2;
2361 adjattrib(rn2(A_MAX), -dmg, 0, TRUE);
2363 dmg = 0;
2364 break;
2366 case CLC_CURE_SELF:
2367 if (mtmp->mhp < mtmp->mhpmax) {
2368 int healamount;
2369 if (canseemon(mtmp))
2370 pline("%s looks better.", Monnam(mtmp));
2371 /* note: player healing does 6d4; this used to do 1d8 */
2372 /* Amy note: boosted it so that it's no longer completely useless */
2373 healamount = d(3,6) + rnz(1 + mtmp->m_lev);
2374 if ((mtmp->mhp += healamount) > mtmp->mhpmax)
2375 mtmp->mhp = mtmp->mhpmax;
2377 if (mtmp->bleedout && mtmp->bleedout <= healamount) {
2378 mtmp->bleedout = 0;
2379 pline("%s's bleeding stops.", Monnam(mtmp));
2380 } else if (mtmp->bleedout) {
2381 mtmp->bleedout -= healamount;
2382 if (mtmp->bleedout < 0) mtmp->bleedout = 0; /* should never happen */
2383 pline("%s's bleeding diminishes.", Monnam(mtmp));
2386 dmg = 0;
2389 break;
2390 case CLC_OPEN_WOUNDS:
2392 if (!rn2(500 - (mtmp->m_lev * 2) )) { /* wishing */
2394 switch (rnd(6)) {
2395 case 1:
2396 (void) mongets(mtmp, rnd_defensive_item(mtmp));
2397 break;
2398 case 2:
2399 (void) mongets(mtmp, rnd_offensive_item(mtmp));
2400 break;
2401 case 3:
2402 (void) mongets(mtmp, rnd_misc_item(mtmp));
2403 break;
2404 case 4:
2405 (void) mongets(mtmp, rnd_defensive_item_new(mtmp));
2406 break;
2407 case 5:
2408 (void) mongets(mtmp, rnd_offensive_item_new(mtmp));
2409 break;
2410 case 6:
2411 (void) mongets(mtmp, rnd_misc_item_new(mtmp));
2412 break;
2414 pline("%s wishes for an object.", Monnam(mtmp) );
2416 break;
2419 if (!rn2(400 - (mtmp->m_lev * 2) )) { /* summon boss */
2421 if (Aggravate_monster) {
2422 u.aggravation = 1;
2423 reset_rndmonst(NON_PM);
2426 { coord cc;
2427 struct permonst *pm = 0;
2428 struct monst *mon;
2429 int attempts = 0;
2431 if (!enexto(&cc, mtmp->mx, mtmp->my, 0)) break;
2433 newboss:
2434 do {
2435 pm = rndmonst();
2436 attempts++;
2437 if (attempts && (attempts % 10000 == 0)) u.mondiffhack++;
2438 if (!rn2(2000)) reset_rndmonst(NON_PM);
2440 } while ( (!pm || (pm && !(pm->geno & G_UNIQ))) && attempts < 50000);
2442 if (!pm && rn2(50) ) {
2443 attempts = 0;
2444 goto newboss;
2446 if (pm && !(pm->geno & G_UNIQ) && rn2(50) ) {
2447 attempts = 0;
2448 goto newboss;
2451 if (pm) mon = makemon(pm, cc.x, cc.y, NO_MM_FLAGS);
2454 pline("A boss monster appears from nowhere!");
2456 u.mondiffhack = 0;
2457 u.aggravation = 0;
2459 break;
2462 if (!rn2(300 - (mtmp->m_lev * 2) )) { /* bad effect */
2464 badeffect();
2466 break;
2469 if (Antimagic && !Race_if(PM_KUTAR) && rn2(StrongAntimagic ? 20 : 5)) {
2470 shieldeff(u.ux, u.uy);
2471 dmg = (dmg + 1) / 2;
2474 /* Amy change: half damage, but also increase bleeding */
2475 if (dmg > 1) dmg /= 2;
2477 if (dmg <= 5)
2478 Your("skin itches badly for a moment.");
2479 else if (dmg <= 10)
2480 pline("Wounds appear on your body!");
2481 else if (dmg <= 20)
2482 pline("Severe wounds appear on your body!");
2483 else
2484 Your("body is covered with painful wounds!");
2486 playerbleed(dmg);
2488 break;
2489 case CLC_VULN_YOU: /* inspired by Sporkhack but enhanced by Amy */
2490 dmg *= 10;
2491 deacrandomintrinsic(rnz(dmg));
2492 dmg = 0;
2493 break;
2495 default:
2496 impossible("mcastu: invalid clerical spell (%d)", spellnum);
2497 dmg = 0;
2498 break;
2501 if (dmg) mdamageu(mtmp, dmg);
2504 STATIC_DCL
2505 boolean
2506 is_undirected_spell(adtyp, spellnum)
2507 unsigned int adtyp;
2508 int spellnum;
2510 if (adtyp == AD_SPEL) {
2511 switch (spellnum) {
2512 case MGC_CLONE_WIZ:
2513 case MGC_SUMMON_MONS:
2514 case MGC_SUMMON_GHOST:
2515 case MGC_AGGRAVATION:
2516 case MGC_DISAPPEAR:
2517 case MGC_HASTE_SELF:
2518 case MGC_CURE_SELF:
2519 case MGC_CALL_UNDEAD:
2520 return TRUE;
2521 default:
2522 break;
2524 } else if (adtyp == AD_CLRC) {
2525 switch (spellnum) {
2526 case CLC_INSECTS:
2527 case CLC_CURE_SELF:
2528 case CLC_AGGRAVATION:
2529 return TRUE;
2530 default:
2531 break;
2534 return FALSE;
2537 STATIC_DCL
2538 boolean
2539 is_melee_spell(adtyp, spellnum)
2540 unsigned int adtyp;
2541 int spellnum;
2543 if (adtyp == AD_SPEL) {
2544 switch (spellnum) {
2545 case MGC_DEATH_TOUCH:
2546 return TRUE;
2547 default:
2548 break;
2550 } else if (adtyp == AD_CLRC) {
2551 switch (spellnum) {
2552 default:
2553 break;
2556 return FALSE;
2560 /* Some spells are useless under some circumstances. */
2561 STATIC_DCL
2562 boolean
2563 spell_would_be_useless(mtmp, adtyp, spellnum)
2564 struct monst *mtmp;
2565 unsigned int adtyp;
2566 int spellnum;
2568 /* Some spells don't require the player to really be there and can be cast
2569 * by the monster when you're invisible, yet still shouldn't be cast when
2570 * the monster doesn't even think you're there.
2571 * This check isn't quite right because it always uses your real position.
2572 * We really want something like "if the monster could see mux, muy".
2574 boolean mcouldseeu = couldsee(mtmp->mx, mtmp->my);
2576 if (adtyp == AD_SPEL) {
2577 /* aggravate monsters, etc. won't be cast by peaceful monsters */
2578 if (mtmp->mpeaceful && (spellnum == MGC_AGGRAVATION || !is_undirected_spell(AD_SPEL,spellnum) ||
2579 spellnum == MGC_SUMMON_MONS || spellnum == MGC_SUMMON_GHOST || spellnum == MGC_CLONE_WIZ || spellnum == MGC_CREATE_POOL ||
2580 spellnum == MGC_CALL_UNDEAD))
2581 return TRUE;
2582 /* Don't go making everything else bonkers if you're peaceful! */
2583 if (spellnum == MGC_ENRAGE && (mtmp->mpeaceful || mtmp->mtame)) {
2584 return TRUE;
2586 /* haste self when already fast */
2587 if (mtmp->permspeed == MFAST && spellnum == MGC_HASTE_SELF)
2588 return TRUE;
2589 /* invisibility when already invisible */
2590 if ((mtmp->minvis || mtmp->invis_blkd) && spellnum == MGC_DISAPPEAR)
2591 return TRUE;
2592 /* peaceful monster won't cast invisibility if you can't see invisible,
2593 same as when monsters drink potions of invisibility. This doesn't
2594 really make a lot of sense, but lets the player avoid hitting
2595 peaceful monsters by mistake */
2596 if (mtmp->mpeaceful && !See_invisible && spellnum == MGC_DISAPPEAR)
2597 return TRUE;
2598 if (mtmp->mpeaceful && See_invisible && !StrongSee_invisible && !(mtmp->seeinvisble) && spellnum == MGC_DISAPPEAR)
2599 return TRUE;
2600 /* healing when already healed */
2601 if (mtmp->mhp == mtmp->mhpmax && spellnum == MGC_CURE_SELF)
2602 return TRUE;
2604 /* summon monsters less often if the monster is low level --Amy */
2605 if ( (spellnum == MGC_SUMMON_MONS || spellnum == MGC_SUMMON_GHOST || spellnum == MGC_CALL_UNDEAD) && mtmp->m_lev < rnd(50) && rn2(5)) return TRUE;
2607 /* don't summon monsters if it doesn't think you're around */ /* or at least not as often --Amy */
2608 if (!mcouldseeu && ( (spellnum == MGC_SUMMON_MONS && rn2(5)) ||
2609 (spellnum == MGC_CALL_UNDEAD && rn2(5)) || (spellnum == MGC_SUMMON_GHOST && rn2(5)) ||
2610 (!mtmp->iswiz && spellnum == MGC_CLONE_WIZ)))
2611 return TRUE;
2612 /* only lichs can cast call undead */ /* well, not anymore --Amy */
2613 /*if (mtmp->data->mlet != S_LICH && spellnum == MGC_CALL_UNDEAD)
2614 return TRUE;*/
2615 /* pools can only be created in certain locations and then only
2616 * rarely unless you're carrying the amulet.
2618 if (((levl[u.ux][u.uy].typ != ROOM && levl[u.ux][u.uy].typ != CORR) /* lowered chance even with amulet --Amy */
2619 || ((!u.uhave.amulet || u.freeplaymode) && rn2(10)) || rn2(3) ) && spellnum == MGC_CREATE_POOL)
2620 return TRUE;
2621 if ((!mtmp->iswiz || (flags.no_of_wizards > 1 && rn2(20)) )
2622 && spellnum == MGC_CLONE_WIZ)
2623 return TRUE;
2624 } else if (adtyp == AD_CLRC) {
2625 /* summon insects/sticks to snakes won't be cast by peaceful monsters */
2626 if (mtmp->mpeaceful && (spellnum == CLC_INSECTS || !is_undirected_spell(AD_CLRC,spellnum) || spellnum == CLC_AGGRAVATION ) )
2627 return TRUE;
2628 /* healing when already healed */
2629 if (mtmp->mhp == mtmp->mhpmax && spellnum == CLC_CURE_SELF)
2630 return TRUE;
2632 /* summon monsters less often if the monster is low level --Amy */
2633 if ( spellnum == CLC_INSECTS && mtmp->m_lev < rnd(50) && rn2(5)) return TRUE;
2635 /* don't summon insects if it doesn't think you're around */ /* or at least not as often --Amy */
2636 if (!mcouldseeu && spellnum == CLC_INSECTS && rn2(5) )
2637 return TRUE;
2638 /* blindness spell on blinded player */
2639 if (Blinded && spellnum == CLC_BLIND_YOU)
2640 return TRUE;
2642 return FALSE;
2645 #endif /* OVLB */
2646 #ifdef OVL0
2648 /* convert 1..10 to 0..9; add 10 for second group (spell casting) */
2649 #define ad_to_typ(k) (10 + (int)k - 1)
2652 buzzmu(mtmp, mattk) /* monster uses spell (ranged) */
2653 register struct monst *mtmp;
2654 register struct attack *mattk;
2656 int spellcasttype = mattk->adtyp;
2658 if (EnthuActive) {
2659 if (!rn2(100)) spellcasttype = AD_DISN;
2660 else {
2661 switch (rnd(9)) {
2662 case 1:
2663 spellcasttype = AD_MAGM; break;
2664 case 2:
2665 spellcasttype = AD_FIRE; break;
2666 case 3:
2667 spellcasttype = AD_COLD; break;
2668 case 4:
2669 spellcasttype = AD_ELEC; break;
2670 case 5:
2671 spellcasttype = AD_SLEE; break;
2672 case 6:
2673 spellcasttype = AD_DRST; break;
2674 case 7:
2675 spellcasttype = AD_ACID; break;
2676 case 8:
2677 spellcasttype = AD_LITE; break;
2678 case 9:
2679 spellcasttype = AD_SPC2; break;
2684 /* don't print constant stream of curse messages for 'normal'
2685 spellcasting monsters at range */
2686 if ((spellcasttype > AD_SPC2) || (spellcasttype < AD_MAGM))
2687 return(0);
2689 if (mtmp->mcan || arcaniumfail() || (RngeAntimagicA && !rn2(10)) || (RngeAntimagicB && !rn2(5)) || (RngeAntimagicC && !rn2(2)) || (RngeAntimagicD) || (RngeSpellDisruption && !rn2(5)) || u.antimagicshell || (uarmh && uarmh->otyp == HELM_OF_ANTI_MAGIC) || (uarmc && uarmc->oartifact == ART_SHELLY && (moves % 3 == 0)) || (uarmc && uarmc->oartifact == ART_BLACK_VEIL_OF_BLACKNESS) || (uarmc && uarmc->oartifact == ART_ARABELLA_S_WAND_BOOSTER) || (uarmu && uarmu->oartifact == ART_ANTIMAGIC_SHELL) || (uarmu && uarmu->oartifact == ART_ANTIMAGIC_FIELD) || (uwep && uwep->oartifact == ART_WINCHESTER_PREMIUM) || Role_if(PM_UNBELIEVER) || (uwep && uwep->oartifact == ART_ARK_OF_THE_COVENANT) || (uwep && uwep->oartifact == ART_LONG_SWORD_OF_ETERNITY) || (uwep && uwep->oartifact == ART_HEAVY_CROSSBOW_OF_ETERNITY) || (uarmc && uarmc->oartifact == ART_SPELL_WARDED_WRAPPINGS_OF_) || (uwep && uwep->oartifact == ART_ANTIMAGICBANE) || (uarmc && (itemhasappearance(uarmc, APP_VOID_CLOAK) || itemhasappearance(uarmc, APP_SHELL_CLOAK)) && !rn2(5)) ) {
2690 cursetxt(mtmp, FALSE);
2691 return(0);
2693 if(lined_up(mtmp) && rn2(3)) {
2694 nomul(0, 0, FALSE);
2695 if(spellcasttype && (spellcasttype < 11)) { /* no cf unsigned >0 */
2696 if(canseemon(mtmp))
2697 pline("%s zaps you with a %s!", Monnam(mtmp),
2698 flash_types[ad_to_typ(spellcasttype)]);
2699 else if (flags.soundok && !issoviet) You_hear("a buzzing sound.");
2700 buzz(-ad_to_typ(spellcasttype), (rn2(2) ? (int)mattk->damn : (int)mattk->damd ),
2701 mtmp->mx, mtmp->my, sgn(tbx), sgn(tby));
2702 } else impossible("Monster spell %d cast", spellcasttype-1);
2704 return(1);
2707 #endif /* OVL0 */
2709 /*mcastu.c*/
2711 STATIC_PTR void
2712 set_litZ(x,y,val)
2713 int x, y;
2714 void * val;
2716 if (val)
2717 levl[x][y].lit = 1;
2718 else {
2719 levl[x][y].lit = 0;
2720 snuff_light_source(x, y);