Source:NetHack 1.3d/vault.c

Below is the full text to vault.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/vault.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

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