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