Source:NetHack 3.0.0/vault.c

From NetHackWiki
Jump to navigation Jump to search

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

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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