*** empty log message ***

This commit is contained in:
jwalz
2002-01-05 21:05:49 +00:00
parent a7a50902bd
commit 254558a40f

355
src/mcastu.c Normal file
View File

@@ -0,0 +1,355 @@
/* SCCS Id: @(#)mcastu.c 3.3 97/11/02 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
#include "hack.h"
STATIC_DCL void FDECL(cursetxt,(struct monst *));
#ifdef OVL0
extern const char *flash_types[]; /* from zap.c */
/* feedback when frustrated monster couldn't cast a spell */
STATIC_OVL
void
cursetxt(mtmp)
struct monst *mtmp;
{
if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)) {
const char *point_msg; /* spellcasting monsters are impolite */
if ((Invis && !perceives(mtmp->data) &&
(mtmp->mux != u.ux || mtmp->muy != u.uy)) ||
(youmonst.m_ap_type == M_AP_OBJECT &&
youmonst.mappearance == STRANGE_OBJECT) ||
u.uundetected)
point_msg = "and curses in your general direction";
else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
point_msg = "and curses at your displaced image";
else
point_msg = "at you, then curses";
pline("%s points %s.", Monnam(mtmp), point_msg);
} else if ((!(moves % 4) || !rn2(4))) {
if (flags.soundok) Norep("You hear a mumbled curse.");
}
}
#endif /* OVL0 */
#ifdef OVLB
int
castmu(mtmp, mattk) /* monster casts spell at you */
register struct monst *mtmp;
register struct attack *mattk;
{
int dmg, ml = mtmp->m_lev;
if(mtmp->mcan || mtmp->mspec_used || !ml) { /* could not attack */
cursetxt(mtmp);
return(0);
} else {
nomul(0);
if(rn2(ml*10) < (mtmp->mconf ? 100 : 20)) { /* fumbled attack */
if (canseemon(mtmp) && flags.soundok)
pline_The("air crackles around %s.", mon_nam(mtmp));
return(0);
}
}
/*
* As these are spells, the damage is related to the level
* of the monster casting the spell.
*/
if (mattk->damd)
dmg = d((int)((ml/3) + mattk->damn), (int)mattk->damd);
else dmg = d((int)((ml/3) + 1), 6);
if (Half_spell_damage) dmg = (dmg+1) / 2;
switch(mattk->adtyp) {
case AD_FIRE:
pline("You're enveloped in flames.");
if(Fire_resistance) {
shieldeff(u.ux, u.uy);
pline("But you resist the effects.");
dmg = 0;
}
burn_away_slime();
break;
case AD_COLD:
pline("You're covered in frost.");
if(Cold_resistance) {
shieldeff(u.ux, u.uy);
pline("But you resist the effects.");
dmg = 0;
}
break;
case AD_MAGM:
You("are hit by a shower of missiles!");
if(Antimagic) {
shieldeff(u.ux, u.uy);
pline_The("missiles bounce off!");
dmg = 0;
} else dmg = d((int)mtmp->m_lev/2 + 1,6);
break;
case AD_SPEL: /* random spell */
mtmp->mspec_used = 10 - mtmp->m_lev;
if (mtmp->mspec_used < 2) mtmp->mspec_used = 2;
switch(rn2((int)mtmp->m_lev)) {
case 22:
case 21:
case 20:
pline("Oh no, %s's using the touch of death!",
humanoid(mtmp->data)
? (mtmp->female ? "she" : "he")
: "it"
);
if (nonliving(youmonst.data) || is_demon(youmonst.data))
You("seem no deader than before.");
else if (!Antimagic && rn2(ml) > 12) {
if(Hallucination)
You("have an out of body experience.");
else {
killer_format = KILLED_BY_AN;
killer = "touch of death";
done(DIED);
}
} else {
if(Antimagic) shieldeff(u.ux, u.uy);
pline("Lucky for you, it didn't work!");
}
dmg = 0;
break;
case 19:
case 18:
if(mtmp->iswiz && flags.no_of_wizards == 1) {
pline("Double Trouble...");
clonewiz();
dmg = 0;
break;
} /* else fall into the next case */
case 17:
case 16:
case 15:
if(mtmp->iswiz)
verbalize("Destroy the thief, my pets!");
nasty(mtmp); /* summon something nasty */
/* fall into the next case */
case 14: /* aggravate all monsters */
case 13:
aggravate();
dmg = 0;
break;
case 12: /* curse random items */
case 11:
case 10:
rndcurse();
dmg = 0;
break;
case 9:
case 8: /* destroy armor */
if (Antimagic) {
shieldeff(u.ux, u.uy);
pline("A field of force surrounds you!");
} else if(!destroy_arm(some_armor(&youmonst)))
Your("skin itches.");
dmg = 0;
break;
case 7:
case 6: /* drain strength */
if(Antimagic) {
shieldeff(u.ux, u.uy);
You_feel("momentarily weakened.");
} else {
You("suddenly feel weaker!");
dmg = ml - 6;
if(Half_spell_damage) dmg = (dmg+1) / 2;
losestr(rnd(dmg));
if(u.uhp < 1)
done_in_by(mtmp);
}
dmg = 0;
break;
case 5: /* make invisible if not */
case 4:
if (!mtmp->minvis && !mtmp->invis_blkd) {
if(canseemon(mtmp) && !See_invisible)
pline("%s suddenly disappears!", Monnam(mtmp));
mon_set_minvis(mtmp);
dmg = 0;
break;
} /* else fall into the next case */
case 3: /* stun */
if (Antimagic || Free_action) {
shieldeff(u.ux, u.uy);
if(!Stunned)
You_feel("momentarily disoriented.");
make_stunned(1L, FALSE);
} else {
if (Stunned)
You("struggle to keep your balance.");
else
You("reel...");
dmg = d(ACURR(A_DEX) < 12 ? 6 : 4, 4);
if(Half_spell_damage) dmg = (dmg+1) / 2;
make_stunned(HStun + dmg, FALSE);
}
dmg = 0;
break;
case 2: /* haste self */
mon_adjust_speed(mtmp, 1);
dmg = 0;
break;
case 1: /* cure self */
if(mtmp->mhp < mtmp->mhpmax) {
if((mtmp->mhp += rnd(8)) > mtmp->mhpmax)
mtmp->mhp = mtmp->mhpmax;
dmg = 0;
break;
} /* else fall through to default case */
default: /* psi bolt */
if(Antimagic) {
shieldeff(u.ux, u.uy);
You("get a slight %sache.",body_part(HEAD));
dmg = 1;
} else {
if (dmg <= 10)
Your("brain is on fire!");
else Your("%s suddenly aches!", body_part(HEAD));
}
break;
}
break;
case AD_CLRC: /* clerical spell */
mtmp->mspec_used = 10 - mtmp->m_lev;
if (mtmp->mspec_used < 2) mtmp->mspec_used = 2;
switch(rn2((int)mtmp->m_lev)) {
/* Other ideas: lightning bolts, towers of flame,
gush of water -3. */
default: /* confuse */
if(Antimagic) {
shieldeff(u.ux, u.uy);
You_feel("momentarily dizzy.");
} else {
dmg = (int)mtmp->m_lev;
if(Half_spell_damage) dmg = (dmg+1) / 2;
make_confused(HConfusion + dmg, TRUE);
}
dmg = 0;
break;
case 12: /* curse random items */
case 11:
case 10:
rndcurse();
dmg = 0;
break;
case 9:
case 8: /* insects */
/* Try for insects, and if there are none
left, go for (sticks to) snakes. -3. */
{
int i;
struct permonst *pm = mkclass(S_ANT,0);
struct monst *mtmp2;
char let = (pm ? S_ANT : S_SNAKE);
for (i = 0; i <= (int) mtmp->m_lev; i++)
if ((pm = mkclass(let,0)) &&
(mtmp2 = makemon(pm, u.ux, u.uy, NO_MM_FLAGS))) {
mtmp2->msleeping = mtmp2->mpeaceful =
mtmp2->mtame = 0;
set_malign(mtmp2);
}
}
dmg = 0;
break;
case 6:
case 7: /* blindness */
/* note: resists_blnd() doesn't apply here */
if (!Blinded) {
int num_eyes = eyecount(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) Your(vision_clears);
dmg = 0;
break;
}
case 4:
case 5: /* wound */
if(Antimagic) {
shieldeff(u.ux, u.uy);
Your("skin itches badly for a moment.");
dmg = 0;
} else {
pline("Wounds appear on your body!");
dmg = d(2,8) + 1;
if (Half_spell_damage) dmg = (dmg+1) / 2;
}
break;
case 3: /* hold */
if (Antimagic || Free_action) {
shieldeff(u.ux, u.uy);
if(multi >= 0)
You("stiffen briefly.");
nomul(-1);
} else {
if (multi >= 0)
You("are frozen in place!");
dmg = 4 + (int)mtmp->m_lev;
if (Half_spell_damage) dmg = (dmg+1) / 2;
nomul(-dmg);
}
dmg = 0;
break;
case 2:
case 1: /* cure self */
if(mtmp->mhp < mtmp->mhpmax) {
if((mtmp->mhp += rnd(8)) > mtmp->mhpmax)
mtmp->mhp = mtmp->mhpmax;
dmg = 0;
break;
} /* else fall through to default case */
}
}
if(dmg) mdamageu(mtmp, dmg);
return(1);
}
#endif /* OVLB */
#ifdef OVL0
/* convert 1..10 to 0..9; add 10 for second group (spell casting) */
#define ad_to_typ(k) (10 + (int)k - 1)
int
buzzmu(mtmp, mattk) /* monster uses spell (ranged) */
register struct monst *mtmp;
register struct attack *mattk;
{
if(mtmp->mcan || mattk->adtyp > AD_SPC2) {
cursetxt(mtmp);
return(0);
}
if(lined_up(mtmp) && rn2(3)) {
nomul(0);
if(mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */
if(canseemon(mtmp))
pline("%s zaps you with a %s!", Monnam(mtmp),
flash_types[ad_to_typ(mattk->adtyp)]);
buzz(-ad_to_typ(mattk->adtyp), (int)mattk->damn,
mtmp->mx, mtmp->my, sgn(tbx), sgn(tby));
} else impossible("Monster spell %d cast", mattk->adtyp-1);
}
return(1);
}
#endif /* OVL0 */
/*mcastu.c*/