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