diff --git a/src/mcastu.c b/src/mcastu.c index 50aafc7f3..3e32f2e4f 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -36,6 +36,22 @@ staticfn void cursetxt(struct monst *, boolean); staticfn int choose_magic_spell(struct monst *); staticfn int choose_clerical_spell(struct monst *); staticfn int m_cure_self(struct monst *, int); +staticfn void mcast_death_touch(struct monst *); +staticfn void mcast_clone_wiz(struct monst *); +staticfn void mcast_summon_mons(struct monst *); +staticfn void mcast_destroy_armor(void); +staticfn void mcast_weaken_you(struct monst *, int); +staticfn void mcast_disappear(struct monst *); +staticfn void mcast_stun_you(int); +staticfn int mcast_geyser(int); +staticfn int mcast_fire_pillar(struct monst *, int); +staticfn int mcast_lightning(struct monst *, int); +staticfn int mcast_psi_bolt(int); +staticfn int mcast_open_wounds(int); +staticfn void mcast_insects(struct monst *); +staticfn void mcast_blind_you(void); +staticfn int mcast_paralyze(struct monst *); +staticfn void mcast_confuse_you(struct monst *); staticfn void mcast_spell(struct monst *, int, int); staticfn boolean is_undirected_spell(int); staticfn boolean spell_would_be_useless(struct monst *, int); @@ -435,6 +451,410 @@ death_inflicted_by( * Monster wizard and cleric spellcasting functions. */ +staticfn void +mcast_death_touch(struct monst *mtmp) +{ + pline("Oh no, %s's using the touch of death!", mhe(mtmp)); + if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) { + You("seem no deader than before."); + } else if (!Antimagic && rn2(mtmp->m_lev) > 12) { + if (Hallucination) { + You("have an out of body experience."); + } else { + touch_of_death(mtmp); + } + monstunseesu(M_SEEN_MAGR); + } else { + if (Antimagic) { + shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); + } + pline("Lucky for you, it didn't work!"); + } +} + +staticfn void +mcast_clone_wiz(struct monst *mtmp) +{ + if (mtmp->iswiz && svc.context.no_of_wizards == 1) { + pline("Double Trouble..."); + clonewiz(); + } else + impossible("bad wizard cloning?"); +} + +staticfn void +mcast_summon_mons(struct monst *mtmp) +{ + int count = nasty(mtmp); + + if (!count) { + ; /* nothing was created? */ + } else if (mtmp->iswiz) { + SetVoice(mtmp, 0, 80, 0); + verbalize("Destroy the thief, my pet%s!", plur(count)); + } else { + boolean one = (count == 1); + const char *mappear = one ? "A monster appears" + : "Monsters appear"; + + /* messages not quite right if plural monsters created but + only a single monster is seen */ + if (Invis && !perceives(mtmp->data) + && (mtmp->mux != u.ux || mtmp->muy != u.uy)) + pline("%s %s a spot near you!", mappear, + one ? "at" : "around"); + else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) + pline("%s %s your displaced image!", mappear, + one ? "by" : "around"); + else + pline("%s from nowhere!", mappear); + } +} + +staticfn void +mcast_destroy_armor(void) +{ + if (Antimagic) { + shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); + pline("A field of force surrounds you!"); + } else if (!destroy_arm()) { + Your("skin itches."); + } else { + /* monsters only realize you aren't magic-protected if armor is + actually destroyed */ + monstunseesu(M_SEEN_MAGR); + } +} + +staticfn void +mcast_weaken_you(struct monst *mtmp, int dmg) +{ + if (Antimagic) { + shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); + You_feel("momentarily weakened."); + } else { + char kbuf[BUFSZ]; + + You("suddenly feel weaker!"); + dmg = mtmp->m_lev - 6; + if (dmg < 1) /* paranoia since only chosen when m_lev is high */ + dmg = 1; + if (Half_spell_damage) + dmg = (dmg + 1) / 2; + losestr(rnd(dmg), + death_inflicted_by(kbuf, "strength loss", mtmp), + KILLED_BY); + svk.killer.name[0] = '\0'; /* not killed if we get here... */ + monstunseesu(M_SEEN_MAGR); + } +} + +staticfn void +mcast_disappear(struct monst *mtmp) +{ + if (!mtmp->minvis && !mtmp->invis_blkd) { + if (canseemon(mtmp)) + pline_mon(mtmp, "%s suddenly %s!", Monnam(mtmp), + !See_invisible ? "disappears" : "becomes transparent"); + mon_set_minvis(mtmp, FALSE); + if (cansee(mtmp->mx, mtmp->my) && !canspotmon(mtmp)) + map_invisible(mtmp->mx, mtmp->my); + } else + impossible("no reason for monster to cast disappear spell?"); +} + +staticfn void +mcast_stun_you(int dmg) +{ + if (Antimagic || Free_action) { + shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); + if (!Stunned) + You_feel("momentarily disoriented."); + make_stunned(1L, FALSE); + } else { + You(Stunned ? "struggle to keep your balance." : "reel..."); + dmg = d(ACURR(A_DEX) < 12 ? 6 : 4, 4); + if (Half_spell_damage) + dmg = (dmg + 1) / 2; + make_stunned((HStun & TIMEOUT) + (long) dmg, FALSE); + monstunseesu(M_SEEN_MAGR); + } +} + +staticfn int +mcast_geyser(int dmg) +{ + /* this is physical damage (force not heat), + * not magical damage or fire damage + */ + pline("A sudden geyser slams into you from nowhere!"); + dmg = d(8, 6); + if (Half_physical_damage) + dmg = (dmg + 1) / 2; +#if 0 /* since inventory items aren't affected, don't include this */ + /* make floor items wet */ + water_damage_chain(level.objects[u.ux][u.uy], TRUE); +#endif + return dmg; +} + +staticfn int +mcast_fire_pillar(struct monst *mtmp, int dmg) +{ + int orig_dmg; + + pline("A pillar of fire strikes all around you!"); + orig_dmg = dmg = d(8, 6); + if (Fire_resistance) { + shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_FIRE); + dmg = 0; + } else { + monstunseesu(M_SEEN_FIRE); + } + if (Half_spell_damage) + dmg = (dmg + 1) / 2; + burn_away_slime(); + (void) burnarmor(&gy.youmonst); + /* item destruction dmg */ + (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); + ignite_items(gi.invent); + /* burn up flammable items on the floor, melt ice terrain */ + mon_spell_hits_spot(mtmp, AD_FIRE, u.ux, u.uy); + return dmg; +} + +staticfn int +mcast_lightning(struct monst *mtmp, int dmg) +{ + int orig_dmg; + boolean reflects; + + Soundeffect(se_bolt_of_lightning, 80); + pline("A bolt of lightning strikes down at you from above!"); + reflects = ureflects("It bounces off your %s%s.", ""); + orig_dmg = dmg = d(8, 6); + if (reflects || Shock_resistance) { + shieldeff(u.ux, u.uy); + dmg = 0; + if (reflects) { + monstseesu(M_SEEN_REFL); + return dmg; + } + monstunseesu(M_SEEN_REFL); + monstseesu(M_SEEN_ELEC); + } else { + monstunseesu(M_SEEN_ELEC | M_SEEN_REFL); + } + if (Half_spell_damage) + dmg = (dmg + 1) / 2; + (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dmg); + /* lightning might destroy iron bars if hero is on such a spot; + reflection protects terrain here [execution won't get here due + to 'if (reflects) break' above] but hero resistance doesn't; + do this before maybe blinding the hero via flashburn() */ + mon_spell_hits_spot(mtmp, AD_ELEC, u.ux, u.uy); + /* blind hero; no effect if already blind */ + (void) flashburn((long) rnd(100), TRUE); + return dmg; +} + +staticfn int +mcast_psi_bolt(int dmg) +{ + /* prior to 3.4.0 Antimagic was setting the damage to 1--this + made the spell virtually harmless to players with magic res. */ + if (Antimagic) { + shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); + dmg = (dmg + 1) / 2; + } else { + monstunseesu(M_SEEN_MAGR); + } + if (dmg <= 5) + You("get a slight %sache.", body_part(HEAD)); + else if (dmg <= 10) + Your("brain is on fire!"); + else if (dmg <= 20) + Your("%s suddenly aches painfully!", body_part(HEAD)); + else + Your("%s suddenly aches very painfully!", body_part(HEAD)); + return dmg; +} + +staticfn int +mcast_open_wounds(int dmg) +{ + if (Antimagic) { + shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); + dmg = (dmg + 1) / 2; + } else { + monstunseesu(M_SEEN_MAGR); + } + if (dmg <= 5) + Your("skin itches badly for a moment."); + else if (dmg <= 10) + pline("Wounds appear on your body!"); + else if (dmg <= 20) + pline("Severe wounds appear on your body!"); + else + Your("body is covered with painful wounds!"); + return dmg; +} + +staticfn void +mcast_insects(struct monst *mtmp) +{ + /* Try for insects, and if there are none + left, go for (sticks to) snakes. -3. */ + struct permonst *pm = mkclass(S_ANT, 0); + struct monst *mtmp2 = (struct monst *) 0; + char whatbuf[QBUFSZ], let = (pm ? S_ANT : S_SNAKE); + boolean success = FALSE, seecaster; + int i, quan, oldseen, newseen; + coord bypos; + const char *fmt, *what; + + oldseen = monster_census(TRUE); + quan = (mtmp->m_lev < 2) ? 1 : rnd((int) mtmp->m_lev / 2); + if (quan < 3) + quan = 3; + for (i = 0; i <= quan; i++) { + if (!enexto(&bypos, mtmp->mux, mtmp->muy, mtmp->data)) + return; + if ((pm = mkclass(let, 0)) != 0 + && (mtmp2 = makemon(pm, bypos.x, bypos.y, MM_ANGRY | MM_NOMSG)) + != 0) { + success = TRUE; + mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0; + set_malign(mtmp2); + } + } + newseen = monster_census(TRUE); + + /* not canspotmon() which includes unseen things sensed via warning */ + seecaster = canseemon(mtmp) || tp_sensemon(mtmp) || Detect_monsters; + what = (let == S_SNAKE) ? "snakes" : "insects"; + if (Hallucination) + what = makeplural(bogusmon(whatbuf, (char *) 0)); + + fmt = 0; + if (!seecaster) { + if (newseen <= oldseen || Unaware) { + /* unseen caster fails or summons unseen critters, + or unconscious hero ("You dream that you hear...") */ + You_hear("someone summoning %s.", what); + } else { + char *arg; + + if (what != whatbuf) + what = strcpy(whatbuf, what); + /* unseen caster summoned seen critter(s) */ + arg = (newseen == oldseen + 1) ? an(makesingular(what)) + : whatbuf; + if (!Deaf) { + Soundeffect(se_someone_summoning, 100); + You_hear("someone summoning something, and %s %s.", arg, + vtense(arg, "appear")); + } else { + pline("%s %s.", upstart(arg), vtense(arg, "appear")); + } + } + + /* seen caster, possibly producing unseen--or just one--critters; + hero is told what the caster is doing and doesn't necessarily + observe complete accuracy of that caster's results (in other + words, no need to fuss with visibility or singularization; + player is told what's happening even if hero is unconscious) */ + } else if (!success) { + fmt = "%s casts at a clump of sticks, but nothing happens.%s"; + what = ""; + } else if (let == S_SNAKE) { + fmt = "%s transforms a clump of sticks into %s!"; + } else if (Invis && !perceives(mtmp->data) + && (mtmp->mux != u.ux || mtmp->muy != u.uy)) { + fmt = "%s summons %s around a spot near you!"; + } else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) { + fmt = "%s summons %s around your displaced image!"; + } else { + fmt = "%s summons %s!"; + } + if (fmt) { + DISABLE_WARNING_FORMAT_NONLITERAL; + pline_mon(mtmp, fmt, Monnam(mtmp), what); + RESTORE_WARNING_FORMAT_NONLITERAL; + } +} + +staticfn void +mcast_blind_you(void) +{ + /* note: resists_blnd() doesn't apply here */ + if (!Blinded) { + int num_eyes = eyecount(gy.youmonst.data); + + pline("Scales cover your %s!", (num_eyes == 1) + ? body_part(EYE) + : makeplural(body_part(EYE))); + make_blinded(Half_spell_damage ? 100L : 200L, FALSE); + if (!Blind) + Your1(vision_clears); + } else + impossible("no reason for monster to cast blindness spell?"); +} + +staticfn int +mcast_paralyze(struct monst *mtmp) +{ + int dmg = 0; + + if (Antimagic || Free_action) { + shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); + if (gm.multi >= 0) + You("stiffen briefly."); + dmg = 1; /* to produce nomul(-1), not actual damage */ + } else { + if (gm.multi >= 0) + You("are frozen in place!"); + dmg = 4 + (int) mtmp->m_lev; + if (Half_spell_damage) + dmg = (dmg + 1) / 2; + monstunseesu(M_SEEN_MAGR); + } + nomul(-dmg); + gm.multi_reason = "paralyzed by a monster"; + gn.nomovemsg = 0; + return dmg; +} + +staticfn void +mcast_confuse_you(struct monst *mtmp) +{ + if (Antimagic) { + shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); + You_feel("momentarily dizzy."); + } else { + boolean oldprop = !!Confusion; + int dmg = (int) mtmp->m_lev; + + if (Half_spell_damage) + dmg = (dmg + 1) / 2; + make_confused(HConfusion + dmg, TRUE); + if (Hallucination) + You_feel("%s!", oldprop ? "trippier" : "trippy"); + else + You_feel("%sconfused!", oldprop ? "more " : ""); + monstunseesu(M_SEEN_MAGR); + } +} + /* If dmg is zero, then the monster is not casting at you. If the monster is intentionally not casting at you, we have previously @@ -446,8 +866,6 @@ death_inflicted_by( staticfn void mcast_spell(struct monst *mtmp, int dmg, int spellnum) { - int orig_dmg = 0; - if (dmg < 0) { impossible("monster cast spell (%d) with negative dmg (%d)?", spellnum, dmg); @@ -460,61 +878,17 @@ mcast_spell(struct monst *mtmp, int dmg, int spellnum) switch (spellnum) { case MCAST_DEATH_TOUCH: - pline("Oh no, %s's using the touch of death!", mhe(mtmp)); - if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) { - You("seem no deader than before."); - } else if (!Antimagic && rn2(mtmp->m_lev) > 12) { - if (Hallucination) { - You("have an out of body experience."); - } else { - touch_of_death(mtmp); - } - monstunseesu(M_SEEN_MAGR); - } else { - if (Antimagic) { - shieldeff(u.ux, u.uy); - monstseesu(M_SEEN_MAGR); - } - pline("Lucky for you, it didn't work!"); - } + mcast_death_touch(mtmp); dmg = 0; break; case MCAST_CLONE_WIZ: - if (mtmp->iswiz && svc.context.no_of_wizards == 1) { - pline("Double Trouble..."); - clonewiz(); - dmg = 0; - } else - impossible("bad wizard cloning?"); - break; - case MCAST_SUMMON_MONS: { - int count = nasty(mtmp); - - if (!count) { - ; /* nothing was created? */ - } else if (mtmp->iswiz) { - SetVoice(mtmp, 0, 80, 0); - verbalize("Destroy the thief, my pet%s!", plur(count)); - } else { - boolean one = (count == 1); - const char *mappear = one ? "A monster appears" - : "Monsters appear"; - - /* messages not quite right if plural monsters created but - only a single monster is seen */ - if (Invis && !perceives(mtmp->data) - && (mtmp->mux != u.ux || mtmp->muy != u.uy)) - pline("%s %s a spot near you!", mappear, - one ? "at" : "around"); - else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) - pline("%s %s your displaced image!", mappear, - one ? "by" : "around"); - else - pline("%s from nowhere!", mappear); - } + mcast_clone_wiz(mtmp); + dmg = 0; + break; + case MCAST_SUMMON_MONS: + mcast_summon_mons(mtmp); dmg = 0; break; - } case MCAST_AGGRAVATION: You_feel("that monsters are aware of your presence."); aggravate(); @@ -526,68 +900,19 @@ mcast_spell(struct monst *mtmp, int dmg, int spellnum) dmg = 0; break; case MCAST_DESTRY_ARMR: - if (Antimagic) { - shieldeff(u.ux, u.uy); - monstseesu(M_SEEN_MAGR); - pline("A field of force surrounds you!"); - } else if (!destroy_arm()) { - Your("skin itches."); - } else { - /* monsters only realize you aren't magic-protected if armor is - actually destroyed */ - monstunseesu(M_SEEN_MAGR); - } + mcast_destroy_armor(); dmg = 0; break; case MCAST_WEAKEN_YOU: /* drain strength */ - if (Antimagic) { - shieldeff(u.ux, u.uy); - monstseesu(M_SEEN_MAGR); - You_feel("momentarily weakened."); - } else { - char kbuf[BUFSZ]; - - You("suddenly feel weaker!"); - dmg = mtmp->m_lev - 6; - if (dmg < 1) /* paranoia since only chosen when m_lev is high */ - dmg = 1; - if (Half_spell_damage) - dmg = (dmg + 1) / 2; - losestr(rnd(dmg), - death_inflicted_by(kbuf, "strength loss", mtmp), - KILLED_BY); - svk.killer.name[0] = '\0'; /* not killed if we get here... */ - monstunseesu(M_SEEN_MAGR); - } + mcast_weaken_you(mtmp, dmg); dmg = 0; break; case MCAST_DISAPPEAR: /* makes self invisible */ - if (!mtmp->minvis && !mtmp->invis_blkd) { - if (canseemon(mtmp)) - pline_mon(mtmp, "%s suddenly %s!", Monnam(mtmp), - !See_invisible ? "disappears" : "becomes transparent"); - mon_set_minvis(mtmp, FALSE); - if (cansee(mtmp->mx, mtmp->my) && !canspotmon(mtmp)) - map_invisible(mtmp->mx, mtmp->my); - dmg = 0; - } else - impossible("no reason for monster to cast disappear spell?"); + mcast_disappear(mtmp); + dmg = 0; break; case MCAST_STUN_YOU: - if (Antimagic || Free_action) { - shieldeff(u.ux, u.uy); - monstseesu(M_SEEN_MAGR); - if (!Stunned) - You_feel("momentarily disoriented."); - make_stunned(1L, FALSE); - } else { - You(Stunned ? "struggle to keep your balance." : "reel..."); - dmg = d(ACURR(A_DEX) < 12 ? 6 : 4, 4); - if (Half_spell_damage) - dmg = (dmg + 1) / 2; - make_stunned((HStun & TIMEOUT) + (long) dmg, FALSE); - monstunseesu(M_SEEN_MAGR); - } + mcast_stun_you(dmg); dmg = 0; break; case MCAST_HASTE_SELF: @@ -598,242 +923,34 @@ mcast_spell(struct monst *mtmp, int dmg, int spellnum) dmg = m_cure_self(mtmp, dmg); break; case MCAST_PSI_BOLT: - /* prior to 3.4.0 Antimagic was setting the damage to 1--this - made the spell virtually harmless to players with magic res. */ - if (Antimagic) { - shieldeff(u.ux, u.uy); - monstseesu(M_SEEN_MAGR); - dmg = (dmg + 1) / 2; - } else { - monstunseesu(M_SEEN_MAGR); - } - if (dmg <= 5) - You("get a slight %sache.", body_part(HEAD)); - else if (dmg <= 10) - Your("brain is on fire!"); - else if (dmg <= 20) - Your("%s suddenly aches painfully!", body_part(HEAD)); - else - Your("%s suddenly aches very painfully!", body_part(HEAD)); + dmg = mcast_psi_bolt(dmg); break; case MCAST_GEYSER: - /* this is physical damage (force not heat), - * not magical damage or fire damage - */ - pline("A sudden geyser slams into you from nowhere!"); - dmg = d(8, 6); - if (Half_physical_damage) - dmg = (dmg + 1) / 2; -#if 0 /* since inventory items aren't affected, don't include this */ - /* make floor items wet */ - water_damage_chain(level.objects[u.ux][u.uy], TRUE); -#endif + dmg = mcast_geyser(dmg); break; case MCAST_FIRE_PILLAR: - pline("A pillar of fire strikes all around you!"); - orig_dmg = dmg = d(8, 6); - if (Fire_resistance) { - shieldeff(u.ux, u.uy); - monstseesu(M_SEEN_FIRE); - dmg = 0; - } else { - monstunseesu(M_SEEN_FIRE); - } - if (Half_spell_damage) - dmg = (dmg + 1) / 2; - burn_away_slime(); - (void) burnarmor(&gy.youmonst); - /* item destruction dmg */ - (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); - ignite_items(gi.invent); - /* burn up flammable items on the floor, melt ice terrain */ - mon_spell_hits_spot(mtmp, AD_FIRE, u.ux, u.uy); + dmg = mcast_fire_pillar(mtmp, dmg); break; - case MCAST_LIGHTNING: { - boolean reflects; - - Soundeffect(se_bolt_of_lightning, 80); - pline("A bolt of lightning strikes down at you from above!"); - reflects = ureflects("It bounces off your %s%s.", ""); - orig_dmg = dmg = d(8, 6); - if (reflects || Shock_resistance) { - shieldeff(u.ux, u.uy); - dmg = 0; - if (reflects) { - monstseesu(M_SEEN_REFL); - break; - } - monstunseesu(M_SEEN_REFL); - monstseesu(M_SEEN_ELEC); - } else { - monstunseesu(M_SEEN_ELEC | M_SEEN_REFL); - } - if (Half_spell_damage) - dmg = (dmg + 1) / 2; - (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dmg); - /* lightning might destroy iron bars if hero is on such a spot; - reflection protects terrain here [execution won't get here due - to 'if (reflects) break' above] but hero resistance doesn't; - do this before maybe blinding the hero via flashburn() */ - mon_spell_hits_spot(mtmp, AD_ELEC, u.ux, u.uy); - /* blind hero; no effect if already blind */ - (void) flashburn((long) rnd(100), TRUE); + case MCAST_LIGHTNING: + dmg = mcast_lightning(mtmp, dmg); break; - } - case MCAST_INSECTS: { - /* Try for insects, and if there are none - left, go for (sticks to) snakes. -3. */ - struct permonst *pm = mkclass(S_ANT, 0); - struct monst *mtmp2 = (struct monst *) 0; - char whatbuf[QBUFSZ], let = (pm ? S_ANT : S_SNAKE); - boolean success = FALSE, seecaster; - int i, quan, oldseen, newseen; - coord bypos; - const char *fmt, *what; - - oldseen = monster_census(TRUE); - quan = (mtmp->m_lev < 2) ? 1 : rnd((int) mtmp->m_lev / 2); - if (quan < 3) - quan = 3; - for (i = 0; i <= quan; i++) { - if (!enexto(&bypos, mtmp->mux, mtmp->muy, mtmp->data)) - break; - if ((pm = mkclass(let, 0)) != 0 - && (mtmp2 = makemon(pm, bypos.x, bypos.y, MM_ANGRY | MM_NOMSG)) - != 0) { - success = TRUE; - mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0; - set_malign(mtmp2); - } - } - newseen = monster_census(TRUE); - - /* not canspotmon() which includes unseen things sensed via warning */ - seecaster = canseemon(mtmp) || tp_sensemon(mtmp) || Detect_monsters; - what = (let == S_SNAKE) ? "snakes" : "insects"; - if (Hallucination) - what = makeplural(bogusmon(whatbuf, (char *) 0)); - - fmt = 0; - if (!seecaster) { - if (newseen <= oldseen || Unaware) { - /* unseen caster fails or summons unseen critters, - or unconscious hero ("You dream that you hear...") */ - You_hear("someone summoning %s.", what); - } else { - char *arg; - - if (what != whatbuf) - what = strcpy(whatbuf, what); - /* unseen caster summoned seen critter(s) */ - arg = (newseen == oldseen + 1) ? an(makesingular(what)) - : whatbuf; - if (!Deaf) { - Soundeffect(se_someone_summoning, 100); - You_hear("someone summoning something, and %s %s.", arg, - vtense(arg, "appear")); - } else { - pline("%s %s.", upstart(arg), vtense(arg, "appear")); - } - } - - /* seen caster, possibly producing unseen--or just one--critters; - hero is told what the caster is doing and doesn't necessarily - observe complete accuracy of that caster's results (in other - words, no need to fuss with visibility or singularization; - player is told what's happening even if hero is unconscious) */ - } else if (!success) { - fmt = "%s casts at a clump of sticks, but nothing happens.%s"; - what = ""; - } else if (let == S_SNAKE) { - fmt = "%s transforms a clump of sticks into %s!"; - } else if (Invis && !perceives(mtmp->data) - && (mtmp->mux != u.ux || mtmp->muy != u.uy)) { - fmt = "%s summons %s around a spot near you!"; - } else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) { - fmt = "%s summons %s around your displaced image!"; - } else { - fmt = "%s summons %s!"; - } - if (fmt) { - DISABLE_WARNING_FORMAT_NONLITERAL; - pline_mon(mtmp, fmt, Monnam(mtmp), what); - RESTORE_WARNING_FORMAT_NONLITERAL; - } + case MCAST_INSECTS: + mcast_insects(mtmp); dmg = 0; break; - } case MCAST_BLIND_YOU: - /* note: resists_blnd() doesn't apply here */ - if (!Blinded) { - int num_eyes = eyecount(gy.youmonst.data); - - pline("Scales cover your %s!", (num_eyes == 1) - ? body_part(EYE) - : makeplural(body_part(EYE))); - make_blinded(Half_spell_damage ? 100L : 200L, FALSE); - if (!Blind) - Your1(vision_clears); - dmg = 0; - } else - impossible("no reason for monster to cast blindness spell?"); + mcast_blind_you(); + dmg = 0; break; case MCAST_PARALYZE: - if (Antimagic || Free_action) { - shieldeff(u.ux, u.uy); - monstseesu(M_SEEN_MAGR); - if (gm.multi >= 0) - You("stiffen briefly."); - dmg = 1; /* to produce nomul(-1), not actual damage */ - } else { - if (gm.multi >= 0) - You("are frozen in place!"); - dmg = 4 + (int) mtmp->m_lev; - if (Half_spell_damage) - dmg = (dmg + 1) / 2; - monstunseesu(M_SEEN_MAGR); - } - nomul(-dmg); - gm.multi_reason = "paralyzed by a monster"; - gn.nomovemsg = 0; - dmg = 0; + dmg = mcast_paralyze(mtmp); break; case MCAST_CONFUSE_YOU: - if (Antimagic) { - shieldeff(u.ux, u.uy); - monstseesu(M_SEEN_MAGR); - You_feel("momentarily dizzy."); - } else { - boolean oldprop = !!Confusion; - - dmg = (int) mtmp->m_lev; - if (Half_spell_damage) - dmg = (dmg + 1) / 2; - make_confused(HConfusion + dmg, TRUE); - if (Hallucination) - You_feel("%s!", oldprop ? "trippier" : "trippy"); - else - You_feel("%sconfused!", oldprop ? "more " : ""); - monstunseesu(M_SEEN_MAGR); - } + mcast_confuse_you(mtmp); dmg = 0; break; case MCAST_OPEN_WOUNDS: - if (Antimagic) { - shieldeff(u.ux, u.uy); - monstseesu(M_SEEN_MAGR); - dmg = (dmg + 1) / 2; - } else { - monstunseesu(M_SEEN_MAGR); - } - if (dmg <= 5) - Your("skin itches badly for a moment."); - else if (dmg <= 10) - pline("Wounds appear on your body!"); - else if (dmg <= 20) - pline("Severe wounds appear on your body!"); - else - Your("body is covered with painful wounds!"); + dmg = mcast_open_wounds(dmg); break; default: impossible("mcastu: invalid magic spell (%d)", spellnum);