1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
/* $NetBSD: hack.wizard.c,v 1.4 1997/10/19 16:59:28 christos Exp $ */
/*
* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.wizard.c,v 1.4 1997/10/19 16:59:28 christos Exp $");
#endif /* not lint */
/* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */
#include "hack.h"
#include "extern.h"
#define WIZSHOT 6 /* one chance in WIZSHOT that wizard will try
* magic */
#define BOLT_LIM 8 /* from this distance D and 1 will try to hit
* you */
const char wizapp[] = "@DNPTUVXcemntx";
/* If he has found the Amulet, make the wizard appear after some time */
void
amulet()
{
struct obj *otmp;
struct monst *mtmp;
if (!flags.made_amulet || !flags.no_of_wizards)
return;
/* find wizard, and wake him if necessary */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (mtmp->data->mlet == '1' && mtmp->msleep && !rn2(40))
for (otmp = invent; otmp; otmp = otmp->nobj)
if (otmp->olet == AMULET_SYM && !otmp->spe) {
mtmp->msleep = 0;
if (dist(mtmp->mx, mtmp->my) > 2)
pline(
"You get the creepy feeling that somebody noticed your taking the Amulet."
);
return;
}
}
int
wiz_hit(mtmp)
struct monst *mtmp;
{
/* if we have stolen or found the amulet, we disappear */
if (mtmp->minvent && mtmp->minvent->olet == AMULET_SYM &&
mtmp->minvent->spe == 0) {
/* vanish -- very primitive */
fall_down(mtmp);
return (1);
}
/* if it is lying around someplace, we teleport to it */
if (!carrying(AMULET_OF_YENDOR)) {
struct obj *otmp;
for (otmp = fobj; otmp; otmp = otmp->nobj)
if (otmp->olet == AMULET_SYM && !otmp->spe) {
if ((u.ux != otmp->ox || u.uy != otmp->oy) &&
!m_at(otmp->ox, otmp->oy)) {
/* teleport to it and pick it up */
mtmp->mx = otmp->ox;
mtmp->my = otmp->oy;
freeobj(otmp);
mpickobj(mtmp, otmp);
pmon(mtmp);
return (0);
}
goto hithim;
}
return (0); /* we don't know where it is */
}
hithim:
if (rn2(2)) { /* hit - perhaps steal */
/*
* if hit 1/20 chance of stealing amulet & vanish - amulet is
* on level 26 again.
*/
if (hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd))
&& !rn2(20) && stealamulet(mtmp))
(void)0;
} else
inrange(mtmp); /* try magic */
return (0);
}
void
inrange(mtmp)
struct monst *mtmp;
{
schar tx, ty;
/* do nothing if cancelled (but make '1' say something) */
if (mtmp->data->mlet != '1' && mtmp->mcan)
return;
/* spit fire only when both in a room or both in a corridor */
if (inroom(u.ux, u.uy) != inroom(mtmp->mx, mtmp->my))
return;
tx = u.ux - mtmp->mx;
ty = u.uy - mtmp->my;
if ((!tx && abs(ty) < BOLT_LIM) || (!ty && abs(tx) < BOLT_LIM)
|| (abs(tx) == abs(ty) && abs(tx) < BOLT_LIM)) {
switch (mtmp->data->mlet) {
case 'D':
/* spit fire in the direction of @ (not nec. hitting) */
buzz(-1, mtmp->mx, mtmp->my, sgn(tx), sgn(ty));
break;
case '1':
if (rn2(WIZSHOT))
break;
/*
* if you zapped wizard with wand of cancellation, he
* has to shake off the effects before he can throw
* spells successfully. 1/2 the time they fail
* anyway
*/
if (mtmp->mcan || rn2(2)) {
if (canseemon(mtmp))
pline("%s makes a gesture, then curses.",
Monnam(mtmp));
else
pline("You hear mumbled cursing.");
if (!rn2(3)) {
mtmp->mspeed = 0;
mtmp->minvis = 0;
}
if (!rn2(3))
mtmp->mcan = 0;
} else {
if (canseemon(mtmp)) {
if (!rn2(6) && !Invis) {
pline("%s hypnotizes you.", Monnam(mtmp));
nomul(rn2(3) + 3);
break;
} else
pline("%s chants an incantation.",
Monnam(mtmp));
} else
pline("You hear a mumbled incantation.");
switch (rn2(Invis ? 5 : 6)) {
case 0:
/*
* create a nasty monster from a deep
* level
*/
/*
* (for the moment, 'nasty' is not
* implemented)
*/
(void) makemon((struct permonst *) 0, u.ux, u.uy);
break;
case 1:
pline("\"Destroy the thief, my pets!\"");
aggravate(); /* aggravate all the
* monsters */
/* fall into next case */
case 2:
if (flags.no_of_wizards == 1 && rnd(5) == 0)
/*
* if only 1 wizard, clone
* himself
*/
clonewiz(mtmp);
break;
case 3:
if (mtmp->mspeed == MSLOW)
mtmp->mspeed = 0;
else
mtmp->mspeed = MFAST;
break;
case 4:
mtmp->minvis = 1;
break;
case 5:
/* Only if not Invisible */
pline("You hear a clap of thunder!");
/*
* shoot a bolt of fire or cold, or a
* sleep ray
*/
buzz(-rnd(3), mtmp->mx, mtmp->my, sgn(tx), sgn(ty));
break;
}
}
}
if (u.uhp < 1)
done_in_by(mtmp);
}
}
void
aggravate()
{
struct monst *mtmp;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
mtmp->msleep = 0;
if (mtmp->mfroz && !rn2(5))
mtmp->mfroz = 0;
}
}
void
clonewiz(mtmp)
struct monst *mtmp;
{
struct monst *mtmp2;
if ((mtmp2 = makemon(PM_WIZARD, mtmp->mx, mtmp->my)) != NULL) {
flags.no_of_wizards = 2;
unpmon(mtmp2);
mtmp2->mappearance = wizapp[rn2(sizeof(wizapp) - 1)];
pmon(mtmp);
}
}
|