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