hack.vault.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /* $NetBSD: hack.vault.c,v 1.7 2004/01/27 20:30:29 jsm Exp $ */
  2. /*
  3. * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
  4. * Amsterdam
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are
  9. * met:
  10. *
  11. * - Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the following disclaimer.
  13. *
  14. * - Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * - Neither the name of the Stichting Centrum voor Wiskunde en
  19. * Informatica, nor the names of its contributors may be used to endorse or
  20. * promote products derived from this software without specific prior
  21. * written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  24. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  25. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  26. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  27. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  28. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  29. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  30. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  31. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  32. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. /*
  36. * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
  37. * All rights reserved.
  38. *
  39. * Redistribution and use in source and binary forms, with or without
  40. * modification, are permitted provided that the following conditions
  41. * are met:
  42. * 1. Redistributions of source code must retain the above copyright
  43. * notice, this list of conditions and the following disclaimer.
  44. * 2. Redistributions in binary form must reproduce the above copyright
  45. * notice, this list of conditions and the following disclaimer in the
  46. * documentation and/or other materials provided with the distribution.
  47. * 3. The name of the author may not be used to endorse or promote products
  48. * derived from this software without specific prior written permission.
  49. *
  50. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  51. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  52. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  53. * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  54. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  55. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  56. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  57. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  58. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  59. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60. */
  61. #include <sys/cdefs.h>
  62. #ifndef lint
  63. __RCSID("$NetBSD: hack.vault.c,v 1.7 2004/01/27 20:30:29 jsm Exp $");
  64. #endif /* not lint */
  65. #include "hack.h"
  66. #include "extern.h"
  67. #ifdef QUEST
  68. void
  69. setgd( /* mtmp */ )
  70. { /* struct monst *mtmp; */
  71. }
  72. int
  73. gd_move() {
  74. return (2);
  75. }
  76. void
  77. gddead()
  78. {
  79. }
  80. void
  81. replgd(mtmp, mtmp2)
  82. struct monst *mtmp, *mtmp2;
  83. {
  84. }
  85. void
  86. invault()
  87. {
  88. }
  89. #else
  90. #include "def.mkroom.h"
  91. #define FCSIZ (ROWNO+COLNO)
  92. struct fakecorridor {
  93. xchar fx, fy, ftyp;
  94. };
  95. struct egd {
  96. int fcbeg, fcend; /* fcend: first unused pos */
  97. xchar gdx, gdy; /* goal of guard's walk */
  98. unsigned gddone:1;
  99. struct fakecorridor fakecorr[FCSIZ];
  100. };
  101. static const struct permonst pm_guard =
  102. {"guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd)};
  103. static struct monst *guard;
  104. static int gdlevel;
  105. #define EGD ((struct egd *)(&(guard->mextra[0])))
  106. static void restfakecorr(void);
  107. static int goldincorridor(void);
  108. static void
  109. restfakecorr()
  110. {
  111. int fcx, fcy, fcbeg;
  112. struct rm *crm;
  113. while ((fcbeg = EGD->fcbeg) < EGD->fcend) {
  114. fcx = EGD->fakecorr[fcbeg].fx;
  115. fcy = EGD->fakecorr[fcbeg].fy;
  116. if ((u.ux == fcx && u.uy == fcy) || cansee(fcx, fcy) ||
  117. m_at(fcx, fcy))
  118. return;
  119. crm = &levl[fcx][fcy];
  120. crm->typ = EGD->fakecorr[fcbeg].ftyp;
  121. if (!crm->typ)
  122. crm->seen = 0;
  123. newsym(fcx, fcy);
  124. EGD->fcbeg++;
  125. }
  126. /* it seems he left the corridor - let the guard disappear */
  127. mondead(guard);
  128. guard = 0;
  129. }
  130. static int
  131. goldincorridor()
  132. {
  133. int fci;
  134. for (fci = EGD->fcbeg; fci < EGD->fcend; fci++)
  135. if (g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy))
  136. return (1);
  137. return (0);
  138. }
  139. void
  140. setgd()
  141. {
  142. struct monst *mtmp;
  143. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  144. if (mtmp->isgd) {
  145. guard = mtmp;
  146. gdlevel = dlevel;
  147. return;
  148. }
  149. guard = 0;
  150. }
  151. void
  152. invault()
  153. {
  154. int tmp = inroom(u.ux, u.uy);
  155. if (tmp < 0 || rooms[tmp].rtype != VAULT) {
  156. u.uinvault = 0;
  157. return;
  158. }
  159. if (++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
  160. char buf[BUFSZ];
  161. int x, y, dd, gx, gy;
  162. /* first find the goal for the guard */
  163. for (dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
  164. for (y = u.uy - dd; y <= u.uy + dd; y++) {
  165. if (y < 0 || y > ROWNO - 1)
  166. continue;
  167. for (x = u.ux - dd; x <= u.ux + dd; x++) {
  168. if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
  169. x = u.ux + dd;
  170. if (x < 0 || x > COLNO - 1)
  171. continue;
  172. if (levl[x][y].typ == CORR)
  173. goto fnd;
  174. }
  175. }
  176. }
  177. impossible("Not a single corridor on this level??");
  178. tele();
  179. return;
  180. fnd:
  181. gx = x;
  182. gy = y;
  183. /* next find a good place for a door in the wall */
  184. x = u.ux;
  185. y = u.uy;
  186. while (levl[x][y].typ == ROOM) {
  187. int dx, dy;
  188. dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
  189. dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
  190. if (abs(gx - x) >= abs(gy - y))
  191. x += dx;
  192. else
  193. y += dy;
  194. }
  195. /* make something interesting happen */
  196. if (!(guard = makemon(&pm_guard, x, y)))
  197. return;
  198. guard->isgd = guard->mpeaceful = 1;
  199. EGD->gddone = 0;
  200. gdlevel = dlevel;
  201. if (!cansee(guard->mx, guard->my)) {
  202. mondead(guard);
  203. guard = 0;
  204. return;
  205. }
  206. pline("Suddenly one of the Vault's guards enters!");
  207. pmon(guard);
  208. do {
  209. pline("\"Hello stranger, who are you?\" - ");
  210. getlin(buf);
  211. } while (!letter(buf[0]));
  212. if (!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
  213. pline("\"Oh, yes - of course. Sorry to have disturbed you.\"");
  214. mondead(guard);
  215. guard = 0;
  216. return;
  217. }
  218. clrlin();
  219. pline("\"I don't know you.\"");
  220. if (!u.ugold)
  221. pline("\"Please follow me.\"");
  222. else {
  223. pline("\"Most likely all that gold was stolen from this vault.\"");
  224. pline("\"Please drop your gold (say d$ ) and follow me.\"");
  225. }
  226. EGD->gdx = gx;
  227. EGD->gdy = gy;
  228. EGD->fcbeg = 0;
  229. EGD->fakecorr[0].fx = x;
  230. EGD->fakecorr[0].fy = y;
  231. EGD->fakecorr[0].ftyp = levl[x][y].typ;
  232. levl[x][y].typ = DOOR;
  233. EGD->fcend = 1;
  234. }
  235. }
  236. int
  237. gd_move()
  238. {
  239. int x, y, dx, dy, gx, gy, nx, ny, typ;
  240. struct fakecorridor *fcp;
  241. struct rm *crm;
  242. if (!guard || gdlevel != dlevel) {
  243. impossible("Where is the guard?");
  244. return (2); /* died */
  245. }
  246. if (u.ugold || goldincorridor())
  247. return (0); /* didnt move */
  248. if (dist(guard->mx, guard->my) > 1 || EGD->gddone) {
  249. restfakecorr();
  250. return (0); /* didnt move */
  251. }
  252. x = guard->mx;
  253. y = guard->my;
  254. /* look around (hor & vert only) for accessible places */
  255. for (nx = x - 1; nx <= x + 1; nx++)
  256. for (ny = y - 1; ny <= y + 1; ny++) {
  257. if (nx == x || ny == y)
  258. if (nx != x || ny != y)
  259. if (isok(nx, ny))
  260. if (!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
  261. int i;
  262. for (i = EGD->fcbeg; i < EGD->fcend; i++)
  263. if (EGD->fakecorr[i].fx == nx &&
  264. EGD->fakecorr[i].fy == ny)
  265. goto nextnxy;
  266. if ((i = inroom(nx, ny)) >= 0 && rooms[i].rtype == VAULT)
  267. goto nextnxy;
  268. /*
  269. * seems we found a
  270. * good place to
  271. * leave him alone
  272. */
  273. EGD->gddone = 1;
  274. if (ACCESSIBLE(typ))
  275. goto newpos;
  276. crm->typ = (typ == SCORR) ? CORR : DOOR;
  277. goto proceed;
  278. }
  279. nextnxy: ;
  280. }
  281. nx = x;
  282. ny = y;
  283. gx = EGD->gdx;
  284. gy = EGD->gdy;
  285. dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
  286. dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
  287. if (abs(gx - x) >= abs(gy - y))
  288. nx += dx;
  289. else
  290. ny += dy;
  291. while ((typ = (crm = &levl[nx][ny])->typ) != 0) {
  292. /*
  293. * in view of the above we must have IS_WALL(typ) or typ ==
  294. * POOL
  295. */
  296. /* must be a wall here */
  297. if (isok(nx + nx - x, ny + ny - y) && typ != POOL &&
  298. ZAP_POS(levl[nx + nx - x][ny + ny - y].typ)) {
  299. crm->typ = DOOR;
  300. goto proceed;
  301. }
  302. if (dy && nx != x) {
  303. nx = x;
  304. ny = y + dy;
  305. continue;
  306. }
  307. if (dx && ny != y) {
  308. ny = y;
  309. nx = x + dx;
  310. dy = 0;
  311. continue;
  312. }
  313. /* I don't like this, but ... */
  314. crm->typ = DOOR;
  315. goto proceed;
  316. }
  317. crm->typ = CORR;
  318. proceed:
  319. if (cansee(nx, ny)) {
  320. mnewsym(nx, ny);
  321. prl(nx, ny);
  322. }
  323. fcp = &(EGD->fakecorr[EGD->fcend]);
  324. if (EGD->fcend++ == FCSIZ)
  325. panic("fakecorr overflow");
  326. fcp->fx = nx;
  327. fcp->fy = ny;
  328. fcp->ftyp = typ;
  329. newpos:
  330. if (EGD->gddone)
  331. nx = ny = 0;
  332. guard->mx = nx;
  333. guard->my = ny;
  334. pmon(guard);
  335. restfakecorr();
  336. return (1);
  337. }
  338. void
  339. gddead()
  340. {
  341. guard = 0;
  342. }
  343. void
  344. replgd(mtmp, mtmp2)
  345. struct monst *mtmp, *mtmp2;
  346. {
  347. if (mtmp == guard)
  348. guard = mtmp2;
  349. }
  350. #endif /* QUEST */