Home | History | Annotate | Line # | Download | only in hack
hack.vault.c revision 1.5
      1 /*	$NetBSD: hack.vault.c,v 1.5 2001/03/25 20:44:03 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.vault.c,v 1.5 2001/03/25 20:44:03 jsm Exp $");
     10 #endif				/* not lint */
     11 
     12 #include "hack.h"
     13 #include "extern.h"
     14 #ifdef QUEST
     15 void
     16 setgd( /* mtmp */ )
     17 {				/* struct monst *mtmp; */
     18 }
     19 int
     20 gd_move() {
     21 	return (2);
     22 }
     23 void
     24 gddead()
     25 {
     26 }
     27 void
     28 replgd(mtmp, mtmp2)
     29 	struct monst   *mtmp, *mtmp2;
     30 {
     31 }
     32 void
     33 invault()
     34 {
     35 }
     36 
     37 #else
     38 
     39 
     40 #include "def.mkroom.h"
     41 #define	FCSIZ	(ROWNO+COLNO)
     42 struct fakecorridor {
     43 	xchar           fx, fy, ftyp;
     44 };
     45 
     46 struct egd {
     47 	int             fcbeg, fcend;	/* fcend: first unused pos */
     48 	xchar           gdx, gdy;	/* goal of guard's walk */
     49 	unsigned        gddone:1;
     50 	struct fakecorridor fakecorr[FCSIZ];
     51 };
     52 
     53 static const struct permonst pm_guard =
     54 {"guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd)};
     55 
     56 static struct monst *guard;
     57 static int      gdlevel;
     58 #define	EGD	((struct egd *)(&(guard->mextra[0])))
     59 
     60 static void restfakecorr __P((void));
     61 static int goldincorridor __P((void));
     62 
     63 static void
     64 restfakecorr()
     65 {
     66 	int		fcx, fcy, fcbeg;
     67 	struct rm      *crm;
     68 
     69 	while ((fcbeg = EGD->fcbeg) < EGD->fcend) {
     70 		fcx = EGD->fakecorr[fcbeg].fx;
     71 		fcy = EGD->fakecorr[fcbeg].fy;
     72 		if ((u.ux == fcx && u.uy == fcy) || cansee(fcx, fcy) ||
     73 		    m_at(fcx, fcy))
     74 			return;
     75 		crm = &levl[fcx][fcy];
     76 		crm->typ = EGD->fakecorr[fcbeg].ftyp;
     77 		if (!crm->typ)
     78 			crm->seen = 0;
     79 		newsym(fcx, fcy);
     80 		EGD->fcbeg++;
     81 	}
     82 	/* it seems he left the corridor - let the guard disappear */
     83 	mondead(guard);
     84 	guard = 0;
     85 }
     86 
     87 static int
     88 goldincorridor()
     89 {
     90 	int             fci;
     91 
     92 	for (fci = EGD->fcbeg; fci < EGD->fcend; fci++)
     93 		if (g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy))
     94 			return (1);
     95 	return (0);
     96 }
     97 
     98 void
     99 setgd()
    100 {
    101 	struct monst   *mtmp;
    102 	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
    103 		if (mtmp->isgd) {
    104 			guard = mtmp;
    105 			gdlevel = dlevel;
    106 			return;
    107 		}
    108 	guard = 0;
    109 }
    110 
    111 void
    112 invault()
    113 {
    114 	int tmp = inroom(u.ux, u.uy);
    115 	if (tmp < 0 || rooms[tmp].rtype != VAULT) {
    116 		u.uinvault = 0;
    117 		return;
    118 	}
    119 	if (++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
    120 		char            buf[BUFSZ];
    121 		int		x, y, dd, gx, gy;
    122 
    123 		/* first find the goal for the guard */
    124 		for (dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
    125 			for (y = u.uy - dd; y <= u.uy + dd; y++) {
    126 				if (y < 0 || y > ROWNO - 1)
    127 					continue;
    128 				for (x = u.ux - dd; x <= u.ux + dd; x++) {
    129 					if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
    130 						x = u.ux + dd;
    131 					if (x < 0 || x > COLNO - 1)
    132 						continue;
    133 					if (levl[x][y].typ == CORR)
    134 						goto fnd;
    135 				}
    136 			}
    137 		}
    138 		impossible("Not a single corridor on this level??");
    139 		tele();
    140 		return;
    141 fnd:
    142 		gx = x;
    143 		gy = y;
    144 
    145 		/* next find a good place for a door in the wall */
    146 		x = u.ux;
    147 		y = u.uy;
    148 		while (levl[x][y].typ == ROOM) {
    149 			int             dx, dy;
    150 
    151 			dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
    152 			dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
    153 			if (abs(gx - x) >= abs(gy - y))
    154 				x += dx;
    155 			else
    156 				y += dy;
    157 		}
    158 
    159 		/* make something interesting happen */
    160 		if (!(guard = makemon(&pm_guard, x, y)))
    161 			return;
    162 		guard->isgd = guard->mpeaceful = 1;
    163 		EGD->gddone = 0;
    164 		gdlevel = dlevel;
    165 		if (!cansee(guard->mx, guard->my)) {
    166 			mondead(guard);
    167 			guard = 0;
    168 			return;
    169 		}
    170 		pline("Suddenly one of the Vault's guards enters!");
    171 		pmon(guard);
    172 		do {
    173 			pline("\"Hello stranger, who are you?\" - ");
    174 			getlin(buf);
    175 		} while (!letter(buf[0]));
    176 
    177 		if (!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
    178 			pline("\"Oh, yes - of course. Sorry to have disturbed you.\"");
    179 			mondead(guard);
    180 			guard = 0;
    181 			return;
    182 		}
    183 		clrlin();
    184 		pline("\"I don't know you.\"");
    185 		if (!u.ugold)
    186 			pline("\"Please follow me.\"");
    187 		else {
    188 			pline("\"Most likely all that gold was stolen from this vault.\"");
    189 			pline("\"Please drop your gold (say d$ ) and follow me.\"");
    190 		}
    191 		EGD->gdx = gx;
    192 		EGD->gdy = gy;
    193 		EGD->fcbeg = 0;
    194 		EGD->fakecorr[0].fx = x;
    195 		EGD->fakecorr[0].fy = y;
    196 		EGD->fakecorr[0].ftyp = levl[x][y].typ;
    197 		levl[x][y].typ = DOOR;
    198 		EGD->fcend = 1;
    199 	}
    200 }
    201 
    202 int
    203 gd_move()
    204 {
    205 	int             x, y, dx, dy, gx, gy, nx, ny, typ;
    206 	struct fakecorridor *fcp;
    207 	struct rm      *crm;
    208 	if (!guard || gdlevel != dlevel) {
    209 		impossible("Where is the guard?");
    210 		return (2);	/* died */
    211 	}
    212 	if (u.ugold || goldincorridor())
    213 		return (0);	/* didnt move */
    214 	if (dist(guard->mx, guard->my) > 1 || EGD->gddone) {
    215 		restfakecorr();
    216 		return (0);	/* didnt move */
    217 	}
    218 	x = guard->mx;
    219 	y = guard->my;
    220 	/* look around (hor & vert only) for accessible places */
    221 	for (nx = x - 1; nx <= x + 1; nx++)
    222 		for (ny = y - 1; ny <= y + 1; ny++) {
    223 			if (nx == x || ny == y)
    224 				if (nx != x || ny != y)
    225 					if (isok(nx, ny))
    226 						if (!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
    227 							int             i;
    228 							for (i = EGD->fcbeg; i < EGD->fcend; i++)
    229 								if (EGD->fakecorr[i].fx == nx &&
    230 								    EGD->fakecorr[i].fy == ny)
    231 									goto nextnxy;
    232 							if ((i = inroom(nx, ny)) >= 0 && rooms[i].rtype == VAULT)
    233 								goto nextnxy;
    234 							/*
    235 							 * seems we found a
    236 							 * good place to
    237 							 * leave him alone
    238 							 */
    239 							EGD->gddone = 1;
    240 							if (ACCESSIBLE(typ))
    241 								goto newpos;
    242 							crm->typ = (typ == SCORR) ? CORR : DOOR;
    243 							goto proceed;
    244 						}
    245 	nextnxy:	;
    246 		}
    247 	nx = x;
    248 	ny = y;
    249 	gx = EGD->gdx;
    250 	gy = EGD->gdy;
    251 	dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
    252 	dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
    253 	if (abs(gx - x) >= abs(gy - y))
    254 		nx += dx;
    255 	else
    256 		ny += dy;
    257 
    258 	while ((typ = (crm = &levl[nx][ny])->typ) != 0) {
    259 		/*
    260 		 * in view of the above we must have IS_WALL(typ) or typ ==
    261 		 * POOL
    262 		 */
    263 		/* must be a wall here */
    264 		if (isok(nx + nx - x, ny + ny - y) && typ != POOL &&
    265 		    ZAP_POS(levl[nx + nx - x][ny + ny - y].typ)) {
    266 			crm->typ = DOOR;
    267 			goto proceed;
    268 		}
    269 		if (dy && nx != x) {
    270 			nx = x;
    271 			ny = y + dy;
    272 			continue;
    273 		}
    274 		if (dx && ny != y) {
    275 			ny = y;
    276 			nx = x + dx;
    277 			dy = 0;
    278 			continue;
    279 		}
    280 		/* I don't like this, but ... */
    281 		crm->typ = DOOR;
    282 		goto proceed;
    283 	}
    284 	crm->typ = CORR;
    285 proceed:
    286 	if (cansee(nx, ny)) {
    287 		mnewsym(nx, ny);
    288 		prl(nx, ny);
    289 	}
    290 	fcp = &(EGD->fakecorr[EGD->fcend]);
    291 	if (EGD->fcend++ == FCSIZ)
    292 		panic("fakecorr overflow");
    293 	fcp->fx = nx;
    294 	fcp->fy = ny;
    295 	fcp->ftyp = typ;
    296 newpos:
    297 	if (EGD->gddone)
    298 		nx = ny = 0;
    299 	guard->mx = nx;
    300 	guard->my = ny;
    301 	pmon(guard);
    302 	restfakecorr();
    303 	return (1);
    304 }
    305 
    306 void
    307 gddead()
    308 {
    309 	guard = 0;
    310 }
    311 
    312 void
    313 replgd(mtmp, mtmp2)
    314 	struct monst   *mtmp, *mtmp2;
    315 {
    316 	if (mtmp == guard)
    317 		guard = mtmp2;
    318 }
    319 
    320 #endif	/* QUEST */
    321