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