Reorganize mcastu code

Merge the two different enums, so all monster spells are in one
list.  This should have no functional difference, but cleans up
the code a bit.
This commit is contained in:
Pasi Kallinen
2026-03-23 11:42:51 +02:00
parent 10eedbe2f0
commit d6cbaca654

View File

@@ -5,44 +5,40 @@
#include "hack.h" #include "hack.h"
/* monster mage spells */ enum mcast_spells {
enum mcast_mage_spells { MCAST_PSI_BOLT = 0,
MGC_PSI_BOLT = 0, MCAST_OPEN_WOUNDS,
MGC_CURE_SELF, MCAST_LIGHTNING,
MGC_HASTE_SELF, MCAST_FIRE_PILLAR,
MGC_STUN_YOU, MCAST_GEYSER,
MGC_DISAPPEAR, MCAST_DEATH_TOUCH,
MGC_WEAKEN_YOU,
MGC_DESTRY_ARMR,
MGC_CURSE_ITEMS,
MGC_AGGRAVATION,
MGC_SUMMON_MONS,
MGC_CLONE_WIZ,
MGC_DEATH_TOUCH
};
/* monster cleric spells */ MCAST_CURE_SELF,
enum mcast_cleric_spells { MCAST_HASTE_SELF,
CLC_OPEN_WOUNDS = 0, MCAST_DISAPPEAR,
CLC_CURE_SELF,
CLC_CONFUSE_YOU, MCAST_AGGRAVATION,
CLC_PARALYZE, MCAST_STUN_YOU,
CLC_BLIND_YOU, MCAST_WEAKEN_YOU,
CLC_INSECTS, MCAST_CONFUSE_YOU,
CLC_CURSE_ITEMS, MCAST_PARALYZE,
CLC_LIGHTNING, MCAST_BLIND_YOU,
CLC_FIRE_PILLAR,
CLC_GEYSER MCAST_DESTRY_ARMR,
MCAST_CURSE_ITEMS,
MCAST_INSECTS,
MCAST_SUMMON_MONS,
MCAST_CLONE_WIZ
}; };
staticfn void cursetxt(struct monst *, boolean); staticfn void cursetxt(struct monst *, boolean);
staticfn int choose_magic_spell(int); staticfn int choose_magic_spell(struct monst *);
staticfn int choose_clerical_spell(int); staticfn int choose_clerical_spell(struct monst *);
staticfn int m_cure_self(struct monst *, int); staticfn int m_cure_self(struct monst *, int);
staticfn void cast_wizard_spell(struct monst *, int, int); staticfn void mcast_spell(struct monst *, int, int);
staticfn void cast_cleric_spell(struct monst *, int, int); staticfn boolean is_undirected_spell(int);
staticfn boolean is_undirected_spell(unsigned int, int); staticfn boolean spell_would_be_useless(struct monst *, int);
staticfn boolean spell_would_be_useless(struct monst *, unsigned int, int);
/* feedback when frustrated monster couldn't cast a spell */ /* feedback when frustrated monster couldn't cast a spell */
staticfn void staticfn void
@@ -73,8 +69,10 @@ cursetxt(struct monst *mtmp, boolean undirected)
/* convert a level-based random selection into a specific mage spell; /* convert a level-based random selection into a specific mage spell;
inappropriate choices will be screened out by spell_would_be_useless() */ inappropriate choices will be screened out by spell_would_be_useless() */
staticfn int staticfn int
choose_magic_spell(int spellval) choose_magic_spell(struct monst *mtmp)
{ {
int spellval = rn2(mtmp->m_lev);
/* for 3.4.3 and earlier, val greater than 22 selected default spell */ /* for 3.4.3 and earlier, val greater than 22 selected default spell */
while (spellval > 24 && rn2(25)) while (spellval > 24 && rn2(25))
spellval = rn2(spellval); spellval = rn2(spellval);
@@ -83,52 +81,54 @@ choose_magic_spell(int spellval)
case 24: case 24:
case 23: case 23:
if (Antimagic || Hallucination) if (Antimagic || Hallucination)
return MGC_PSI_BOLT; return MCAST_PSI_BOLT;
FALLTHROUGH; FALLTHROUGH;
/*FALLTHRU*/ /*FALLTHRU*/
case 22: case 22:
case 21: case 21:
case 20: case 20:
return MGC_DEATH_TOUCH; return MCAST_DEATH_TOUCH;
case 19: case 19:
case 18: case 18:
return MGC_CLONE_WIZ; return MCAST_CLONE_WIZ;
case 17: case 17:
case 16: case 16:
case 15: case 15:
return MGC_SUMMON_MONS; return MCAST_SUMMON_MONS;
case 14: case 14:
case 13: case 13:
return MGC_AGGRAVATION; return MCAST_AGGRAVATION;
case 12: case 12:
case 11: case 11:
case 10: case 10:
return MGC_CURSE_ITEMS; return MCAST_CURSE_ITEMS;
case 9: case 9:
case 8: case 8:
return MGC_DESTRY_ARMR; return MCAST_DESTRY_ARMR;
case 7: case 7:
case 6: case 6:
return MGC_WEAKEN_YOU; return MCAST_WEAKEN_YOU;
case 5: case 5:
case 4: case 4:
return MGC_DISAPPEAR; return MCAST_DISAPPEAR;
case 3: case 3:
return MGC_STUN_YOU; return MCAST_STUN_YOU;
case 2: case 2:
return MGC_HASTE_SELF; return MCAST_HASTE_SELF;
case 1: case 1:
return MGC_CURE_SELF; return MCAST_CURE_SELF;
case 0: case 0:
default: default:
return MGC_PSI_BOLT; return MCAST_PSI_BOLT;
} }
} }
/* convert a level-based random selection into a specific cleric spell */ /* convert a level-based random selection into a specific cleric spell */
staticfn int staticfn int
choose_clerical_spell(int spellnum) choose_clerical_spell(struct monst *mtmp)
{ {
int spellnum = rn2(mtmp->m_lev);
/* for 3.4.3 and earlier, num greater than 13 selected the default spell /* for 3.4.3 and earlier, num greater than 13 selected the default spell
*/ */
while (spellnum > 15 && rn2(16)) while (spellnum > 15 && rn2(16))
@@ -138,34 +138,34 @@ choose_clerical_spell(int spellnum)
case 15: case 15:
case 14: case 14:
if (rn2(3)) if (rn2(3))
return CLC_OPEN_WOUNDS; return MCAST_OPEN_WOUNDS;
FALLTHROUGH; FALLTHROUGH;
/*FALLTHRU*/ /*FALLTHRU*/
case 13: case 13:
return CLC_GEYSER; return MCAST_GEYSER;
case 12: case 12:
return CLC_FIRE_PILLAR; return MCAST_FIRE_PILLAR;
case 11: case 11:
return CLC_LIGHTNING; return MCAST_LIGHTNING;
case 10: case 10:
case 9: case 9:
return CLC_CURSE_ITEMS; return MCAST_CURSE_ITEMS;
case 8: case 8:
return CLC_INSECTS; return MCAST_INSECTS;
case 7: case 7:
case 6: case 6:
return CLC_BLIND_YOU; return MCAST_BLIND_YOU;
case 5: case 5:
case 4: case 4:
return CLC_PARALYZE; return MCAST_PARALYZE;
case 3: case 3:
case 2: case 2:
return CLC_CONFUSE_YOU; return MCAST_CONFUSE_YOU;
case 1: case 1:
return CLC_CURE_SELF; return MCAST_CURE_SELF;
case 0: case 0:
default: default:
return CLC_OPEN_WOUNDS; return MCAST_OPEN_WOUNDS;
} }
} }
@@ -200,15 +200,14 @@ castmu(
int cnt = 40; int cnt = 40;
do { do {
spellnum = rn2(ml);
if (mattk->adtyp == AD_SPEL) if (mattk->adtyp == AD_SPEL)
spellnum = choose_magic_spell(spellnum); spellnum = choose_magic_spell(mtmp);
else else
spellnum = choose_clerical_spell(spellnum); spellnum = choose_clerical_spell(mtmp);
/* not trying to attack? don't allow directed spells */ /* not trying to attack? don't allow directed spells */
if (!thinks_it_foundyou) { if (!thinks_it_foundyou) {
if (!is_undirected_spell(mattk->adtyp, spellnum) if (!is_undirected_spell(spellnum)
|| spell_would_be_useless(mtmp, mattk->adtyp, spellnum)) { || spell_would_be_useless(mtmp, spellnum)) {
if (foundyou) if (foundyou)
impossible( impossible(
"spellcasting monster found you and doesn't know it?"); "spellcasting monster found you and doesn't know it?");
@@ -217,7 +216,7 @@ castmu(
break; break;
} }
} while (--cnt > 0 } while (--cnt > 0
&& spell_would_be_useless(mtmp, mattk->adtyp, spellnum)); && spell_would_be_useless(mtmp, spellnum));
if (cnt == 0) if (cnt == 0)
return M_ATTK_MISS; return M_ATTK_MISS;
} }
@@ -225,10 +224,12 @@ castmu(
/* monster unable to cast spells? */ /* monster unable to cast spells? */
if (mtmp->mcan || mtmp->mspec_used || !ml if (mtmp->mcan || mtmp->mspec_used || !ml
|| m_seenres(mtmp, cvt_adtyp_to_mseenres(mattk->adtyp))) { || m_seenres(mtmp, cvt_adtyp_to_mseenres(mattk->adtyp))) {
cursetxt(mtmp, is_undirected_spell(mattk->adtyp, spellnum)); cursetxt(mtmp, is_undirected_spell(spellnum));
return M_ATTK_MISS; return M_ATTK_MISS;
} }
debugpline3("castmu:%s,lvl:%i,spell:%i", noit_Monnam(mtmp), ml, spellnum);
if (mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) { if (mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) {
/* monst->m_lev is unsigned (uchar), monst->mspec_used is int */ /* monst->m_lev is unsigned (uchar), monst->mspec_used is int */
mtmp->mspec_used = (int) ((mtmp->m_lev < 8) ? (10 - mtmp->m_lev) : 2); mtmp->mspec_used = (int) ((mtmp->m_lev < 8) ? (10 - mtmp->m_lev) : 2);
@@ -245,7 +246,7 @@ castmu(
* for fire mis-aimed at ice. * for fire mis-aimed at ice.
*/ */
if (!foundyou && thinks_it_foundyou if (!foundyou && thinks_it_foundyou
&& !is_undirected_spell(mattk->adtyp, spellnum)) { && !is_undirected_spell(spellnum)) {
pline_mon(mtmp, "%s casts a spell at %s!", pline_mon(mtmp, "%s casts a spell at %s!",
canseemon(mtmp) ? Monnam(mtmp) : "Something", canseemon(mtmp) ? Monnam(mtmp) : "Something",
is_waterwall(mtmp->mux, mtmp->muy) ? "empty water" is_waterwall(mtmp->mux, mtmp->muy) ? "empty water"
@@ -262,10 +263,10 @@ castmu(
} }
return M_ATTK_MISS; return M_ATTK_MISS;
} }
if (canspotmon(mtmp) || !is_undirected_spell(mattk->adtyp, spellnum)) { if (canspotmon(mtmp) || !is_undirected_spell(spellnum)) {
pline_mon(mtmp, "%s casts a spell%s!", pline_mon(mtmp, "%s casts a spell%s!",
canspotmon(mtmp) ? Monnam(mtmp) : "Something", canspotmon(mtmp) ? Monnam(mtmp) : "Something",
is_undirected_spell(mattk->adtyp, spellnum) ? "" is_undirected_spell(spellnum) ? ""
: (Invis && !perceives(mtmp->data) : (Invis && !perceives(mtmp->data)
&& !u_at(mtmp->mux, mtmp->muy)) && !u_at(mtmp->mux, mtmp->muy))
? " at a spot near you" ? " at a spot near you"
@@ -344,10 +345,7 @@ castmu(
break; break;
case AD_SPEL: /* wizard spell */ case AD_SPEL: /* wizard spell */
case AD_CLRC: /* clerical spell */ case AD_CLRC: /* clerical spell */
if (mattk->adtyp == AD_SPEL) mcast_spell(mtmp, dmg, spellnum);
cast_wizard_spell(mtmp, dmg, spellnum);
else
cast_cleric_spell(mtmp, dmg, spellnum);
dmg = 0; /* done by the spell casting functions */ dmg = 0; /* done by the spell casting functions */
break; break;
} /* switch */ } /* switch */
@@ -446,20 +444,22 @@ death_inflicted_by(
and spell_would_be_useless(). and spell_would_be_useless().
*/ */
staticfn void staticfn void
cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum) mcast_spell(struct monst *mtmp, int dmg, int spellnum)
{ {
int orig_dmg = 0;
if (dmg < 0) { if (dmg < 0) {
impossible("monster cast wizard spell (%d) with negative dmg (%d)?", impossible("monster cast spell (%d) with negative dmg (%d)?",
spellnum, dmg); spellnum, dmg);
return; return;
} }
if (dmg == 0 && !is_undirected_spell(AD_SPEL, spellnum)) { if (dmg == 0 && !is_undirected_spell(spellnum)) {
impossible("cast directed wizard spell (%d) with dmg=0?", spellnum); impossible("cast directed wizard spell (%d) with dmg=0?", spellnum);
return; return;
} }
switch (spellnum) { switch (spellnum) {
case MGC_DEATH_TOUCH: case MCAST_DEATH_TOUCH:
pline("Oh no, %s's using the touch of death!", mhe(mtmp)); pline("Oh no, %s's using the touch of death!", mhe(mtmp));
if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) { if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) {
You("seem no deader than before."); You("seem no deader than before.");
@@ -479,7 +479,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
} }
dmg = 0; dmg = 0;
break; break;
case MGC_CLONE_WIZ: case MCAST_CLONE_WIZ:
if (mtmp->iswiz && svc.context.no_of_wizards == 1) { if (mtmp->iswiz && svc.context.no_of_wizards == 1) {
pline("Double Trouble..."); pline("Double Trouble...");
clonewiz(); clonewiz();
@@ -487,7 +487,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
} else } else
impossible("bad wizard cloning?"); impossible("bad wizard cloning?");
break; break;
case MGC_SUMMON_MONS: { case MCAST_SUMMON_MONS: {
int count = nasty(mtmp); int count = nasty(mtmp);
if (!count) { if (!count) {
@@ -515,17 +515,17 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
dmg = 0; dmg = 0;
break; break;
} }
case MGC_AGGRAVATION: case MCAST_AGGRAVATION:
You_feel("that monsters are aware of your presence."); You_feel("that monsters are aware of your presence.");
aggravate(); aggravate();
dmg = 0; dmg = 0;
break; break;
case MGC_CURSE_ITEMS: case MCAST_CURSE_ITEMS:
You_feel("as if you need some help."); You_feel("as if you need some help.");
rndcurse(); rndcurse();
dmg = 0; dmg = 0;
break; break;
case MGC_DESTRY_ARMR: case MCAST_DESTRY_ARMR:
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR); monstseesu(M_SEEN_MAGR);
@@ -539,7 +539,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
} }
dmg = 0; dmg = 0;
break; break;
case MGC_WEAKEN_YOU: /* drain strength */ case MCAST_WEAKEN_YOU: /* drain strength */
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR); monstseesu(M_SEEN_MAGR);
@@ -561,7 +561,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
} }
dmg = 0; dmg = 0;
break; break;
case MGC_DISAPPEAR: /* makes self invisible */ case MCAST_DISAPPEAR: /* makes self invisible */
if (!mtmp->minvis && !mtmp->invis_blkd) { if (!mtmp->minvis && !mtmp->invis_blkd) {
if (canseemon(mtmp)) if (canseemon(mtmp))
pline_mon(mtmp, "%s suddenly %s!", Monnam(mtmp), pline_mon(mtmp, "%s suddenly %s!", Monnam(mtmp),
@@ -573,7 +573,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
} else } else
impossible("no reason for monster to cast disappear spell?"); impossible("no reason for monster to cast disappear spell?");
break; break;
case MGC_STUN_YOU: case MCAST_STUN_YOU:
if (Antimagic || Free_action) { if (Antimagic || Free_action) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR); monstseesu(M_SEEN_MAGR);
@@ -590,14 +590,14 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
} }
dmg = 0; dmg = 0;
break; break;
case MGC_HASTE_SELF: case MCAST_HASTE_SELF:
mon_adjust_speed(mtmp, 1, (struct obj *) 0); mon_adjust_speed(mtmp, 1, (struct obj *) 0);
dmg = 0; dmg = 0;
break; break;
case MGC_CURE_SELF: case MCAST_CURE_SELF:
dmg = m_cure_self(mtmp, dmg); dmg = m_cure_self(mtmp, dmg);
break; break;
case MGC_PSI_BOLT: case MCAST_PSI_BOLT:
/* prior to 3.4.0 Antimagic was setting the damage to 1--this /* prior to 3.4.0 Antimagic was setting the damage to 1--this
made the spell virtually harmless to players with magic res. */ made the spell virtually harmless to players with magic res. */
if (Antimagic) { if (Antimagic) {
@@ -616,35 +616,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
else else
Your("%s suddenly aches very painfully!", body_part(HEAD)); Your("%s suddenly aches very painfully!", body_part(HEAD));
break; break;
default: case MCAST_GEYSER:
impossible("mcastu: invalid magic spell (%d)", spellnum);
dmg = 0;
break;
}
if (dmg)
mdamageu(mtmp, dmg);
}
DISABLE_WARNING_FORMAT_NONLITERAL
staticfn void
cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
{
int orig_dmg = 0;
if (dmg < 0) {
impossible("monster cast cleric spell (%d) with negative dmg (%d)?",
spellnum, dmg);
return;
}
if (dmg == 0 && !is_undirected_spell(AD_CLRC, spellnum)) {
impossible("cast directed cleric spell (%d) with dmg=0?", spellnum);
return;
}
switch (spellnum) {
case CLC_GEYSER:
/* this is physical damage (force not heat), /* this is physical damage (force not heat),
* not magical damage or fire damage * not magical damage or fire damage
*/ */
@@ -657,7 +629,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
water_damage_chain(level.objects[u.ux][u.uy], TRUE); water_damage_chain(level.objects[u.ux][u.uy], TRUE);
#endif #endif
break; break;
case CLC_FIRE_PILLAR: case MCAST_FIRE_PILLAR:
pline("A pillar of fire strikes all around you!"); pline("A pillar of fire strikes all around you!");
orig_dmg = dmg = d(8, 6); orig_dmg = dmg = d(8, 6);
if (Fire_resistance) { if (Fire_resistance) {
@@ -677,7 +649,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
/* burn up flammable items on the floor, melt ice terrain */ /* burn up flammable items on the floor, melt ice terrain */
mon_spell_hits_spot(mtmp, AD_FIRE, u.ux, u.uy); mon_spell_hits_spot(mtmp, AD_FIRE, u.ux, u.uy);
break; break;
case CLC_LIGHTNING: { case MCAST_LIGHTNING: {
boolean reflects; boolean reflects;
Soundeffect(se_bolt_of_lightning, 80); Soundeffect(se_bolt_of_lightning, 80);
@@ -708,12 +680,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
(void) flashburn((long) rnd(100), TRUE); (void) flashburn((long) rnd(100), TRUE);
break; break;
} }
case CLC_CURSE_ITEMS: case MCAST_INSECTS: {
You_feel("as if you need some help.");
rndcurse();
dmg = 0;
break;
case CLC_INSECTS: {
/* Try for insects, and if there are none /* Try for insects, and if there are none
left, go for (sticks to) snakes. -3. */ left, go for (sticks to) snakes. -3. */
struct permonst *pm = mkclass(S_ANT, 0); struct permonst *pm = mkclass(S_ANT, 0);
@@ -788,13 +755,15 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
} else { } else {
fmt = "%s summons %s!"; fmt = "%s summons %s!";
} }
if (fmt) if (fmt) {
DISABLE_WARNING_FORMAT_NONLITERAL;
pline_mon(mtmp, fmt, Monnam(mtmp), what); pline_mon(mtmp, fmt, Monnam(mtmp), what);
RESTORE_WARNING_FORMAT_NONLITERAL;
}
dmg = 0; dmg = 0;
break; break;
} }
case CLC_BLIND_YOU: case MCAST_BLIND_YOU:
/* note: resists_blnd() doesn't apply here */ /* note: resists_blnd() doesn't apply here */
if (!Blinded) { if (!Blinded) {
int num_eyes = eyecount(gy.youmonst.data); int num_eyes = eyecount(gy.youmonst.data);
@@ -809,7 +778,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
} else } else
impossible("no reason for monster to cast blindness spell?"); impossible("no reason for monster to cast blindness spell?");
break; break;
case CLC_PARALYZE: case MCAST_PARALYZE:
if (Antimagic || Free_action) { if (Antimagic || Free_action) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR); monstseesu(M_SEEN_MAGR);
@@ -829,7 +798,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
gn.nomovemsg = 0; gn.nomovemsg = 0;
dmg = 0; dmg = 0;
break; break;
case CLC_CONFUSE_YOU: case MCAST_CONFUSE_YOU:
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR); monstseesu(M_SEEN_MAGR);
@@ -849,10 +818,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
} }
dmg = 0; dmg = 0;
break; break;
case CLC_CURE_SELF: case MCAST_OPEN_WOUNDS:
dmg = m_cure_self(mtmp, dmg);
break;
case CLC_OPEN_WOUNDS:
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR); monstseesu(M_SEEN_MAGR);
@@ -870,7 +836,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
Your("body is covered with painful wounds!"); Your("body is covered with painful wounds!");
break; break;
default: default:
impossible("mcastu: invalid clerical spell (%d)", spellnum); impossible("mcastu: invalid magic spell (%d)", spellnum);
dmg = 0; dmg = 0;
break; break;
} }
@@ -879,38 +845,27 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
mdamageu(mtmp, dmg); mdamageu(mtmp, dmg);
} }
RESTORE_WARNING_FORMAT_NONLITERAL
staticfn boolean staticfn boolean
is_undirected_spell(unsigned int adtyp, int spellnum) is_undirected_spell(int spellnum)
{ {
if (adtyp == AD_SPEL) { switch (spellnum) {
switch (spellnum) { case MCAST_CLONE_WIZ:
case MGC_CLONE_WIZ: case MCAST_SUMMON_MONS:
case MGC_SUMMON_MONS: case MCAST_AGGRAVATION:
case MGC_AGGRAVATION: case MCAST_DISAPPEAR:
case MGC_DISAPPEAR: case MCAST_HASTE_SELF:
case MGC_HASTE_SELF: case MCAST_CURE_SELF:
case MGC_CURE_SELF: case MCAST_INSECTS:
return TRUE; return TRUE;
default: default:
break; break;
}
} else if (adtyp == AD_CLRC) {
switch (spellnum) {
case CLC_INSECTS:
case CLC_CURE_SELF:
return TRUE;
default:
break;
}
} }
return FALSE; return FALSE;
} }
/* Some spells are useless under some circumstances. */ /* Some spells are useless under some circumstances. */
staticfn boolean staticfn boolean
spell_would_be_useless(struct monst *mtmp, unsigned int adtyp, int spellnum) spell_would_be_useless(struct monst *mtmp, int spellnum)
{ {
/* Some spells don't require the player to really be there and can be cast /* Some spells don't require the player to really be there and can be cast
* by the monster when you're invisible, yet still shouldn't be cast when * by the monster when you're invisible, yet still shouldn't be cast when
@@ -920,58 +875,63 @@ spell_would_be_useless(struct monst *mtmp, unsigned int adtyp, int spellnum)
*/ */
boolean mcouldseeu = couldsee(mtmp->mx, mtmp->my); boolean mcouldseeu = couldsee(mtmp->mx, mtmp->my);
if (adtyp == AD_SPEL) { switch (spellnum) {
case MCAST_CLONE_WIZ:
/* only the Wizard is allowed to clone himself */
if (!mtmp->iswiz || svc.context.no_of_wizards > 1)
return TRUE;
if (!mcouldseeu)
return TRUE;
break;
case MCAST_SUMMON_MONS:
/* don't summon monsters if it doesn't think you're around */
if (!mcouldseeu || mtmp->mpeaceful)
return TRUE;
break;
case MCAST_AGGRAVATION:
/* aggravate monsters, etc. won't be cast by peaceful monsters */ /* aggravate monsters, etc. won't be cast by peaceful monsters */
if (mtmp->mpeaceful if (!mcouldseeu || mtmp->mpeaceful)
&& (spellnum == MGC_AGGRAVATION || spellnum == MGC_SUMMON_MONS
|| spellnum == MGC_CLONE_WIZ))
return TRUE; return TRUE;
/* aggravation (global wakeup) when everyone is already active */
/* if nothing needs to be awakened then this spell is useless
but caster might not realize that [chance to pick it then
must be very small otherwise caller's many retry attempts
will eventually end up picking it too often] */
if (!has_aggravatables(mtmp))
return rn2(100) ? TRUE : FALSE;
break;
case MCAST_HASTE_SELF:
/* haste self when already fast */ /* haste self when already fast */
if (mtmp->permspeed == MFAST && spellnum == MGC_HASTE_SELF) if (mtmp->permspeed == MFAST)
return TRUE; return TRUE;
break;
case MCAST_DISAPPEAR:
/* invisibility when already invisible */ /* invisibility when already invisible */
if ((mtmp->minvis || mtmp->invis_blkd) && spellnum == MGC_DISAPPEAR) if (mtmp->minvis || mtmp->invis_blkd)
return TRUE; return TRUE;
/* peaceful monster won't cast invisibility if you can't see /* peaceful monster won't cast invisibility if you can't see
invisible, invisible,
same as when monsters drink potions of invisibility. This doesn't same as when monsters drink potions of invisibility. This doesn't
really make a lot of sense, but lets the player avoid hitting really make a lot of sense, but lets the player avoid hitting
peaceful monsters by mistake */ peaceful monsters by mistake */
if (mtmp->mpeaceful && !See_invisible && spellnum == MGC_DISAPPEAR) if (mtmp->mpeaceful && !See_invisible)
return TRUE; return TRUE;
break;
case MCAST_CURE_SELF:
/* healing when already healed */ /* healing when already healed */
if (mtmp->mhp == mtmp->mhpmax && spellnum == MGC_CURE_SELF) if (mtmp->mhp == mtmp->mhpmax)
return TRUE; return TRUE;
/* don't summon monsters if it doesn't think you're around */ break;
if (!mcouldseeu && (spellnum == MGC_SUMMON_MONS case MCAST_INSECTS:
|| (!mtmp->iswiz && spellnum == MGC_CLONE_WIZ))) /* summon insects/sticks to snakes won't be cast by peaceful monsters */
if (!mcouldseeu || mtmp->mpeaceful)
return TRUE; return TRUE;
if ((!mtmp->iswiz || svc.context.no_of_wizards > 1) break;
&& spellnum == MGC_CLONE_WIZ) case MCAST_BLIND_YOU:
return TRUE; if (Blinded)
/* aggravation (global wakeup) when everyone is already active */
if (spellnum == MGC_AGGRAVATION) {
/* if nothing needs to be awakened then this spell is useless
but caster might not realize that [chance to pick it then
must be very small otherwise caller's many retry attempts
will eventually end up picking it too often] */
if (!has_aggravatables(mtmp))
return rn2(100) ? TRUE : FALSE;
}
} else if (adtyp == AD_CLRC) {
/* summon insects/sticks to snakes won't be cast by peaceful monsters
*/
if (mtmp->mpeaceful && spellnum == CLC_INSECTS)
return TRUE;
/* healing when already healed */
if (mtmp->mhp == mtmp->mhpmax && spellnum == CLC_CURE_SELF)
return TRUE;
/* don't summon insects if it doesn't think you're around */
if (!mcouldseeu && spellnum == CLC_INSECTS)
return TRUE;
/* blindness spell on blinded player */
if (Blinded && spellnum == CLC_BLIND_YOU)
return TRUE; return TRUE;
break;
default:
} }
return FALSE; return FALSE;
} }