Source:NetHack 1.3d/vault.c

From NetHackWiki
Jump to navigation Jump to search

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

Screenshots and source code from Hack are used under the CWI license.

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 /**/