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. */
6 #include "edog.h" /* sporkhack MGC_ENRAGE needs this */
8 /* monster mage spells */
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
24 #define MGC_DAMAGE_ARMR 15
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
41 #define CLC_CURSE_ITEMS 6
42 #define CLC_LIGHTNING 7
43 #define CLC_FIRE_PILLAR 8
45 #define CLC_AGGRAVATION 10
46 #define CLC_PETRIFY 11 /* currently unused */
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);
67 extern const char * const flash_types
[]; /* from zap.c */
69 /* feedback when frustrated monster couldn't cast a spell */
72 cursetxt(mtmp
, undirected
)
76 if (canseemon(mtmp
) && couldsee(mtmp
->mx
, mtmp
->my
)) {
77 const char *point_msg
; /* spellcasting monsters are impolite */
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
) ||
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";
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.");
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 */
106 if (uwep
&& objects
[uwep
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
109 if (u
.twoweap
&& uswapwep
&& objects
[uswapwep
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
112 if (uarm
&& objects
[uarm
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
115 if (uarmc
&& objects
[uarmc
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
118 if (uarmh
&& objects
[uarmh
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
121 if (uarms
&& objects
[uarms
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
124 if (uarmg
&& objects
[uarmg
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
127 if (uarmf
&& objects
[uarmf
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
130 if (uarmu
&& objects
[uarmu
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
133 if (uamul
&& objects
[uamul
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
136 if (uimplant
&& objects
[uimplant
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
139 if (uleft
&& objects
[uleft
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
142 if (uright
&& objects
[uright
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
145 if (ublindf
&& objects
[ublindf
->otyp
].oc_material
== MT_ARCANIUM
&& !rn2(20)) {
152 /* convert a level based random selection into a specific mage spell;
153 inappropriate choices will be screened out by spell_would_be_useless() */
155 choose_magic_spell(spellval
)
158 if (EnthuActive
) spellval
= rnd(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
;
165 return MGC_ENRAGE
; /* we reduce the risk of getting a touch of death */
167 return MGC_DEATH_TOUCH
;
169 return MGC_ESCALATION
;
171 if (!rn2(25)) return MGC_SUMMON_GHOST
; /* Should be rare --Amy */
172 else return MGC_CLONE_WIZ
;
175 return MGC_HASTE_SELF
;
177 return MGC_SUMMON_MONS
;
180 return MGC_AGGRAVATION
;
182 if (!rn2(2)) return MGC_LEVITATE
;
183 else if (!rn2(5)) return MGC_MEGALOAD
;
184 else return MGC_CREATE_POOL
;
188 return MGC_CURSE_ITEMS
;
190 return MGC_CALL_UNDEAD
;
192 if (!rn2(4)) return MGC_WITHER
;
193 else if (!rn2(2)) return MGC_DAMAGE_ARMR
;
194 else return MGC_DESTRY_ARMR
;
198 return MGC_WEAKEN_YOU
;
202 return MGC_DISAPPEAR
;
206 return MGC_HASTE_SELF
;
208 return MGC_CURE_SELF
;
212 if (!rn2(25)) return MGC_DIVINE_WRATH
; /* waaaay too overpowered, so this will appear much more rarely --Amy */
213 else return MGC_ENRAGE
;
215 return MGC_ENRAGE
; /* we reduce the risk of getting a touch of death */
217 return MGC_DEATH_TOUCH
;
219 return MGC_ESCALATION
;
221 if (!rn2(25)) return MGC_SUMMON_GHOST
; /* Should be rare --Amy */
222 else return MGC_CLONE_WIZ
;
225 return MGC_HASTE_SELF
;
227 return MGC_SUMMON_MONS
;
230 return MGC_AGGRAVATION
;
232 if (!rn2(2)) return MGC_LEVITATE
;
233 else if (!rn2(5)) return MGC_MEGALOAD
;
234 else return MGC_CREATE_POOL
;
238 return MGC_CURSE_ITEMS
;
240 return MGC_CALL_UNDEAD
;
242 if (!rn2(4)) return MGC_WITHER
;
243 else if (!rn2(2)) return MGC_DAMAGE_ARMR
;
244 else return MGC_DESTRY_ARMR
;
248 return MGC_WEAKEN_YOU
;
252 return MGC_DISAPPEAR
;
256 return MGC_HASTE_SELF
;
258 return MGC_CURE_SELF
;
265 /* convert a level based random selection into a specific cleric spell */
267 choose_clerical_spell(spellnum
)
270 if (EnthuActive
) spellnum
= rnd(41);
276 return CLC_FIRE_PILLAR
;
278 return CLC_LIGHTNING
;
280 return CLC_STAT_DRAIN
;
282 return CLC_CURSE_ITEMS
;
284 if (rn2(2)) return CLC_RANDOM
;
285 else if (!rn2(50)) return CLC_AGGRAVATION
;
286 else return CLC_INSECTS
;
288 return CLC_FREEZE_YOU
;
290 return CLC_BLIND_YOU
;
296 return CLC_SEPARATION
;
298 return CLC_CONFUSE_YOU
;
300 return CLC_CURE_SELF
;
302 return (rn2(10) ? CLC_OPEN_WOUNDS
: CLC_VULN_YOU
);
306 return CLC_FIRE_PILLAR
;
308 return CLC_LIGHTNING
;
310 return CLC_STAT_DRAIN
;
312 return CLC_CURSE_ITEMS
;
314 if (rn2(2)) return CLC_RANDOM
;
315 else if (!rn2(50)) return CLC_AGGRAVATION
;
316 else return CLC_INSECTS
;
318 return CLC_FREEZE_YOU
;
320 return CLC_BLIND_YOU
;
326 return CLC_SEPARATION
;
328 return CLC_CONFUSE_YOU
;
330 return CLC_CURE_SELF
;
332 return (rn2(10) ? CLC_OPEN_WOUNDS
: CLC_VULN_YOU
);
336 return CLC_FIRE_PILLAR
;
338 return CLC_LIGHTNING
;
340 return CLC_STAT_DRAIN
;
342 return CLC_CURSE_ITEMS
;
344 if (rn2(2)) return CLC_RANDOM
;
345 else if (!rn2(50)) return CLC_AGGRAVATION
;
346 else return CLC_INSECTS
;
348 return CLC_FREEZE_YOU
;
350 return CLC_BLIND_YOU
;
356 return CLC_SEPARATION
;
358 return CLC_CONFUSE_YOU
;
360 return CLC_CURE_SELF
;
363 return (rn2(10) ? CLC_OPEN_WOUNDS
: CLC_VULN_YOU
);
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
;
378 int dmg
, ml
= mtmp
->m_lev
;
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
);
388 if (is_lightsaber(monweapon
) && monweapon
->lamplit
) {
390 if (mtmp
->data
->geno
& G_UNIQ
) ml
+= 5;
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
;
405 spellcasttype
= AD_MAGM
; break;
407 spellcasttype
= AD_FIRE
; break;
409 spellcasttype
= AD_COLD
; break;
411 spellcasttype
= AD_ELEC
; break;
413 spellcasttype
= AD_SLEE
; break;
415 spellcasttype
= AD_DRST
; break;
417 spellcasttype
= AD_ACID
; break;
419 spellcasttype
= AD_LITE
; break;
421 spellcasttype
= AD_SPC2
; break;
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
) {
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;
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
;
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
;
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
)) {
486 impossible("spellcasting monster found you and doesn't know it?");
492 spell_would_be_useless(mtmp
, spellcasttype
, spellnum
));
493 if (cnt
== 0) return 0;
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
));
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.
517 mtmp
->mspec_used
= 10 - mtmp
->m_lev
;
518 if (mtmp
->mspec_used
< 2) mtmp
->mspec_used
= 2;
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");
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
;
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;
574 chance
= chance
* (20-splcaster
) / 15 - splcaster
;
576 /* Clamp to percentile */
577 if (chance
> 100) chance
= 100;
578 if (chance
< 0) chance
= 0;
581 if(rn2(ml
*10) < (mtmp
->mconf
? 100 : 20)) { /* fumbled attack */
583 if (mtmp
->mconf
|| rnd(100) > chance
) { /* fumbled attack */
585 if (canseemon(mtmp
) && flags
.soundok
)
586 pline_The("air crackles around %s.", mon_nam(mtmp
));
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" :
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.
607 if (spellcasttype
!= AD_SPEL
&& spellcasttype
!= AD_CLRC
&& spellcasttype
!= AD_CAST
) {
609 "%s casting non-hand-to-hand version of hand-to-hand spell %d?",
610 Monnam(mtmp
), spellcasttype
);
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;
621 switch (spellcasttype
) {
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.");
634 pline("The slime is burned away!");
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.");
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.");
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.");
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.");
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.");
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!");
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.");
691 pline("Your %s spins wildly.", body_part(HEAD
) );
698 make_confused(HConfusion
+ dmg
, FALSE
);
703 make_stunned(HStun
+ dmg
, FALSE
);
706 make_confused(HConfusion
+ dmg
, FALSE
);
707 make_stunned(HStun
+ dmg
, FALSE
);
710 make_hallucinated(HHallucination
+ dmg
, FALSE
, 0L);
713 make_feared(HFeared
+ dmg
, FALSE
);
716 make_numbed(HNumbed
+ dmg
, FALSE
);
721 forget(rnd(5), FALSE
);
722 pline("You forget some important things...");
725 losexp("psionic drain", FALSE
, TRUE
);
728 adjattrib(A_INT
, -1, 1, TRUE
);
729 adjattrib(A_WIS
, -1, 1, TRUE
);
732 pline("You scream in pain!");
738 if (!rn2(5)) increasesanity(rnz(5));
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.");
748 else if (!PlayerResistsDeathRays
&& !rn2(20)) {
750 killer_format
= KILLED_BY_AN
;
751 killer
= "Avada Kedavra curse";
754 return 1; /* lifesaved */
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!");
765 case AD_SPEL
: /* wizard spell */
766 case AD_CLRC
: /* clerical spell */
768 if (spellcasttype
== AD_SPEL
)
769 cast_wizard_spell(mtmp
, dmg
, spellnum
);
771 cast_cleric_spell(mtmp
, dmg
, spellnum
);
772 dmg
= 0; /* done by the spell casting functions */
775 case AD_CAST
: /* clerical spell */
777 if ((moves
% 4 == 0) || ((moves
+ 1) % 4 == 0))
778 cast_cleric_spell(mtmp
, dmg
, spellnum
);
780 cast_wizard_spell(mtmp
, dmg
, spellnum
);
781 dmg
= 0; /* done by the spell casting functions */
785 if(dmg
) mdamageu(mtmp
, dmg
);
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
796 If you modify either of these, be sure to change is_undirected_spell()
797 and spell_would_be_useless().
801 cast_wizard_spell(mtmp
, dmg
, spellnum
)
812 if (dmg
== 0 && !is_undirected_spell(AD_SPEL
, spellnum
)) {
813 impossible("cast directed wizard spell (%d) with dmg=0?", 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) {
824 You("have an out of body experience.");
825 } else if (!rnd(50) && !Antimagic
) {
827 killer_format
= KILLED_BY_AN
;
828 killer
= "touch of death";
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
);
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
);
844 You_feel("drained...");
845 if (PlayerHearsSoundEffects
) pline(issoviet
? "Vy odin shag blizhe k provalu v nastoyashcheye vremya. Pozdravleniya." : "Doaing!");
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.");*/
853 if (Antimagic
) shieldeff(u
.ux
, u
.uy
);
854 pline("Lucky for you, it didn't work!");
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 */
867 impossible("bad pool creation?");
872 if (MysteryResist
&& rn2(2)) {
874 You("resist the megaload spell!");
877 if (chitinprotection() && rn2(2)) {
879 You("resist the megaload spell!");
882 if (StrongMysteryResist
&& rn2(2)) {
884 You("resist the megaload spell!");
888 if ((otmp
= mksobj(LOADSTONE
, TRUE
, FALSE
, FALSE
)) != (struct obj
*)0) {
889 pline(FunnyHallu
? "Aww, something's killing your good feelings!" : "You feel burdened");
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
); }
902 pline(FunnyHallu
? "Wow... you're suddenly walking on air!" : "You float up!");
903 HLevitation
&= ~I_SPECIAL
;
904 incr_itimeout(&HLevitation
, rnz(50));
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...");
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.");
918 case MGC_SUMMON_MONS
:
922 count
= nasty(mtmp
); /* summon something nasty */
924 verbalize("Destroy the thief, my pet%s!", plur(count
));
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
);
937 pline("%s from nowhere!", mappear
);
940 if (mtmp
->data
== &mons
[PM_WOK
]) {
942 struct permonst
*pm
= 0;
944 if (Aggravate_monster
) {
946 reset_rndmonst(NON_PM
);
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) ) {
962 if (pm
&& !(pm
->msound
== MS_SUPERMAN
) && rn2(50) ) {
967 if (pm
) (void) makemon(pm
, 0, 0, MM_ANGRY
|MM_FRENZIED
);
977 case MGC_SUMMON_GHOST
:
983 tt_mname(&mm
, FALSE
, 0); /* create player-monster ghosts */
985 verbalize("Destroy the thief, my pets!");
987 const char *mappear
=
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
);
998 pline("%s from nowhere!", mappear
);
1002 if (mtmp
->data
== &mons
[PM_WOK
]) {
1004 struct permonst
*pm
= 0;
1006 if (Aggravate_monster
) {
1008 reset_rndmonst(NON_PM
);
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) ) {
1024 if (pm
&& !(pm
->msound
== MS_SUPERMAN
) && rn2(50) ) {
1029 if (pm
) (void) makemon(pm
, 0, 0, MM_ANGRY
|MM_FRENZIED
);
1040 case MGC_CALL_UNDEAD
:
1045 pline("Undead creatures are called forth from the grave!");
1046 mkundead(&mm
, FALSE
, 0, FALSE
);
1049 if (mtmp
->data
== &mons
[PM_WOK
]) {
1051 struct permonst
*pm
= 0;
1053 if (Aggravate_monster
) {
1055 reset_rndmonst(NON_PM
);
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) ) {
1071 if (pm
&& !(pm
->msound
== MS_SUPERMAN
) && rn2(50) ) {
1076 if (pm
) (void) makemon(pm
, 0, 0, MM_ANGRY
|MM_FRENZIED
);
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!");
1091 case MGC_CURSE_ITEMS
:
1092 if (MysteryResist
&& !rn2(3)) {
1094 You("resist the itemcursing spell!");
1097 if (chitinprotection() && !rn2(3)) {
1099 You("resist the itemcursing spell!");
1102 if (StrongMysteryResist
&& !rn2(3)) {
1104 You("resist the itemcursing spell!");
1107 You_feel("as if you need some help.");
1108 if (PlayerHearsSoundEffects
) pline(issoviet
? "Vashe der'mo tol'ko chto proklinal." : "Woaaaaaa-AAAH!");
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!");
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;
1140 else if (!otmp2
) pline("Your skin itches.");
1141 else if(!destroy_arm(otmp2
)) pline("Your skin itches.");
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!
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) {
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
); }
1186 } else if (mtmp2
->mpeaceful
&& !is_infrastructure_monster(mtmp2
)) {
1187 mtmp2
->mpeaceful
= 0;
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 */
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());
1204 pline("It seems a little more dangerous here now...");
1205 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) doredraw();
1210 case MGC_DIVINE_WRATH
: /* new idea by Amy. Yes, this is very evil. :D */
1212 if (chitinprotection() && !rn2(2)) {
1214 You("resist the divine wrath spell!");
1217 if (MysteryResist
&& !rn2(2)) {
1219 You("resist the divine wrath spell!");
1222 if (StrongMysteryResist
&& !rn2(2)) {
1224 You("resist the divine wrath spell!");
1229 if (!rn2(5)) u
.ugangr
++;
1230 if (!rn2(25)) u
.ugangr
++;
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!");
1247 pline("You sense a sinister feeling of loss!");
1252 if (!uarmh
|| !wither_dmg(uarmh
, xname(uarmh
), rn2(4), FALSE
, &youmonst
))
1257 (void)wither_dmg(uarmc
, xname(uarmc
), rn2(4), TRUE
, &youmonst
);
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.
1266 (void)wither_dmg(uarm
, xname(uarm
), rn2(4), TRUE
, &youmonst
);
1268 (void)wither_dmg(uarmu
, xname(uarmu
), rn2(4), TRUE
, &youmonst
);
1271 if (!uarms
|| !wither_dmg(uarms
, xname(uarms
), rn2(4), FALSE
, &youmonst
))
1275 if (!uarmg
|| !wither_dmg(uarmg
, xname(uarmg
), rn2(4), FALSE
, &youmonst
))
1279 if (!uarmf
|| !wither_dmg(uarmf
, xname(uarmf
), rn2(4), FALSE
, &youmonst
))
1283 break; /* Out of while loop */
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!");
1299 pline("Your body shakes!");
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
))
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
);
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.
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
);
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
);
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
))
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
))
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
))
1378 break; /* Out of while loop */
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.");
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
);
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
);
1414 impossible("no reason for monster to cast disappear spell?");
1417 if (Antimagic
&& rn2(StrongAntimagic
? 3 : 2)) {
1418 shieldeff(u
.ux
, u
.uy
);
1420 You_feel("numb for a moment.");
1421 make_numbed(1L, FALSE
);
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
);
1431 if (Antimagic
&& rn2(StrongAntimagic
? 3 : 2)) {
1432 shieldeff(u
.ux
, u
.uy
);
1434 You_feel("ablaze for a moment.");
1435 make_burned(1L, FALSE
);
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
);
1445 if ((Antimagic
|| Free_action
) && rn2((StrongAntimagic
|| StrongFree_action
) ? 20 : 5)) {
1446 shieldeff(u
.ux
, u
.uy
);
1448 You_feel("momentarily disoriented.");
1449 make_stunned(1L, FALSE
);
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
);
1459 case MGC_HASTE_SELF
:
1460 mon_adjust_speed(mtmp
, 1, (struct obj
*)0);
1464 if (mtmp
->mhp
< mtmp
->mhpmax
) {
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
) {
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
));
1488 if (!rn2(500 - (mtmp
->m_lev
* 2) )) { /* wishing */
1492 (void) mongets(mtmp
, rnd_defensive_item(mtmp
));
1495 (void) mongets(mtmp
, rnd_offensive_item(mtmp
));
1498 (void) mongets(mtmp
, rnd_misc_item(mtmp
));
1501 (void) mongets(mtmp
, rnd_defensive_item_new(mtmp
));
1504 (void) mongets(mtmp
, rnd_offensive_item_new(mtmp
));
1507 (void) mongets(mtmp
, rnd_misc_item_new(mtmp
));
1510 pline("%s wishes for an object.", Monnam(mtmp
) );
1515 if (!rn2(400 - (mtmp
->m_lev
* 2) )) { /* summon boss */
1517 if (Aggravate_monster
) {
1519 reset_rndmonst(NON_PM
);
1523 struct permonst
*pm
= 0;
1527 if (!enexto(&cc
, mtmp
->mx
, mtmp
->my
, 0)) break;
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) ) {
1542 if (pm
&& !(pm
->geno
& G_UNIQ
) && rn2(50) ) {
1547 if (pm
) mon
= makemon(pm
, cc
.x
, cc
.y
, NO_MM_FLAGS
);
1550 pline("A boss monster appears from nowhere!");
1558 if (!rn2(300 - (mtmp
->m_lev
* 2) )) { /* bad effect */
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;
1576 You("get a slight %sache.", body_part(HEAD
));
1578 Your("brain is on fire!");
1580 Your("%s suddenly aches painfully!", body_part(HEAD
));
1582 Your("%s suddenly aches very painfully!", body_part(HEAD
));
1584 if (!Psi_resist
|| !rn2(StrongPsi_resist
? 20 : 5) ) increasesanity(dmg
);
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
;
1598 You("get a %sache.", body_part(HEAD
));
1600 Your("brain is on fire, and the pain seems to be getting stronger!");
1602 Your("%s suddenly aches really painfully!", body_part(HEAD
));
1604 Your("%s suddenly aches extremely painfully!", body_part(HEAD
));
1610 impossible("mcastu: invalid magic spell (%d)", spellnum
);
1615 if (dmg
) mdamageu(mtmp
, dmg
);
1620 cast_cleric_spell(mtmp
, dmg
, spellnum
)
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
);
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.");
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;
1675 /* antimatter storm --Amy */
1677 if (chitinprotection() && rn2(2)) {
1679 You("resist the antimatter spell!");
1682 if (MysteryResist
&& rn2(2)) {
1684 You("resist the antimatter spell!");
1687 if (StrongMysteryResist
&& rn2(2)) {
1689 You("resist the antimatter spell!");
1693 pline("You are caught in an antimatter storm!");
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;
1707 if (chitinprotection() && rn2(2)) {
1709 You("resist the petrify spell!");
1712 if (MysteryResist
&& rn2(2)) {
1714 You("resist the petrify spell!");
1717 if (StrongMysteryResist
&& rn2(2)) {
1719 You("resist the petrify spell!");
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.");
1728 You("start turning to stone!");
1729 Stoned
= Race_if(PM_EROSATOR
) ? 3 : 7;
1730 u
.cnd_stoningcount
++;
1732 delayed_killer
= "petrify spell";
1744 if (chitinprotection() && rn2(2)) {
1746 You("resist the sliming spell!");
1749 if (MysteryResist
&& rn2(2)) {
1751 You("resist the sliming spell!");
1754 if (StrongMysteryResist
&& rn2(2)) {
1756 You("resist the sliming spell!");
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.");
1765 killer_format
= KILLED_BY_AN
;
1766 delayed_killer
= "slimed by a monster spell";
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
);
1788 if (chitinprotection() && rn2(2)) {
1790 You("resist the amnesia spell!");
1793 if (MysteryResist
&& rn2(2)) {
1795 You("resist the amnesia spell!");
1798 if (StrongMysteryResist
&& rn2(2)) {
1800 You("resist the amnesia spell!");
1804 /* amnesia - evil patch idea by jonadab */
1807 if (!strncmpi(plname
, "Maud", 4) || !strncmpi(plalias
, "Maud", 4))
1808 pline("As your mind turns inward on itself, you forget everything else.");
1810 pline("Who was that Maud person anyway?");
1812 pline("Thinking of Maud you forget everything else.");
1819 /* wraparound - evil patch idea */
1822 oldhpmax
= u
.uhpmax
;
1823 oldmpmax
= u
.uenmax
;
1827 u
.uenmax
= oldhpmax
;
1828 u
.uhpmax
= oldmpmax
;
1829 You_feel("a wraparound!");
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
) {
1840 if (!rn2(5)) objX
->oinvis
= objX
->oinvisreal
= FALSE
;
1846 default: /*failsafe*/
1847 You_feel("that monsters are aware of your presence."); /* aggravate monster */
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
);
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;
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
);
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.", "");
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
);
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
);
1899 case CLC_CURSE_ITEMS
:
1901 if (chitinprotection() && !rn2(3)) {
1903 You("resist the itemcursing spell!");
1906 if (MysteryResist
&& !rn2(3)) {
1908 You("resist the itemcursing spell!");
1911 if (StrongMysteryResist
&& !rn2(3)) {
1913 You("resist the itemcursing spell!");
1917 You_feel("as if you need some help.");
1918 if (PlayerHearsSoundEffects
) pline(issoviet
? "Vashe der'mo tol'ko chto proklinal." : "Woaaaaaa-AAAH!");
1923 case CLC_AGGRAVATION
: /* aggravate monster */
1924 You_feel("that monsters are aware of your presence."); /* aggravate monster */
1926 if (PlayerHearsSoundEffects
) pline(issoviet
? "Dazhe sovetskaya Pyat' Lo obostryayetsya v vashem nizkom igrovom masterstve." : "Woaaaaaah!");
1930 case CLC_RANDOM
: /* inofficial names see below */
1943 You_feel("a sense of intrinsic loss."); /* intrinsic loss */
1957 You_feel("a dark aura."); /* dark aura */
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));
1973 You_feel("very trippy all of a sudden!"); /* acid trip */
1975 duratX
= (rnz(1 + mtmp
->m_lev
));
1976 make_hallucinated(HHallucination
+ duratX
,FALSE
,0L);
1981 You_feel("endangered!!"); /* create traps */
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;
1997 (void) maketrap(u
.ux
+ i
, u
.uy
+ j
, rtrap
, 100, TRUE
);
2002 You_feel("yanked in a new direction!"); /* relocation */
2003 (void) safe_teleds_normalterrain(FALSE
);
2009 pline("Your mana is sapped!"); /* mana drain */
2011 manastealX
= (rnz(1 + mtmp
->m_lev
));
2012 drain_en(manastealX
);
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!");
2021 ep
= (struct engr
*)0;
2028 pline(FunnyHallu
? "You suddenly feel like you're on cold turkey!" : "Your hands start trembling!"); /* disarm */
2030 glibberX
= (rnz(1 + mtmp
->m_lev
));
2031 incr_itimeout(&Glib
, glibberX
);
2037 You_feel("pulsating winds!"); /* slow */
2042 pline(FunnyHallu
? "You feel like you just got dumped by your girlfriend!" : "You feel out of luck!"); /* dementor force */
2044 if (!rn2(10)) change_luck(-5);
2046 if (!rn2(10)) adjalign(-50);
2050 You_feel("burdened"); /* punishment - message is from Castle of the Winds */
2056 pushplayer(FALSE
); /* use the force */
2058 default: /*failsafe*/
2059 You_feel("that monsters are aware of your presence."); /* aggravate monster */
2061 if (PlayerHearsSoundEffects
) pline(issoviet
? "Dazhe sovetskaya Pyat' Lo obostryayetsya v vashem nizkom igrovom masterstve." : "Woaaaaaah!");
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
);
2081 /* Let's allow some variation. Unofficial spell names for each type of creature see below. --Amy */
2083 if (!rn2(3)) { switch (rnd(54)) {
2165 default: /* failsafe */
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
) {
2180 reset_rndmonst(NON_PM
);
2183 for (i
= 0; i
<= quan
; i
++) {
2184 if (!enexto(&bypos
, mtmp
->mux
, mtmp
->muy
, mtmp
->data
))
2186 if ((pm
= mkclass(let
,0)) != 0 &&
2187 (mtmp2
= makemon(pm
, bypos
.x
, bypos
.y
, NO_MM_FLAGS
)) != 0) {
2189 mtmp2
->msleeping
= mtmp2
->mpeaceful
= mtmp2
->mtame
= 0;
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
2204 pline("%s casts at a clump of sticks, but nothing happens.",
2206 else if (let
== S_SNAKE
) /* sticks to snakes */
2207 pline("%s transforms a clump of sticks into snakes!",
2209 else if (let
== S_MIMIC
) /* garbage spam */
2210 pline("%s conjures up random garbage!",
2212 else if (let
== S_NYMPH
) /* charming seduction */
2213 pline("%s summons some beautiful ladies!",
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!",
2220 else if (let
== S_SPIDER
) /* demonic spiders */
2221 pline("%s summons spiders!",
2223 else if (let
== S_WORM
) /* can of worms */
2224 pline("%s opens up a can of worms!",
2226 else if (let
== S_BAT
) /* flapping bats */
2227 pline("%s summons a bat swarm!",
2229 else if (let
== S_UMBER
) /* hulking brutes */
2230 pline("%s summons terrifying creatures!",
2232 else if (let
== S_HUMAN
) /* court summoning */
2233 pline("%s summons interesting people from around the world!",
2235 else if (let
== S_GOLEM
) /* golem mastery */
2236 pline("%s transforms a heap of junk into animated beings!",
2238 else if (let
== S_EEL
) /* deep sea trouble */
2239 pline("%s opens up a can of whoop-ass!",
2241 else if (let
== S_BAD_FOOD
) /* mystic nature */
2242 pline("%s summons mystic natures!",
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!",
2248 else if (Displaced
&& (StrongDisplaced
|| !rn2(3)) && (mtmp
->mux
!= u
.ux
|| mtmp
->muy
!= u
.uy
))
2249 pline("%s summons insects around your displaced image!",
2252 pline("%s summons insects!", Monnam(mtmp
));
2257 /* note: resists_blnd() doesn't apply here */
2259 int num_eyes
= eyecount(youmonst
.data
);
2260 pline("Scales cover your %s!",
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
);
2267 impossible("no reason for monster to cast blindness spell?");
2270 if ((Antimagic
|| Free_action
) && rn2((StrongAntimagic
|| StrongFree_action
) ? 20 : 5)) {
2271 shieldeff(u
.ux
, u
.uy
);
2273 You("stiffen briefly.");
2274 nomul(-1, "paralyzed by a monster spell", TRUE
);
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
);
2293 case CLC_CONFUSE_YOU
:
2294 if (Antimagic
&& rn2(StrongAntimagic
? 20 : 5)) {
2295 shieldeff(u
.ux
, u
.uy
);
2296 You_feel("momentarily dizzy.");
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
);
2305 You_feel("%s!", oldprop
? "trippier" : "trippy");
2307 You_feel("%sconfused!", oldprop
? "more " : "");
2312 if (Antimagic
&& rn2(StrongAntimagic
? 3 : 2)) {
2313 shieldeff(u
.ux
, u
.uy
);
2315 You_feel("afraid for a moment.");
2316 make_feared(1L, FALSE
);
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
);
2325 case CLC_FREEZE_YOU
:
2326 if (Antimagic
&& rn2(StrongAntimagic
? 3 : 2)) {
2327 shieldeff(u
.ux
, u
.uy
);
2329 You_feel("frozen for a moment.");
2330 make_frozen(1L, FALSE
);
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
);
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.");
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.");
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
);
2367 if (mtmp
->mhp
< mtmp
->mhpmax
) {
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
) {
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
));
2390 case CLC_OPEN_WOUNDS
:
2392 if (!rn2(500 - (mtmp
->m_lev
* 2) )) { /* wishing */
2396 (void) mongets(mtmp
, rnd_defensive_item(mtmp
));
2399 (void) mongets(mtmp
, rnd_offensive_item(mtmp
));
2402 (void) mongets(mtmp
, rnd_misc_item(mtmp
));
2405 (void) mongets(mtmp
, rnd_defensive_item_new(mtmp
));
2408 (void) mongets(mtmp
, rnd_offensive_item_new(mtmp
));
2411 (void) mongets(mtmp
, rnd_misc_item_new(mtmp
));
2414 pline("%s wishes for an object.", Monnam(mtmp
) );
2419 if (!rn2(400 - (mtmp
->m_lev
* 2) )) { /* summon boss */
2421 if (Aggravate_monster
) {
2423 reset_rndmonst(NON_PM
);
2427 struct permonst
*pm
= 0;
2431 if (!enexto(&cc
, mtmp
->mx
, mtmp
->my
, 0)) break;
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) ) {
2446 if (pm
&& !(pm
->geno
& G_UNIQ
) && rn2(50) ) {
2451 if (pm
) mon
= makemon(pm
, cc
.x
, cc
.y
, NO_MM_FLAGS
);
2454 pline("A boss monster appears from nowhere!");
2462 if (!rn2(300 - (mtmp
->m_lev
* 2) )) { /* bad effect */
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;
2478 Your("skin itches badly for a moment.");
2480 pline("Wounds appear on your body!");
2482 pline("Severe wounds appear on your body!");
2484 Your("body is covered with painful wounds!");
2489 case CLC_VULN_YOU
: /* inspired by Sporkhack but enhanced by Amy */
2491 deacrandomintrinsic(rnz(dmg
));
2496 impossible("mcastu: invalid clerical spell (%d)", spellnum
);
2501 if (dmg
) mdamageu(mtmp
, dmg
);
2506 is_undirected_spell(adtyp
, spellnum
)
2510 if (adtyp
== AD_SPEL
) {
2513 case MGC_SUMMON_MONS
:
2514 case MGC_SUMMON_GHOST
:
2515 case MGC_AGGRAVATION
:
2517 case MGC_HASTE_SELF
:
2519 case MGC_CALL_UNDEAD
:
2524 } else if (adtyp
== AD_CLRC
) {
2528 case CLC_AGGRAVATION
:
2539 is_melee_spell(adtyp
, spellnum
)
2543 if (adtyp
== AD_SPEL
) {
2545 case MGC_DEATH_TOUCH
:
2550 } else if (adtyp
== AD_CLRC
) {
2560 /* Some spells are useless under some circumstances. */
2563 spell_would_be_useless(mtmp
, adtyp
, 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
))
2582 /* Don't go making everything else bonkers if you're peaceful! */
2583 if (spellnum
== MGC_ENRAGE
&& (mtmp
->mpeaceful
|| mtmp
->mtame
)) {
2586 /* haste self when already fast */
2587 if (mtmp
->permspeed
== MFAST
&& spellnum
== MGC_HASTE_SELF
)
2589 /* invisibility when already invisible */
2590 if ((mtmp
->minvis
|| mtmp
->invis_blkd
) && spellnum
== MGC_DISAPPEAR
)
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
)
2598 if (mtmp
->mpeaceful
&& See_invisible
&& !StrongSee_invisible
&& !(mtmp
->seeinvisble
) && spellnum
== MGC_DISAPPEAR
)
2600 /* healing when already healed */
2601 if (mtmp
->mhp
== mtmp
->mhpmax
&& spellnum
== MGC_CURE_SELF
)
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
)))
2612 /* only lichs can cast call undead */ /* well, not anymore --Amy */
2613 /*if (mtmp->data->mlet != S_LICH && spellnum == MGC_CALL_UNDEAD)
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
)
2621 if ((!mtmp
->iswiz
|| (flags
.no_of_wizards
> 1 && rn2(20)) )
2622 && spellnum
== MGC_CLONE_WIZ
)
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
) )
2628 /* healing when already healed */
2629 if (mtmp
->mhp
== mtmp
->mhpmax
&& spellnum
== CLC_CURE_SELF
)
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) )
2638 /* blindness spell on blinded player */
2639 if (Blinded
&& spellnum
== CLC_BLIND_YOU
)
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
;
2659 if (!rn2(100)) spellcasttype
= AD_DISN
;
2663 spellcasttype
= AD_MAGM
; break;
2665 spellcasttype
= AD_FIRE
; break;
2667 spellcasttype
= AD_COLD
; break;
2669 spellcasttype
= AD_ELEC
; break;
2671 spellcasttype
= AD_SLEE
; break;
2673 spellcasttype
= AD_DRST
; break;
2675 spellcasttype
= AD_ACID
; break;
2677 spellcasttype
= AD_LITE
; break;
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
))
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
);
2693 if(lined_up(mtmp
) && rn2(3)) {
2695 if(spellcasttype
&& (spellcasttype
< 11)) { /* no cf unsigned >0 */
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);
2720 snuff_light_source(x
, y
);