abstract
| - Below is the full text to hack.vault.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.vault.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 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
|