hack.lev.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /* $NetBSD: hack.lev.c,v 1.6 2003/04/02 18:36:37 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.lev.c,v 1.6 2003/04/02 18:36:37 jsm Exp $");
  64. #endif /* not lint */
  65. #include <stdlib.h>
  66. #include <unistd.h>
  67. #include "hack.h"
  68. #include "extern.h"
  69. #include "def.mkroom.h"
  70. #ifndef NOWORM
  71. #include "def.wseg.h"
  72. #endif /* NOWORM */
  73. boolean level_exists[MAXLEVEL + 1];
  74. void
  75. savelev(fd, lev)
  76. int fd;
  77. xchar lev;
  78. {
  79. #ifndef NOWORM
  80. struct wseg *wtmp, *wtmp2;
  81. int tmp;
  82. #endif /* NOWORM */
  83. if (fd < 0)
  84. panic("Save on bad file!"); /* impossible */
  85. if (lev >= 0 && lev <= MAXLEVEL)
  86. level_exists[lev] = TRUE;
  87. bwrite(fd, (char *) &hackpid, sizeof(hackpid));
  88. bwrite(fd, (char *) &lev, sizeof(lev));
  89. bwrite(fd, (char *) levl, sizeof(levl));
  90. bwrite(fd, (char *) &moves, sizeof(long));
  91. bwrite(fd, (char *) &xupstair, sizeof(xupstair));
  92. bwrite(fd, (char *) &yupstair, sizeof(yupstair));
  93. bwrite(fd, (char *) &xdnstair, sizeof(xdnstair));
  94. bwrite(fd, (char *) &ydnstair, sizeof(ydnstair));
  95. savemonchn(fd, fmon);
  96. savegoldchn(fd, fgold);
  97. savetrapchn(fd, ftrap);
  98. saveobjchn(fd, fobj);
  99. saveobjchn(fd, billobjs);
  100. billobjs = 0;
  101. save_engravings(fd);
  102. #ifndef QUEST
  103. bwrite(fd, (char *) rooms, sizeof(rooms));
  104. bwrite(fd, (char *) doors, sizeof(doors));
  105. #endif /* QUEST */
  106. fgold = 0;
  107. ftrap = 0;
  108. fmon = 0;
  109. fobj = 0;
  110. #ifndef NOWORM
  111. bwrite(fd, (char *) wsegs, sizeof(wsegs));
  112. for (tmp = 1; tmp < 32; tmp++) {
  113. for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) {
  114. wtmp2 = wtmp->nseg;
  115. bwrite(fd, (char *) wtmp, sizeof(struct wseg));
  116. }
  117. wsegs[tmp] = 0;
  118. }
  119. bwrite(fd, (char *) wgrowtime, sizeof(wgrowtime));
  120. #endif /* NOWORM */
  121. }
  122. void
  123. bwrite(fd, loc, num)
  124. int fd;
  125. const void *loc;
  126. unsigned num;
  127. {
  128. if (write(fd, loc, num) != (ssize_t)num)
  129. panic("cannot write %u bytes to file #%d", num, fd);
  130. }
  131. void
  132. saveobjchn(fd, otmp)
  133. int fd;
  134. struct obj *otmp;
  135. {
  136. struct obj *otmp2;
  137. unsigned xl;
  138. int minusone = -1;
  139. while (otmp) {
  140. otmp2 = otmp->nobj;
  141. xl = otmp->onamelth;
  142. bwrite(fd, (char *) &xl, sizeof(int));
  143. bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
  144. free((char *) otmp);
  145. otmp = otmp2;
  146. }
  147. bwrite(fd, (char *) &minusone, sizeof(int));
  148. }
  149. void
  150. savemonchn(fd, mtmp)
  151. int fd;
  152. struct monst *mtmp;
  153. {
  154. struct monst *mtmp2;
  155. unsigned xl;
  156. int minusone = -1;
  157. const struct permonst *monbegin = &mons[0];
  158. bwrite(fd, &monbegin, sizeof(monbegin));
  159. while (mtmp) {
  160. mtmp2 = mtmp->nmon;
  161. xl = mtmp->mxlth + mtmp->mnamelth;
  162. bwrite(fd, (char *) &xl, sizeof(int));
  163. bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
  164. if (mtmp->minvent)
  165. saveobjchn(fd, mtmp->minvent);
  166. free((char *) mtmp);
  167. mtmp = mtmp2;
  168. }
  169. bwrite(fd, (char *) &minusone, sizeof(int));
  170. }
  171. void
  172. savegoldchn(fd, gold)
  173. int fd;
  174. struct gold *gold;
  175. {
  176. struct gold *gold2;
  177. while (gold) {
  178. gold2 = gold->ngold;
  179. bwrite(fd, (char *) gold, sizeof(struct gold));
  180. free((char *) gold);
  181. gold = gold2;
  182. }
  183. bwrite(fd, nul, sizeof(struct gold));
  184. }
  185. void
  186. savetrapchn(fd, trap)
  187. int fd;
  188. struct trap *trap;
  189. {
  190. struct trap *trap2;
  191. while (trap) {
  192. trap2 = trap->ntrap;
  193. bwrite(fd, (char *) trap, sizeof(struct trap));
  194. free((char *) trap);
  195. trap = trap2;
  196. }
  197. bwrite(fd, nul, sizeof(struct trap));
  198. }
  199. void
  200. getlev(fd, pid, lev)
  201. int fd, pid;
  202. xchar lev;
  203. {
  204. struct gold *gold;
  205. struct trap *trap;
  206. #ifndef NOWORM
  207. struct wseg *wtmp;
  208. #endif /* NOWORM */
  209. int tmp;
  210. long omoves;
  211. int hpid;
  212. xchar dlvl;
  213. /* First some sanity checks */
  214. mread(fd, (char *) &hpid, sizeof(hpid));
  215. mread(fd, (char *) &dlvl, sizeof(dlvl));
  216. if ((pid && pid != hpid) || (lev && dlvl != lev)) {
  217. pline("Strange, this map is not as I remember it.");
  218. pline("Somebody is trying some trickery here ...");
  219. pline("This game is void ...");
  220. done("tricked");
  221. }
  222. fgold = 0;
  223. ftrap = 0;
  224. mread(fd, (char *) levl, sizeof(levl));
  225. mread(fd, (char *) &omoves, sizeof(omoves));
  226. mread(fd, (char *) &xupstair, sizeof(xupstair));
  227. mread(fd, (char *) &yupstair, sizeof(yupstair));
  228. mread(fd, (char *) &xdnstair, sizeof(xdnstair));
  229. mread(fd, (char *) &ydnstair, sizeof(ydnstair));
  230. fmon = restmonchn(fd);
  231. /* regenerate animals while on another level */
  232. {
  233. long tmoves = (moves > omoves) ? moves - omoves : 0;
  234. struct monst *mtmp, *mtmp2;
  235. for (mtmp = fmon; mtmp; mtmp = mtmp2) {
  236. long newhp; /* tmoves may be very large */
  237. mtmp2 = mtmp->nmon;
  238. if (strchr(genocided, mtmp->data->mlet)) {
  239. mondead(mtmp);
  240. continue;
  241. }
  242. if (mtmp->mtame && tmoves > 250) {
  243. mtmp->mtame = 0;
  244. mtmp->mpeaceful = 0;
  245. }
  246. newhp = mtmp->mhp +
  247. (strchr(MREGEN, mtmp->data->mlet) ? tmoves : tmoves / 20);
  248. if (newhp > mtmp->mhpmax)
  249. mtmp->mhp = mtmp->mhpmax;
  250. else
  251. mtmp->mhp = newhp;
  252. }
  253. }
  254. setgd();
  255. gold = newgold();
  256. mread(fd, (char *) gold, sizeof(struct gold));
  257. while (gold->gx) {
  258. gold->ngold = fgold;
  259. fgold = gold;
  260. gold = newgold();
  261. mread(fd, (char *) gold, sizeof(struct gold));
  262. }
  263. free((char *) gold);
  264. trap = newtrap();
  265. mread(fd, (char *) trap, sizeof(struct trap));
  266. while (trap->tx) {
  267. trap->ntrap = ftrap;
  268. ftrap = trap;
  269. trap = newtrap();
  270. mread(fd, (char *) trap, sizeof(struct trap));
  271. }
  272. free((char *) trap);
  273. fobj = restobjchn(fd);
  274. billobjs = restobjchn(fd);
  275. rest_engravings(fd);
  276. #ifndef QUEST
  277. mread(fd, (char *) rooms, sizeof(rooms));
  278. mread(fd, (char *) doors, sizeof(doors));
  279. #endif /* QUEST */
  280. #ifndef NOWORM
  281. mread(fd, (char *) wsegs, sizeof(wsegs));
  282. for (tmp = 1; tmp < 32; tmp++)
  283. if (wsegs[tmp]) {
  284. wheads[tmp] = wsegs[tmp] = wtmp = newseg();
  285. while (1) {
  286. mread(fd, (char *) wtmp, sizeof(struct wseg));
  287. if (!wtmp->nseg)
  288. break;
  289. wheads[tmp]->nseg = wtmp = newseg();
  290. wheads[tmp] = wtmp;
  291. }
  292. }
  293. mread(fd, (char *) wgrowtime, sizeof(wgrowtime));
  294. #endif /* NOWORM */
  295. }
  296. void
  297. mread(fd, buf, len)
  298. int fd;
  299. char *buf;
  300. unsigned len;
  301. {
  302. int rlen;
  303. rlen = read(fd, buf, (int) len);
  304. if (rlen != (int)len) {
  305. pline("Read %d instead of %u bytes.\n", rlen, len);
  306. if (restoring) {
  307. (void) unlink(SAVEF);
  308. error("Error restoring old game.");
  309. }
  310. panic("Error reading level file.");
  311. }
  312. }
  313. void
  314. mklev()
  315. {
  316. if (getbones())
  317. return;
  318. in_mklev = TRUE;
  319. makelevel();
  320. in_mklev = FALSE;
  321. }