home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume14 / umoria4 / part08 < prev    next >
Internet Message Format  |  1992-08-31  |  57KB

  1. Path: uunet!zephyr.ens.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v14i040:  umoria4 - single player dungeon simulation (ver. 5.5), Part08/39
  5. Message-ID: <3398@master.CNA.TEK.COM>
  6. Date: 20 Aug 92 18:03:13 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1953
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: grabiner@math.harvard.edu (David Grabiner)
  12. Posting-number: Volume 14, Issue 40
  13. Archive-name: umoria4/Part08
  14. Supersedes: umoria3: Volume 9, Issue 55-97; Volume 10, Issue 15-17
  15. Environment: Curses, Unix, Mac, MS-DOS, Atari-ST, Amiga, VMS
  16.  
  17.  
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 8 (of 39)."
  26. # Contents:  source/save.c source/tables.c
  27. # Wrapped by billr@saab on Thu Aug 20 09:11:27 1992
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'source/save.c' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'source/save.c'\"
  31. else
  32. echo shar: Extracting \"'source/save.c'\" \(41704 characters\)
  33. sed "s/^X//" >'source/save.c' <<'END_OF_FILE'
  34. X/* source/save.c: save and restore games and monster memory info
  35. X
  36. X   Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  37. X
  38. X   This software may be copied and distributed for educational, research, and
  39. X   not for profit purposes provided that this copyright and statement are
  40. X   included in all such copies. */
  41. X
  42. X/* For debugging the savefile code on systems with broken compilers.  */
  43. X#if 0
  44. X#define DEBUG(x)    x
  45. X#else
  46. X#define DEBUG(x)
  47. X#endif
  48. X
  49. X#include <stdio.h>
  50. X
  51. X#ifndef STDIO_LOADED
  52. X#define STDIO_LOADED
  53. X#endif
  54. X
  55. X#ifdef __TURBOC__
  56. X#include    <io.h>
  57. X#endif /* __TURBOC__ */
  58. X#include "config.h"
  59. X#include "constant.h"
  60. X#include "types.h"
  61. X
  62. X#ifndef USG
  63. X/* stuff only needed for Berkeley UNIX */
  64. X#include <sys/types.h>
  65. X#include <sys/file.h>
  66. X#include <sys/param.h>
  67. X#endif
  68. X
  69. X#ifdef VMS
  70. X#include <string.h>
  71. X#include <file.h>
  72. X#else
  73. X#ifdef USG
  74. X#ifndef ATARIST_MWC
  75. X#include <string.h>
  76. X#ifndef ATARIST_TC
  77. X#include <fcntl.h>
  78. X#endif
  79. X#else
  80. X#include "string.h"
  81. X#endif
  82. X#else
  83. X#include <strings.h>
  84. X#endif
  85. X#endif
  86. X
  87. X/* This must be included after fcntl.h, which has a prototype for `open'
  88. X   on some systems.  Otherwise, the `open' prototype conflicts with the
  89. X   `topen' declaration.  */
  90. X#include "externs.h"
  91. X
  92. X#ifdef ATARIST_TC
  93. X#include <time.h>
  94. X#endif
  95. X
  96. XDEBUG(static FILE *logfile);
  97. X
  98. X#if defined(LINT_ARGS)
  99. Xstatic int sv_write(void);
  100. Xstatic void wr_byte(int8u);
  101. Xstatic void wr_short(int16u);
  102. Xstatic void wr_long(int32u);
  103. Xstatic void wr_bytes(int8u *, int);
  104. Xstatic void wr_string(char *);
  105. Xstatic void wr_shorts(int16u *, int);
  106. Xstatic void wr_item(inven_type *);
  107. Xstatic void wr_monster(monster_type *);
  108. Xstatic void rd_byte(int8u *);
  109. Xstatic void rd_short(int16u *);
  110. Xstatic void rd_long(int32u *);
  111. Xstatic void rd_bytes(int8u *, int);
  112. Xstatic void rd_string(char *);
  113. Xstatic void rd_shorts(int16u *, int);
  114. Xstatic void rd_item(inven_type *);
  115. Xstatic void rd_monster(monster_type *);
  116. X#else
  117. Xstatic int sv_write();
  118. Xstatic void wr_byte();
  119. Xstatic void wr_short();
  120. Xstatic void wr_long();
  121. Xstatic void wr_bytes();
  122. Xstatic void wr_string();
  123. Xstatic void wr_shorts();
  124. Xstatic void wr_item();
  125. Xstatic void wr_monster();
  126. Xstatic void rd_byte();
  127. Xstatic void rd_short();
  128. Xstatic void rd_long();
  129. Xstatic void rd_bytes();
  130. Xstatic void rd_string();
  131. Xstatic void rd_shorts();
  132. Xstatic void rd_item();
  133. Xstatic void rd_monster();
  134. X#endif
  135. X
  136. X#if !defined(ATARIST_MWC)
  137. X#ifdef MAC
  138. X#include <time.h>
  139. X#else
  140. Xlong time();
  141. X#endif
  142. X#else
  143. Xchar *malloc();
  144. X#endif
  145. X
  146. X/* these are used for the save file, to avoid having to pass them to every
  147. X   procedure */
  148. Xstatic FILE *fileptr;
  149. Xstatic int8u xor_byte;
  150. Xstatic int from_savefile;    /* can overwrite old savefile when save */
  151. Xstatic int32u start_time;    /* time that play started */
  152. X
  153. X/* This save package was brought to by            -JWT-
  154. X   and                            -RAK-
  155. X   and has been completely rewritten for UNIX by    -JEW-  */
  156. X/* and has been completely rewritten again by     -CJS-    */
  157. X/* and completely rewritten again! for portability by -JEW- */
  158. X
  159. Xstatic int sv_write()
  160. X{
  161. X  int32u l;
  162. X  register int i, j;
  163. X  int count;
  164. X  int8u char_tmp, prev_char;
  165. X  register cave_type *c_ptr;
  166. X  register recall_type *r_ptr;
  167. X  struct stats *s_ptr;
  168. X  register struct flags *f_ptr;
  169. X  store_type *st_ptr;
  170. X  struct misc *m_ptr;
  171. X#if defined(MSDOS) || defined(ATARI_ST)
  172. X  inven_type *t_ptr;
  173. X#endif
  174. X
  175. X  /* clear the death flag when creating a HANGUP save file, so that player
  176. X     can see tombstone when restart */
  177. X  if (eof_flag)
  178. X    death = FALSE;
  179. X
  180. X  l = 0;
  181. X  if (find_cut)
  182. X    l |= 0x1;
  183. X  if (find_examine)
  184. X    l |= 0x2;
  185. X  if (find_prself)
  186. X    l |= 0x4;
  187. X  if (find_bound)
  188. X    l |= 0x8;
  189. X  if (prompt_carry_flag)
  190. X    l |= 0x10;
  191. X  if (rogue_like_commands)
  192. X    l |= 0x20;
  193. X  if (show_weight_flag)
  194. X    l |= 0x40;
  195. X  if (highlight_seams)
  196. X    l |= 0x80;
  197. X  if (find_ignore_doors)
  198. X    l |= 0x100;
  199. X  if (sound_beep_flag)
  200. X    l |= 0x200;
  201. X  if (display_counts)
  202. X    l |= 0x400;
  203. X  if (death)
  204. X    l |= 0x80000000L;    /* Sign bit */
  205. X  if (total_winner)
  206. X    l |= 0x40000000L;
  207. X
  208. X  for (i = 0; i < MAX_CREATURES; i++)
  209. X    {
  210. X      r_ptr = &c_recall[i];
  211. X      if (r_ptr->r_cmove || r_ptr->r_cdefense || r_ptr->r_kills ||
  212. X      r_ptr->r_spells || r_ptr->r_deaths || r_ptr->r_attacks[0] ||
  213. X      r_ptr->r_attacks[1] || r_ptr->r_attacks[2] || r_ptr->r_attacks[3])
  214. X    {
  215. X      wr_short((int16u)i);
  216. X      wr_long(r_ptr->r_cmove);
  217. X      wr_long(r_ptr->r_spells);
  218. X      wr_short(r_ptr->r_kills);
  219. X      wr_short(r_ptr->r_deaths);
  220. X      wr_short(r_ptr->r_cdefense);
  221. X      wr_byte(r_ptr->r_wake);
  222. X      wr_byte(r_ptr->r_ignore);
  223. X      wr_bytes(r_ptr->r_attacks, MAX_MON_NATTACK);
  224. X    }
  225. X    }
  226. X  wr_short((int16u)0xFFFF); /* sentinel to indicate no more monster info */
  227. X
  228. X  wr_long(l);
  229. X
  230. X  m_ptr = &py.misc;
  231. X  wr_string(m_ptr->name);
  232. X  wr_byte(m_ptr->male);
  233. X  wr_long((int32u)m_ptr->au);
  234. X  wr_long((int32u)m_ptr->max_exp);
  235. X  wr_long((int32u)m_ptr->exp);
  236. X  wr_short(m_ptr->exp_frac);
  237. X  wr_short(m_ptr->age);
  238. X  wr_short(m_ptr->ht);
  239. X  wr_short(m_ptr->wt);
  240. X  wr_short(m_ptr->lev);
  241. X  wr_short(m_ptr->max_dlv);
  242. X  wr_short((int16u)m_ptr->srh);
  243. X  wr_short((int16u)m_ptr->fos);
  244. X  wr_short((int16u)m_ptr->bth);
  245. X  wr_short((int16u)m_ptr->bthb);
  246. X  wr_short((int16u)m_ptr->mana);
  247. X  wr_short((int16u)m_ptr->mhp);
  248. X  wr_short((int16u)m_ptr->ptohit);
  249. X  wr_short((int16u)m_ptr->ptodam);
  250. X  wr_short((int16u)m_ptr->pac);
  251. X  wr_short((int16u)m_ptr->ptoac);
  252. X  wr_short((int16u)m_ptr->dis_th);
  253. X  wr_short((int16u)m_ptr->dis_td);
  254. X  wr_short((int16u)m_ptr->dis_ac);
  255. X  wr_short((int16u)m_ptr->dis_tac);
  256. X  wr_short((int16u)m_ptr->disarm);
  257. X  wr_short((int16u)m_ptr->save);
  258. X  wr_short((int16u)m_ptr->sc);
  259. X  wr_short((int16u)m_ptr->stl);
  260. X  wr_byte(m_ptr->pclass);
  261. X  wr_byte(m_ptr->prace);
  262. X  wr_byte(m_ptr->hitdie);
  263. X  wr_byte(m_ptr->expfact);
  264. X  wr_short((int16u)m_ptr->cmana);
  265. X  wr_short(m_ptr->cmana_frac);
  266. X  wr_short((int16u)m_ptr->chp);
  267. X  wr_short(m_ptr->chp_frac);
  268. X  for (i = 0; i < 4; i++)
  269. X    wr_string (m_ptr->history[i]);
  270. X
  271. X  s_ptr = &py.stats;
  272. X  wr_bytes(s_ptr->max_stat, 6);
  273. X  wr_bytes(s_ptr->cur_stat, 6);
  274. X  wr_shorts((int16u *)s_ptr->mod_stat, 6);
  275. X  wr_bytes(s_ptr->use_stat, 6);
  276. X
  277. X  f_ptr = &py.flags;
  278. X  wr_long(f_ptr->status);
  279. X  wr_short((int16u)f_ptr->rest);
  280. X  wr_short((int16u)f_ptr->blind);
  281. X  wr_short((int16u)f_ptr->paralysis);
  282. X  wr_short((int16u)f_ptr->confused);
  283. X  wr_short((int16u)f_ptr->food);
  284. X  wr_short((int16u)f_ptr->food_digested);
  285. X  wr_short((int16u)f_ptr->protection);
  286. X  wr_short((int16u)f_ptr->speed);
  287. X  wr_short((int16u)f_ptr->fast);
  288. X  wr_short((int16u)f_ptr->slow);
  289. X  wr_short((int16u)f_ptr->afraid);
  290. X  wr_short((int16u)f_ptr->poisoned);
  291. X  wr_short((int16u)f_ptr->image);
  292. X  wr_short((int16u)f_ptr->protevil);
  293. X  wr_short((int16u)f_ptr->invuln);
  294. X  wr_short((int16u)f_ptr->hero);
  295. X  wr_short((int16u)f_ptr->shero);
  296. X  wr_short((int16u)f_ptr->blessed);
  297. X  wr_short((int16u)f_ptr->resist_heat);
  298. X  wr_short((int16u)f_ptr->resist_cold);
  299. X  wr_short((int16u)f_ptr->detect_inv);
  300. X  wr_short((int16u)f_ptr->word_recall);
  301. X  wr_short((int16u)f_ptr->see_infra);
  302. X  wr_short((int16u)f_ptr->tim_infra);
  303. X  wr_byte(f_ptr->see_inv);
  304. X  wr_byte(f_ptr->teleport);
  305. X  wr_byte(f_ptr->free_act);
  306. X  wr_byte(f_ptr->slow_digest);
  307. X  wr_byte(f_ptr->aggravate);
  308. X  wr_byte(f_ptr->fire_resist);
  309. X  wr_byte(f_ptr->cold_resist);
  310. X  wr_byte(f_ptr->acid_resist);
  311. X  wr_byte(f_ptr->regenerate);
  312. X  wr_byte(f_ptr->lght_resist);
  313. X  wr_byte(f_ptr->ffall);
  314. X  wr_byte(f_ptr->sustain_str);
  315. X  wr_byte(f_ptr->sustain_int);
  316. X  wr_byte(f_ptr->sustain_wis);
  317. X  wr_byte(f_ptr->sustain_con);
  318. X  wr_byte(f_ptr->sustain_dex);
  319. X  wr_byte(f_ptr->sustain_chr);
  320. X  wr_byte(f_ptr->confuse_monster);
  321. X  wr_byte(f_ptr->new_spells);
  322. X
  323. X  wr_short((int16u)missile_ctr);
  324. X  wr_long((int32u)turn);
  325. X  wr_short((int16u)inven_ctr);
  326. X  for (i = 0; i < inven_ctr; i++)
  327. X    wr_item(&inventory[i]);
  328. X  for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++)
  329. X    wr_item(&inventory[i]);
  330. X  wr_short((int16u)inven_weight);
  331. X  wr_short((int16u)equip_ctr);
  332. X  wr_long(spell_learned);
  333. X  wr_long(spell_worked);
  334. X  wr_long(spell_forgotten);
  335. X  wr_bytes(spell_order, 32);
  336. X  wr_bytes(object_ident, OBJECT_IDENT_SIZE);
  337. X  wr_long(randes_seed);
  338. X  wr_long(town_seed);
  339. X  wr_short((int16u)last_msg);
  340. X  for (i = 0; i < MAX_SAVE_MSG; i++)
  341. X    wr_string(old_msg[i]);
  342. X
  343. X  /* this indicates 'cheating' if it is a one */
  344. X  wr_short((int16u)panic_save);
  345. X  wr_short((int16u)total_winner);
  346. X  wr_short((int16u)noscore);
  347. X  wr_shorts(player_hp, MAX_PLAYER_LEVEL);
  348. X
  349. X  for (i = 0; i < MAX_STORES; i++)
  350. X    {
  351. X      st_ptr = &store[i];
  352. X      wr_long((int32u)st_ptr->store_open);
  353. X      wr_short((int16u)st_ptr->insult_cur);
  354. X      wr_byte(st_ptr->owner);
  355. X      wr_byte(st_ptr->store_ctr);
  356. X      wr_short(st_ptr->good_buy);
  357. X      wr_short(st_ptr->bad_buy);
  358. X      for (j = 0; j < st_ptr->store_ctr; j++)
  359. X    {
  360. X      wr_long((int32u)st_ptr->store_inven[j].scost);
  361. X      wr_item(&st_ptr->store_inven[j].sitem);
  362. X    }
  363. X    }
  364. X
  365. X  /* save the current time in the savefile */
  366. X#ifdef MAC
  367. X  l = time((time_t *)0);
  368. X#else
  369. X  l = time((long *)0);
  370. X#endif
  371. X  if (l < start_time)
  372. X    {
  373. X      /* someone is messing with the clock!, assume that we have been
  374. X     playing for 1 day */
  375. X      l = start_time + 86400L;
  376. X    }
  377. X  wr_long(l);
  378. X
  379. X  /* starting with 5.2, put died_from string in savefile */
  380. X  wr_string(died_from);
  381. X
  382. X  /* starting with 5.2.2, put the max_score in the savefile */
  383. X  l = total_points ();
  384. X  wr_long (l);
  385. X
  386. X  /* starting with 5.2.2, put the birth_date in the savefile */
  387. X  wr_long ((int32u) birth_date);
  388. X
  389. X  /* only level specific info follows, this allows characters to be
  390. X     resurrected, the dungeon level info is not needed for a resurrection */
  391. X  if (death)
  392. X    {
  393. X      if (ferror(fileptr) || fflush(fileptr) == EOF)
  394. X    return FALSE;
  395. X      return TRUE;
  396. X    }
  397. X
  398. X  wr_short((int16u)dun_level);
  399. X  wr_short((int16u)char_row);
  400. X  wr_short((int16u)char_col);
  401. X  wr_short((int16u)mon_tot_mult);
  402. X  wr_short((int16u)cur_height);
  403. X  wr_short((int16u)cur_width);
  404. X  wr_short((int16u)max_panel_rows);
  405. X  wr_short((int16u)max_panel_cols);
  406. X
  407. X  for (i = 0; i < MAX_HEIGHT; i++)
  408. X    for (j = 0; j < MAX_WIDTH; j++)
  409. X      {
  410. X    c_ptr = &cave[i][j];
  411. X    if (c_ptr->cptr != 0)
  412. X      {
  413. X        wr_byte((int8u)i);
  414. X        wr_byte((int8u)j);
  415. X        wr_byte(c_ptr->cptr);
  416. X      }
  417. X      }
  418. X  wr_byte((int8u)0xFF); /* marks end of cptr info */
  419. X  for (i = 0; i < MAX_HEIGHT; i++)
  420. X    for (j = 0; j < MAX_WIDTH; j++)
  421. X      {
  422. X    c_ptr = &cave[i][j];
  423. X    if (c_ptr->tptr != 0)
  424. X      {
  425. X        wr_byte((int8u)i);
  426. X        wr_byte((int8u)j);
  427. X        wr_byte(c_ptr->tptr);
  428. X      }
  429. X      }
  430. X  wr_byte((int8u)0xFF); /* marks end of tptr info */
  431. X  /* must set counter to zero, note that code may write out two bytes
  432. X     unnecessarily */
  433. X  count = 0;
  434. X  prev_char = 0;
  435. X  for (i = 0; i < MAX_HEIGHT; i++)
  436. X    for (j = 0; j < MAX_WIDTH; j++)
  437. X      {
  438. X    c_ptr = &cave[i][j];
  439. X    char_tmp = c_ptr->fval | (c_ptr->lr << 4) | (c_ptr->fm << 5) |
  440. X      (c_ptr->pl << 6) | (c_ptr->tl << 7);
  441. X    if (char_tmp != prev_char || count == MAX_UCHAR)
  442. X      {
  443. X        wr_byte((int8u)count);
  444. X        wr_byte(prev_char);
  445. X        prev_char = char_tmp;
  446. X        count = 1;
  447. X      }
  448. X    else
  449. X      count++;
  450. X      }
  451. X  /* save last entry */
  452. X  wr_byte((int8u)count);
  453. X  wr_byte(prev_char);
  454. X
  455. X#if defined(MSDOS) || defined(ATARI_ST)
  456. X  /* must change graphics symbols for walls and floors back to default chars,
  457. X     this is necessary so that if the user changes the graphics line, the
  458. X     program will be able change all existing walls and floors to the new
  459. X     symbol */
  460. X  /* Or if the user moves the savefile from one machine to another, we
  461. X     must have a consistent representation here.  */
  462. X  t_ptr = &t_list[tcptr - 1];
  463. X  for (i = tcptr - 1; i >= MIN_TRIX; i--)
  464. X    {
  465. X#ifdef MSDOS
  466. X      if (t_ptr->tchar == wallsym)
  467. X    t_ptr->tchar = '#';
  468. X#endif
  469. X#ifdef ATARI_ST
  470. X      if (t_ptr->tchar == (unsigned char)240)
  471. X    t_ptr->tchar = '#';
  472. X#endif
  473. X      t_ptr--;
  474. X    }
  475. X#endif
  476. X  wr_short((int16u)tcptr);
  477. X  for (i = MIN_TRIX; i < tcptr; i++)
  478. X    wr_item(&t_list[i]);
  479. X  wr_short((int16u)mfptr);
  480. X  for (i = MIN_MONIX; i < mfptr; i++)
  481. X    wr_monster(&m_list[i]);
  482. X
  483. X  if (ferror(fileptr) || (fflush(fileptr) == EOF))
  484. X    return FALSE;
  485. X  return TRUE;
  486. X}
  487. X
  488. X#ifdef MAC
  489. X
  490. X/* Set up prior to actual save, do the save, then clean up */
  491. X/* Notice that Mac version of this function takes a parameter */
  492. X/* To do a "save as" set always_ask */
  493. X/* To do a "save" clear always_ask */
  494. X
  495. Xint save_char(always_ask)
  496. Xint always_ask;
  497. X{
  498. X  int rc, already_set, proceed;
  499. X  int16 vrefnum;
  500. X
  501. X  /* cannot rely on _save_char to do this because we may put up a dialog */
  502. X  if (character_saved) return(TRUE);
  503. X
  504. X  enablefilemenu(FALSE);
  505. X
  506. X  already_set = getsavedefaults(savefile, &vrefnum);
  507. X
  508. X  if (!already_set || always_ask)
  509. X    {
  510. X      /* Here if always_ask or user has not yet specified a save file */
  511. X      /* User specifies a save file when he restarts a previous one */
  512. X      sfposition(vrefnum);
  513. X      proceed = doputfile(death ? "Save memories as:" : "Save game as:",
  514. X              savefile, &vrefnum);
  515. X    }
  516. X  else
  517. X    proceed = TRUE;
  518. X
  519. X  if (proceed)
  520. X    {
  521. X      changedirectory(vrefnum);
  522. X      rc = _save_char(savefile);
  523. X      restoredirectory();
  524. X    }
  525. X  else
  526. X    rc = FALSE;
  527. X
  528. X  if (rc)
  529. X    (void) setfileinfo(savefile, vrefnum, SAVE_FTYPE);
  530. X
  531. X  enablefilemenu(TRUE);
  532. X
  533. X  return(rc);
  534. X}
  535. X
  536. X#else
  537. X
  538. X/* The Mac has different logic here -- See above */
  539. X
  540. Xint save_char()
  541. X{
  542. X  int i;
  543. X  vtype temp;
  544. X
  545. X#ifdef SECURE
  546. X  bePlayer();
  547. X#endif
  548. X
  549. X  while (!_save_char(savefile))
  550. X    {
  551. X      (void) sprintf(temp, "Savefile '%s' fails.", savefile);
  552. X      msg_print(temp);
  553. X      i = 0;
  554. X      if (access(savefile, 0) < 0
  555. X      || get_check("File exists. Delete old savefile?") == 0
  556. X      || (i = unlink(savefile)) < 0)
  557. X    {
  558. X      if (i < 0)
  559. X        {
  560. X          (void) sprintf(temp, "Can't delete '%s'", savefile);
  561. X          msg_print(temp);
  562. X        }
  563. X      prt("New Savefile [ESC to give up]:", 0, 0);
  564. X      if (!get_string(temp, 0, 31, 45))
  565. X        return FALSE;
  566. X      if (temp[0])
  567. X        (void) strcpy(savefile, temp);
  568. X    }
  569. X      (void) sprintf(temp, "Saving with %s...", savefile);
  570. X      prt(temp, 0, 0);
  571. X    }
  572. X#ifdef SECURE
  573. X  beGames();
  574. X#endif
  575. X  return TRUE;
  576. X}
  577. X#endif
  578. X
  579. Xint _save_char(fnam)
  580. Xchar *fnam;
  581. X{
  582. X  vtype temp;
  583. X  register int ok, fd;
  584. X  int8u char_tmp;
  585. X
  586. X  if (character_saved)
  587. X    return TRUE;    /* Nothing to save. */
  588. X
  589. X  nosignals();
  590. X  put_qio();
  591. X  disturb (1, 0);        /* Turn off resting and searching. */
  592. X  change_speed(-pack_heavy);    /* Fix the speed */
  593. X  pack_heavy = 0;
  594. X  ok = FALSE;
  595. X  /* VMS files have version numbers, so don't worry about overwriting
  596. X     the old save file. */
  597. X#if !defined(ATARIST_MWC) && !defined(VMS)
  598. X  fd = -1;
  599. X  fileptr = NULL;        /* Do not assume it has been init'ed */
  600. X#if defined(MAC) || defined(AMIGA)
  601. X  /* The Mac version automatically overwrites */
  602. X  fd = open(fnam, O_RDWR|O_CREAT|O_TRUNC);
  603. X#ifdef MAC
  604. X  macbeginwait ();
  605. X#endif
  606. X#else
  607. X  fd = open(fnam, O_RDWR|O_CREAT|O_EXCL, 0600);
  608. X  if (fd < 0 && access(fnam, 0) >= 0 &&
  609. X      (from_savefile ||
  610. X       (wizard && get_check("Can't make new savefile. Overwrite old?"))))
  611. X    {
  612. X      (void) chmod(fnam, 0600);
  613. X      fd = open(fnam, O_RDWR|O_TRUNC, 0600);
  614. X    }
  615. X#endif
  616. X  if (fd >= 0)
  617. X    {
  618. X      (void) close(fd);
  619. X#endif /* !ATARIST_MWC && !VMS */
  620. X      /* GCC for atari st defines atarist */
  621. X#if defined(atarist) || defined(ATARI_ST) || defined(THINK_C) || defined(MSDOS)
  622. X      fileptr = fopen(savefile, "wb");
  623. X#else
  624. X      fileptr = fopen(savefile, "w");
  625. X#endif
  626. X#if !defined(ATARIST_MWC) && !defined(VMS)
  627. X    }
  628. X#endif
  629. X  DEBUG(logfile = fopen("IO_LOG", "a"));
  630. X  DEBUG(fprintf (logfile, "Saving data to %s\n", savefile));
  631. X  if (fileptr != NULL)
  632. X    {
  633. X      xor_byte = 0;
  634. X      wr_byte((int8u)CUR_VERSION_MAJ);
  635. X      xor_byte = 0;
  636. X      wr_byte((int8u)CUR_VERSION_MIN);
  637. X      xor_byte = 0;
  638. X      wr_byte((int8u)PATCH_LEVEL);
  639. X      xor_byte = 0;
  640. X      char_tmp = randint(256) - 1;
  641. X      wr_byte(char_tmp);
  642. X      /* Note that xor_byte is now equal to char_tmp */
  643. X
  644. X      ok = sv_write();
  645. X
  646. X      DEBUG(fclose (logfile));
  647. X
  648. X      if (fclose(fileptr) == EOF)
  649. X    ok = FALSE;
  650. X    }
  651. X
  652. X#ifdef MAC
  653. X  macendwait ();
  654. X#endif
  655. X
  656. X  if (!ok)
  657. X    {
  658. X      if (fd >= 0)
  659. X    (void) unlink(fnam);
  660. X      signals();
  661. X      if (fd >= 0)
  662. X    (void) sprintf(temp, "Error writing to file %s", fnam);
  663. X      else
  664. X    (void) sprintf(temp, "Can't create new file %s", fnam);
  665. X      msg_print(temp);
  666. X      return FALSE;
  667. X    }
  668. X  else
  669. X    character_saved = 1;
  670. X
  671. X  turn = -1;
  672. X  signals();
  673. X
  674. X  return TRUE;
  675. X}
  676. X
  677. X
  678. X#ifdef MAC
  679. X/* Wrapper to set the appropriate directory */
  680. Xint get_char(generate)
  681. Xint *generate;
  682. X{
  683. X  int rc, exit_flag;
  684. X  int16 vrefnum;
  685. X
  686. X  (void) getsavedefaults(savefile, &vrefnum);
  687. X
  688. X  changedirectory(vrefnum);
  689. X  rc = _get_char(generate, &exit_flag);
  690. X  restoredirectory();
  691. X
  692. X  if (exit_flag)
  693. X    exit_game();
  694. X
  695. X  return(rc);
  696. X}
  697. X#endif
  698. X
  699. X/* Certain checks are ommitted for the wizard. -CJS- */
  700. X
  701. X#ifdef MAC
  702. Xint _get_char(generate, exit_flag)
  703. Xint *generate, *exit_flag;
  704. X#else
  705. Xint get_char(generate)
  706. Xint *generate;
  707. X#endif
  708. X{
  709. X  register int i, j;
  710. X  int fd, c, ok, total_count;
  711. X  int32u l, age, time_saved;
  712. X  vtype temp;
  713. X  int16u int16u_tmp;
  714. X  register cave_type *c_ptr;
  715. X  register recall_type *r_ptr;
  716. X  struct misc *m_ptr;
  717. X  struct stats *s_ptr;
  718. X  register struct flags *f_ptr;
  719. X  store_type *st_ptr;
  720. X  int8u char_tmp, ychar, xchar, count;
  721. X  int8u version_maj, version_min, patch_level;
  722. X#if defined(MSDOS) || defined(ATARI_ST)
  723. X  inven_type *t_ptr;
  724. X#endif
  725. X
  726. X#ifdef MAC
  727. X  *exit_flag = FALSE;
  728. X#endif
  729. X
  730. X  nosignals();
  731. X  *generate = TRUE;
  732. X  fd = -1;
  733. X
  734. X#ifndef MAC
  735. X  /* Not required for Mac, because the file name is obtained through a dialog.
  736. X     There is no way for a non existnat file to be specified.  -BS-    */
  737. X  if (access(savefile, 0) != 0)
  738. X    {
  739. X      signals();
  740. X      msg_print("Savefile does not exist.");
  741. X      return FALSE;    /* Don't bother with messages here. File absent. */
  742. X    }
  743. X#endif
  744. X
  745. X  clear_screen();
  746. X
  747. X  (void) sprintf(temp, "Savefile %s present. Attempting restore.", savefile);
  748. X  put_buffer(temp, 23, 0);
  749. X
  750. X  if (turn >= 0)
  751. X    msg_print("IMPOSSIBLE! Attempt to restore while still alive!");
  752. X
  753. X  /* Allow restoring a file belonging to someone else, if we can delete it. */
  754. X  /* Hence first try to read without doing a chmod. */
  755. X
  756. X#if defined(MAC) || defined(AMIGA)
  757. X  else if ((fd = open(savefile, O_RDONLY)) < 0)
  758. X#else
  759. X#ifdef ATARI_ST
  760. X  else if (FALSE)
  761. X#else
  762. X  else if ((fd = open(savefile, O_RDONLY, 0)) < 0
  763. X       && (chmod(savefile, 0400) < 0 ||
  764. X           (fd = open(savefile, O_RDONLY, 0)) < 0))
  765. X#endif
  766. X#endif
  767. X    msg_print("Can't open file for reading.");
  768. X  else
  769. X    {
  770. X      turn = -1;
  771. X      ok = TRUE;
  772. X
  773. X      (void) close(fd);
  774. X      /* GCC for atari st defines atarist */
  775. X#if defined(atarist) || defined(ATARI_ST) || defined(THINK_C) || defined(MSDOS)
  776. X      fileptr = fopen(savefile, "rb");
  777. X#else
  778. X      fileptr = fopen(savefile, "r");
  779. X#endif
  780. X      if (fileptr == NULL)
  781. X    goto error;
  782. X
  783. X#ifdef MAC
  784. X      macbeginwait ();
  785. X#endif
  786. X
  787. X      prt("Restoring Memory...", 0, 0);
  788. X      put_qio();
  789. X
  790. X      DEBUG(logfile = fopen("IO_LOG", "a"));
  791. X      DEBUG(fprintf (logfile, "Reading data from %s\n", savefile));
  792. X
  793. X      xor_byte = 0;
  794. X      rd_byte(&version_maj);
  795. X      xor_byte = 0;
  796. X      rd_byte(&version_min);
  797. X      xor_byte = 0;
  798. X      rd_byte(&patch_level);
  799. X      xor_byte = 0;
  800. X      rd_byte(&xor_byte);
  801. X
  802. X      /* COMPAT support savefiles from 5.0.14 to 5.0.17 */
  803. X      /* support savefiles from 5.1.0 to present */
  804. X      if ((version_maj != CUR_VERSION_MAJ)
  805. X#if 0
  806. X      /* As of version 5.4, accept savefiles even if they have higher
  807. X         version numbers.  The savefile format was frozen as of version
  808. X         5.2.2.  */
  809. X      || (version_min > CUR_VERSION_MIN)
  810. X      || (version_min == CUR_VERSION_MIN && patch_level > PATCH_LEVEL)
  811. X#endif
  812. X      || (version_min == 0 && patch_level < 14))
  813. X    {
  814. X      prt("Sorry. This savefile is from a different version of umoria.",
  815. X          2, 0);
  816. X      goto error;
  817. X    }
  818. X
  819. X      rd_short(&int16u_tmp);
  820. X      while (int16u_tmp != 0xFFFF)
  821. X    {
  822. X      if (int16u_tmp >= MAX_CREATURES)
  823. X        goto error;
  824. X      r_ptr = &c_recall[int16u_tmp];
  825. X      rd_long(&r_ptr->r_cmove);
  826. X      rd_long(&r_ptr->r_spells);
  827. X      rd_short(&r_ptr->r_kills);
  828. X      rd_short(&r_ptr->r_deaths);
  829. X      rd_short(&r_ptr->r_cdefense);
  830. X      rd_byte(&r_ptr->r_wake);
  831. X      rd_byte(&r_ptr->r_ignore);
  832. X      rd_bytes(r_ptr->r_attacks, MAX_MON_NATTACK);
  833. X      rd_short(&int16u_tmp);
  834. X    }
  835. X
  836. X      /* for save files before 5.2.2, read and ignore log_index (sic) */
  837. X      if ((version_min < 2) || (version_min == 2 && patch_level < 2))
  838. X    rd_short(&int16u_tmp);
  839. X      rd_long(&l);
  840. X
  841. X      if (l & 0x1)
  842. X    find_cut = TRUE;
  843. X      else
  844. X    find_cut = FALSE;
  845. X      if (l & 0x2)
  846. X    find_examine = TRUE;
  847. X      else
  848. X    find_examine = FALSE;
  849. X      if (l & 0x4)
  850. X    find_prself = TRUE;
  851. X      else
  852. X    find_prself = FALSE;
  853. X      if (l & 0x8)
  854. X    find_bound = TRUE;
  855. X      else
  856. X    find_bound = FALSE;
  857. X      if (l & 0x10)
  858. X    prompt_carry_flag = TRUE;
  859. X      else
  860. X    prompt_carry_flag = FALSE;
  861. X      if (l & 0x20)
  862. X    rogue_like_commands = TRUE;
  863. X      else
  864. X    rogue_like_commands = FALSE;
  865. X      if (l & 0x40)
  866. X    show_weight_flag = TRUE;
  867. X      else
  868. X    show_weight_flag = FALSE;
  869. X      if (l & 0x80)
  870. X    highlight_seams = TRUE;
  871. X      else
  872. X    highlight_seams = FALSE;
  873. X      if (l & 0x100)
  874. X    find_ignore_doors = TRUE;
  875. X      else
  876. X    find_ignore_doors = FALSE;
  877. X      /* save files before 5.2.2 don't have sound_beep_flag, set it on
  878. X     for compatibility */
  879. X      if ((version_min < 2) || (version_min == 2 && patch_level < 2))
  880. X    sound_beep_flag = TRUE;
  881. X      else if (l & 0x200)
  882. X    sound_beep_flag = TRUE;
  883. X      else
  884. X    sound_beep_flag = FALSE;
  885. X      /* save files before 5.2.2 don't have display_counts, set it on
  886. X     for compatibility */
  887. X      if ((version_min < 2) || (version_min == 2 && patch_level < 2))
  888. X    display_counts = TRUE;
  889. X      else if (l & 0x400)
  890. X    display_counts = TRUE;
  891. X      else
  892. X    display_counts = FALSE;
  893. X
  894. X      /* Don't allow resurrection of total_winner characters.  It causes
  895. X     problems because the character level is out of the allowed range.  */
  896. X      if (to_be_wizard && (l & 0x40000000L))
  897. X    {
  898. X      msg_print ("Sorry, this character is retired from moria.");
  899. X      msg_print ("You can not resurrect a retired character.");
  900. X    }
  901. X      else if (to_be_wizard && (l & 0x80000000L)
  902. X           && get_check("Resurrect a dead character?"))
  903. X    l &= ~0x80000000L;
  904. X      if ((l & 0x80000000L) == 0)
  905. X    {
  906. X      m_ptr = &py.misc;
  907. X      rd_string(m_ptr->name);
  908. X      rd_byte(&m_ptr->male);
  909. X      rd_long((int32u *)&m_ptr->au);
  910. X      rd_long((int32u *)&m_ptr->max_exp);
  911. X      rd_long((int32u *)&m_ptr->exp);
  912. X      rd_short(&m_ptr->exp_frac);
  913. X      rd_short(&m_ptr->age);
  914. X      rd_short(&m_ptr->ht);
  915. X      rd_short(&m_ptr->wt);
  916. X      rd_short(&m_ptr->lev);
  917. X      rd_short(&m_ptr->max_dlv);
  918. X      rd_short((int16u *)&m_ptr->srh);
  919. X      rd_short((int16u *)&m_ptr->fos);
  920. X      rd_short((int16u *)&m_ptr->bth);
  921. X      rd_short((int16u *)&m_ptr->bthb);
  922. X      rd_short((int16u *)&m_ptr->mana);
  923. X      rd_short((int16u *)&m_ptr->mhp);
  924. X      rd_short((int16u *)&m_ptr->ptohit);
  925. X      rd_short((int16u *)&m_ptr->ptodam);
  926. X      rd_short((int16u *)&m_ptr->pac);
  927. X      rd_short((int16u *)&m_ptr->ptoac);
  928. X      rd_short((int16u *)&m_ptr->dis_th);
  929. X      rd_short((int16u *)&m_ptr->dis_td);
  930. X      rd_short((int16u *)&m_ptr->dis_ac);
  931. X      rd_short((int16u *)&m_ptr->dis_tac);
  932. X      rd_short((int16u *)&m_ptr->disarm);
  933. X      rd_short((int16u *)&m_ptr->save);
  934. X      rd_short((int16u *)&m_ptr->sc);
  935. X      rd_short((int16u *)&m_ptr->stl);
  936. X      rd_byte(&m_ptr->pclass);
  937. X      rd_byte(&m_ptr->prace);
  938. X      rd_byte(&m_ptr->hitdie);
  939. X      rd_byte(&m_ptr->expfact);
  940. X      rd_short((int16u *)&m_ptr->cmana);
  941. X      rd_short(&m_ptr->cmana_frac);
  942. X      rd_short((int16u *)&m_ptr->chp);
  943. X      rd_short(&m_ptr->chp_frac);
  944. X      for (i = 0; i < 4; i++)
  945. X        rd_string (m_ptr->history[i]);
  946. X
  947. X      s_ptr = &py.stats;
  948. X      rd_bytes(s_ptr->max_stat, 6);
  949. X      rd_bytes(s_ptr->cur_stat, 6);
  950. X      rd_shorts((int16u *)s_ptr->mod_stat, 6);
  951. X      rd_bytes(s_ptr->use_stat, 6);
  952. X
  953. X      f_ptr = &py.flags;
  954. X      rd_long(&f_ptr->status);
  955. X      rd_short((int16u *)&f_ptr->rest);
  956. X      rd_short((int16u *)&f_ptr->blind);
  957. X      rd_short((int16u *)&f_ptr->paralysis);
  958. X      rd_short((int16u *)&f_ptr->confused);
  959. X      rd_short((int16u *)&f_ptr->food);
  960. X      rd_short((int16u *)&f_ptr->food_digested);
  961. X      rd_short((int16u *)&f_ptr->protection);
  962. X      rd_short((int16u *)&f_ptr->speed);
  963. X      rd_short((int16u *)&f_ptr->fast);
  964. X      rd_short((int16u *)&f_ptr->slow);
  965. X      rd_short((int16u *)&f_ptr->afraid);
  966. X      rd_short((int16u *)&f_ptr->poisoned);
  967. X      rd_short((int16u *)&f_ptr->image);
  968. X      rd_short((int16u *)&f_ptr->protevil);
  969. X      rd_short((int16u *)&f_ptr->invuln);
  970. X      rd_short((int16u *)&f_ptr->hero);
  971. X      rd_short((int16u *)&f_ptr->shero);
  972. X      rd_short((int16u *)&f_ptr->blessed);
  973. X      rd_short((int16u *)&f_ptr->resist_heat);
  974. X      rd_short((int16u *)&f_ptr->resist_cold);
  975. X      rd_short((int16u *)&f_ptr->detect_inv);
  976. X      rd_short((int16u *)&f_ptr->word_recall);
  977. X      rd_short((int16u *)&f_ptr->see_infra);
  978. X      rd_short((int16u *)&f_ptr->tim_infra);
  979. X      rd_byte(&f_ptr->see_inv);
  980. X      rd_byte(&f_ptr->teleport);
  981. X      rd_byte(&f_ptr->free_act);
  982. X      rd_byte(&f_ptr->slow_digest);
  983. X      rd_byte(&f_ptr->aggravate);
  984. X      rd_byte(&f_ptr->fire_resist);
  985. X      rd_byte(&f_ptr->cold_resist);
  986. X      rd_byte(&f_ptr->acid_resist);
  987. X      rd_byte(&f_ptr->regenerate);
  988. X      rd_byte(&f_ptr->lght_resist);
  989. X      rd_byte(&f_ptr->ffall);
  990. X      rd_byte(&f_ptr->sustain_str);
  991. X      rd_byte(&f_ptr->sustain_int);
  992. X      rd_byte(&f_ptr->sustain_wis);
  993. X      rd_byte(&f_ptr->sustain_con);
  994. X      rd_byte(&f_ptr->sustain_dex);
  995. X      rd_byte(&f_ptr->sustain_chr);
  996. X      rd_byte(&f_ptr->confuse_monster);
  997. X      rd_byte(&f_ptr->new_spells);
  998. X
  999. X      rd_short((int16u *)&missile_ctr);
  1000. X      rd_long((int32u *)&turn);
  1001. X      rd_short((int16u *)&inven_ctr);
  1002. X      if (inven_ctr > INVEN_WIELD)
  1003. X        goto error;
  1004. X      for (i = 0; i < inven_ctr; i++)
  1005. X        rd_item(&inventory[i]);
  1006. X      for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++)
  1007. X        rd_item(&inventory[i]);
  1008. X      rd_short((int16u *)&inven_weight);
  1009. X      rd_short((int16u *)&equip_ctr);
  1010. X      rd_long(&spell_learned);
  1011. X      rd_long(&spell_worked);
  1012. X      rd_long(&spell_forgotten);
  1013. X      rd_bytes(spell_order, 32);
  1014. X      rd_bytes(object_ident, OBJECT_IDENT_SIZE);
  1015. X      rd_long(&randes_seed);
  1016. X      rd_long(&town_seed);
  1017. X      rd_short((int16u *)&last_msg);
  1018. X      for (i = 0; i < MAX_SAVE_MSG; i++)
  1019. X        rd_string(old_msg[i]);
  1020. X
  1021. X      rd_short((int16u *)&panic_save);
  1022. X      rd_short((int16u *)&total_winner);
  1023. X      rd_short((int16u *)&noscore);
  1024. X      rd_shorts(player_hp, MAX_PLAYER_LEVEL);
  1025. X
  1026. X      if ((version_min >= 2)
  1027. X          || (version_min == 1 && patch_level >= 3))
  1028. X        for (i = 0; i < MAX_STORES; i++)
  1029. X          {
  1030. X        st_ptr = &store[i];
  1031. X        rd_long((int32u *)&st_ptr->store_open);
  1032. X        rd_short((int16u *)&st_ptr->insult_cur);
  1033. X        rd_byte(&st_ptr->owner);
  1034. X        rd_byte(&st_ptr->store_ctr);
  1035. X        rd_short(&st_ptr->good_buy);
  1036. X        rd_short(&st_ptr->bad_buy);
  1037. X        if (st_ptr->store_ctr > STORE_INVEN_MAX)
  1038. X          goto error;
  1039. X        for (j = 0; j < st_ptr->store_ctr; j++)
  1040. X          {
  1041. X            rd_long((int32u *)&st_ptr->store_inven[j].scost);
  1042. X            rd_item(&st_ptr->store_inven[j].sitem);
  1043. X          }
  1044. X          }
  1045. X
  1046. X      if ((version_min >= 2)
  1047. X          || (version_min == 1 && patch_level >= 3))
  1048. X        rd_long(&time_saved);
  1049. X
  1050. X      if (version_min >= 2)
  1051. X        rd_string(died_from);
  1052. X
  1053. X      if ((version_min >= 3)
  1054. X          || (version_min == 2 && patch_level >= 2))
  1055. X        rd_long ((int32u *)&max_score);
  1056. X      else
  1057. X        max_score = 0;
  1058. X
  1059. X      if ((version_min >= 3)
  1060. X          || (version_min == 2 && patch_level >= 2))
  1061. X        rd_long ((int32u *)&birth_date);
  1062. X      else
  1063. X#ifdef MAC
  1064. X        birth_date = time((time_t *)0);
  1065. X#else
  1066. X        birth_date = time((long *)0);
  1067. X#endif
  1068. X    }
  1069. X      if ((c = getc(fileptr)) == EOF || (l & 0x80000000L))
  1070. X    {
  1071. X      if ((l & 0x80000000L) == 0)
  1072. X        {
  1073. X          if (!to_be_wizard || turn < 0)
  1074. X        goto error;
  1075. X          prt("Attempting a resurrection!", 0, 0);
  1076. X          if (py.misc.chp < 0)
  1077. X        {
  1078. X          py.misc.chp =     0;
  1079. X          py.misc.chp_frac = 0;
  1080. X        }
  1081. X          /* don't let him starve to death immediately */
  1082. X          if (py.flags.food < 0)
  1083. X        py.flags.food = 0;
  1084. X          /* don't let him die of poison again immediately */
  1085. X          if (py.flags.poisoned > 1)
  1086. X        py.flags.poisoned = 1;
  1087. X          dun_level = 0; /* Resurrect on the town level. */
  1088. X          character_generated = 1;
  1089. X          /* set noscore to indicate a resurrection, and don't enter
  1090. X         wizard mode */
  1091. X          to_be_wizard = FALSE;
  1092. X          noscore |= 0x1;
  1093. X        }
  1094. X      else
  1095. X        {
  1096. X          /* Make sure that this message is seen, since it is a bit
  1097. X         more interesting than the other messages.  */
  1098. X          msg_print("Restoring Memory of a departed spirit...");
  1099. X          turn = -1;
  1100. X        }
  1101. X      put_qio();
  1102. X      goto closefiles;
  1103. X    }
  1104. X      if (ungetc(c, fileptr) == EOF)
  1105. X    goto error;
  1106. X
  1107. X      prt("Restoring Character...", 0, 0);
  1108. X      put_qio();
  1109. X
  1110. X      /* only level specific info should follow, not present for dead
  1111. X         characters */
  1112. X
  1113. X      rd_short((int16u *)&dun_level);
  1114. X      rd_short((int16u *)&char_row);
  1115. X      rd_short((int16u *)&char_col);
  1116. X      rd_short((int16u *)&mon_tot_mult);
  1117. X      rd_short((int16u *)&cur_height);
  1118. X      rd_short((int16u *)&cur_width);
  1119. X      rd_short((int16u *)&max_panel_rows);
  1120. X      rd_short((int16u *)&max_panel_cols);
  1121. X
  1122. X      /* read in the creature ptr info */
  1123. X      rd_byte(&char_tmp);
  1124. X      while (char_tmp != 0xFF)
  1125. X    {
  1126. X      ychar = char_tmp;
  1127. X      rd_byte(&xchar);
  1128. X      rd_byte(&char_tmp);
  1129. X      if (xchar > MAX_WIDTH || ychar > MAX_HEIGHT)
  1130. X        goto error;
  1131. X      cave[ychar][xchar].cptr = char_tmp;
  1132. X      rd_byte(&char_tmp);
  1133. X    }
  1134. X      /* read in the treasure ptr info */
  1135. X      rd_byte(&char_tmp);
  1136. X      while (char_tmp != 0xFF)
  1137. X    {
  1138. X      ychar = char_tmp;
  1139. X      rd_byte(&xchar);
  1140. X      rd_byte(&char_tmp);
  1141. X      if (xchar > MAX_WIDTH || ychar > MAX_HEIGHT)
  1142. X        goto error;
  1143. X      cave[ychar][xchar].tptr = char_tmp;
  1144. X      rd_byte(&char_tmp);
  1145. X    }
  1146. X      /* read in the rest of the cave info */
  1147. X      c_ptr = &cave[0][0];
  1148. X      total_count = 0;
  1149. X      while (total_count != MAX_HEIGHT*MAX_WIDTH)
  1150. X    {
  1151. X      rd_byte(&count);
  1152. X      rd_byte(&char_tmp);
  1153. X      for (i = count; i > 0; i--)
  1154. X        {
  1155. X#ifndef ATARIST_MWC
  1156. X          if (c_ptr >= &cave[MAX_HEIGHT][0])
  1157. X        goto error;
  1158. X#endif
  1159. X          c_ptr->fval = char_tmp & 0xF;
  1160. X          c_ptr->lr = (char_tmp >> 4) & 0x1;
  1161. X          c_ptr->fm = (char_tmp >> 5) & 0x1;
  1162. X          c_ptr->pl = (char_tmp >> 6) & 0x1;
  1163. X          c_ptr->tl = (char_tmp >> 7) & 0x1;
  1164. X          c_ptr++;
  1165. X        }
  1166. X      total_count += count;
  1167. X    }
  1168. X
  1169. X      rd_short((int16u *)&tcptr);
  1170. X      if (tcptr > MAX_TALLOC)
  1171. X    goto error;
  1172. X      for (i = MIN_TRIX; i < tcptr; i++)
  1173. X    rd_item(&t_list[i]);
  1174. X      rd_short((int16u *)&mfptr);
  1175. X      if (mfptr > MAX_MALLOC)
  1176. X    goto error;
  1177. X      for (i = MIN_MONIX; i < mfptr; i++)
  1178. X    rd_monster(&m_list[i]);
  1179. X
  1180. X#if defined(MSDOS) || defined(ATARI_ST)
  1181. X      /* change walls and floors to graphic symbols */
  1182. X      t_ptr = &t_list[tcptr - 1];
  1183. X      for (i = tcptr - 1; i >= MIN_TRIX; i--)
  1184. X    {
  1185. X#ifdef MSDOS
  1186. X      if (t_ptr->tchar == '#')
  1187. X        t_ptr->tchar = wallsym;
  1188. X#endif
  1189. X#ifdef ATARI_ST
  1190. X      if (t_ptr->tchar == '#')
  1191. X        t_ptr->tchar = (unsigned char) 240;
  1192. X#endif
  1193. X      t_ptr--;
  1194. X    }
  1195. X#endif
  1196. X
  1197. X      *generate = FALSE;  /* We have restored a cave - no need to generate. */
  1198. X
  1199. X      if ((version_min == 1 && patch_level < 3)
  1200. X      || (version_min == 0))
  1201. X    for (i = 0; i < MAX_STORES; i++)
  1202. X      {
  1203. X        st_ptr = &store[i];
  1204. X        rd_long((int32u *)&st_ptr->store_open);
  1205. X        rd_short((int16u *)&st_ptr->insult_cur);
  1206. X        rd_byte(&st_ptr->owner);
  1207. X        rd_byte(&st_ptr->store_ctr);
  1208. X        rd_short(&st_ptr->good_buy);
  1209. X        rd_short(&st_ptr->bad_buy);
  1210. X        if (st_ptr->store_ctr > STORE_INVEN_MAX)
  1211. X          goto error;
  1212. X        for (j = 0; j < st_ptr->store_ctr; j++)
  1213. X          {
  1214. X        rd_long((int32u *)&st_ptr->store_inven[j].scost);
  1215. X        rd_item(&st_ptr->store_inven[j].sitem);
  1216. X          }
  1217. X      }
  1218. X
  1219. X      /* read the time that the file was saved */
  1220. X      if (version_min == 0 && patch_level < 16)
  1221. X    time_saved = 0; /* no time in file, clear to zero */
  1222. X      else if (version_min == 1 && patch_level < 3)
  1223. X    rd_long(&time_saved);
  1224. X
  1225. X      if (ferror(fileptr))
  1226. X    goto error;
  1227. X
  1228. X      if (turn < 0)
  1229. X      error:
  1230. X    ok = FALSE;    /* Assume bad data. */
  1231. X      else
  1232. X    {
  1233. X      /* don't overwrite the killed by string if character is dead */
  1234. X      if (py.misc.chp >= 0)
  1235. X        (void) strcpy(died_from, "(alive and well)");
  1236. X      character_generated = 1;
  1237. X    }
  1238. X
  1239. X    closefiles:
  1240. X
  1241. X      DEBUG(fclose (logfile));
  1242. X
  1243. X      if (fileptr != NULL)
  1244. X    {
  1245. X      if (fclose(fileptr) < 0)
  1246. X        ok = FALSE;
  1247. X    }
  1248. X      if (fd >= 0)
  1249. X    (void) close(fd);
  1250. X
  1251. X#ifdef MAC
  1252. X      macendwait ();
  1253. X#endif
  1254. X
  1255. X      if (!ok)
  1256. X    msg_print("Error during reading of file.");
  1257. X      else
  1258. X    {
  1259. X      /* let the user overwrite the old savefile when save/quit */
  1260. X      from_savefile = 1;
  1261. X
  1262. X      signals();
  1263. X
  1264. X      if (panic_save == 1)
  1265. X        {
  1266. X          (void) sprintf(temp, "This game is from a panic save.  \
  1267. XScore will not be added to scoreboard.");
  1268. X          msg_print (temp);
  1269. X        }
  1270. X      else if ((!noscore & 0x04) && duplicate_character ())
  1271. X        {
  1272. X          (void) sprintf (temp, "This character is already on the \
  1273. Xscoreboard; it will not be scored again.");
  1274. X          msg_print (temp);
  1275. X          noscore |= 0x4;
  1276. X        }
  1277. X
  1278. X      if (turn >= 0)
  1279. X        {    /* Only if a full restoration. */
  1280. X          weapon_heavy = FALSE;
  1281. X          pack_heavy = 0;
  1282. X          check_strength();
  1283. X
  1284. X          /* rotate store inventory, depending on how old the save file */
  1285. X          /* is foreach day old (rounded up), call store_maint */
  1286. X          /* calculate age in seconds */
  1287. X#ifdef MAC
  1288. X          start_time = time((time_t *)0);
  1289. X#else
  1290. X          start_time = time((long *)0);
  1291. X#endif
  1292. X          /* check for reasonable values of time here ... */
  1293. X          if (start_time < time_saved)
  1294. X        age = 0;
  1295. X          else
  1296. X        age = start_time - time_saved;
  1297. X
  1298. X          age = (age + 43200L) / 86400L;  /* age in days */
  1299. X          if (age > 10) age = 10; /* in case savefile is very old */
  1300. X          for (i = 0; i < age; i++)
  1301. X        store_maint();
  1302. X        }
  1303. X
  1304. X      if (noscore)
  1305. X        msg_print("This save file cannot be used to get on the score board.");
  1306. X
  1307. X      if (version_maj != CUR_VERSION_MAJ
  1308. X          || version_min != CUR_VERSION_MIN)
  1309. X        {
  1310. X          (void) sprintf(temp,
  1311. X                 "Save file version %d.%d %s on game version %d.%d.",
  1312. X                 version_maj, version_min,
  1313. X                 version_min <= CUR_VERSION_MIN
  1314. X                 ? "accepted" : "risky" ,
  1315. X                 CUR_VERSION_MAJ, CUR_VERSION_MIN);
  1316. X          msg_print(temp);
  1317. X        }
  1318. X
  1319. X      if (turn >= 0)
  1320. X        return TRUE;
  1321. X      else
  1322. X        return FALSE;    /* Only restored options and monster memory. */
  1323. X    }
  1324. X    }
  1325. X  turn = -1;
  1326. X  prt("Please try again without that savefile.", 1, 0);
  1327. X  signals();
  1328. X#ifdef MAC
  1329. X  *exit_flag = TRUE;
  1330. X#else
  1331. X  exit_game();
  1332. X#endif
  1333. X
  1334. X  return FALSE;    /* not reached, unless on mac */
  1335. X}
  1336. X
  1337. Xstatic void wr_byte(c)
  1338. Xint8u c;
  1339. X{
  1340. X  xor_byte ^= c;
  1341. X  (void) putc((int)xor_byte, fileptr);
  1342. X  DEBUG(fprintf (logfile, "BYTE:  %02X = %d\n", (int) xor_byte, (int) c));
  1343. X}
  1344. X
  1345. Xstatic void wr_short(s)
  1346. Xint16u s;
  1347. X{
  1348. X  xor_byte ^= (s & 0xFF);
  1349. X  (void) putc((int)xor_byte, fileptr);
  1350. X  DEBUG(fprintf (logfile, "SHORT: %02X", (int) xor_byte));
  1351. X  xor_byte ^= ((s >> 8) & 0xFF);
  1352. X  (void) putc((int)xor_byte, fileptr);
  1353. X  DEBUG(fprintf (logfile, " %02X = %d\n", (int) xor_byte, (int) s));
  1354. X}
  1355. X
  1356. Xstatic void wr_long(l)
  1357. Xregister int32u l;
  1358. X{
  1359. X  xor_byte ^= (l & 0xFF);
  1360. X  (void) putc((int)xor_byte, fileptr);
  1361. X  DEBUG(fprintf (logfile, "LONG:  %02X", (int) xor_byte));
  1362. X  xor_byte ^= ((l >> 8) & 0xFF);
  1363. X  (void) putc((int)xor_byte, fileptr);
  1364. X  DEBUG(fprintf (logfile, " %02X", (int) xor_byte));
  1365. X  xor_byte ^= ((l >> 16) & 0xFF);
  1366. X  (void) putc((int)xor_byte, fileptr);
  1367. X  DEBUG(fprintf (logfile, " %02X", (int) xor_byte));
  1368. X  xor_byte ^= ((l >> 24) & 0xFF);
  1369. X  (void) putc((int)xor_byte, fileptr);
  1370. X  DEBUG(fprintf (logfile, " %02X = %ld\n", (int) xor_byte, (long) l));
  1371. X}
  1372. X
  1373. Xstatic void wr_bytes(c, count)
  1374. Xint8u *c;
  1375. Xregister int count;
  1376. X{
  1377. X  register int i;
  1378. X  register int8u *ptr;
  1379. X
  1380. X  DEBUG(fprintf (logfile, "%d BYTES:", count));
  1381. X  ptr = c;
  1382. X  for (i = 0; i < count; i++)
  1383. X    {
  1384. X      xor_byte ^= *ptr++;
  1385. X      (void) putc((int)xor_byte, fileptr);
  1386. X      DEBUG(fprintf (logfile, "  %02X = %d", (int) xor_byte,
  1387. X             (int) (ptr[-1])));
  1388. X    }
  1389. X  DEBUG(fprintf (logfile, "\n"));
  1390. X}
  1391. X
  1392. Xstatic void wr_string(str)
  1393. Xregister char *str;
  1394. X{
  1395. X  DEBUG(char *s = str);
  1396. X  DEBUG(fprintf (logfile, "STRING:"));
  1397. X  while (*str != '\0')
  1398. X    {
  1399. X      xor_byte ^= *str++;
  1400. X      (void) putc((int)xor_byte, fileptr);
  1401. X      DEBUG(fprintf (logfile, " %02X", (int) xor_byte));
  1402. X    }
  1403. X  xor_byte ^= *str;
  1404. X  (void) putc((int)xor_byte, fileptr);
  1405. X  DEBUG(fprintf (logfile, " %02X = \"%s\"\n", (int) xor_byte, s));
  1406. X}
  1407. X
  1408. Xstatic void wr_shorts(s, count)
  1409. Xint16u *s;
  1410. Xregister int count;
  1411. X{
  1412. X  register int i;
  1413. X  register int16u *sptr;
  1414. X
  1415. X  DEBUG(fprintf (logfile, "%d SHORTS:", count));
  1416. X  sptr = s;
  1417. X  for (i = 0; i < count; i++)
  1418. X    {
  1419. X      xor_byte ^= (*sptr & 0xFF);
  1420. X      (void) putc((int)xor_byte, fileptr);
  1421. X      DEBUG(fprintf (logfile, "  %02X", (int) xor_byte));
  1422. X      xor_byte ^= ((*sptr++ >> 8) & 0xFF);
  1423. X      (void) putc((int)xor_byte, fileptr);
  1424. X      DEBUG(fprintf (logfile, " %02X = %d", (int) xor_byte, (int) sptr[-1]));
  1425. X    }
  1426. X  DEBUG(fprintf (logfile, "\n"));
  1427. X}
  1428. X
  1429. Xstatic void wr_item(item)
  1430. Xregister inven_type *item;
  1431. X{
  1432. X  DEBUG(fprintf (logfile, "ITEM:\n"));
  1433. X  wr_short(item->index);
  1434. X  wr_byte(item->name2);
  1435. X  wr_string(item->inscrip);
  1436. X  wr_long(item->flags);
  1437. X  wr_byte(item->tval);
  1438. X  wr_byte(item->tchar);
  1439. X  wr_short((int16u)item->p1);
  1440. X  wr_long((int32u)item->cost);
  1441. X  wr_byte(item->subval);
  1442. X  wr_byte(item->number);
  1443. X  wr_short(item->weight);
  1444. X  wr_short((int16u)item->tohit);
  1445. X  wr_short((int16u)item->todam);
  1446. X  wr_short((int16u)item->ac);
  1447. X  wr_short((int16u)item->toac);
  1448. X  wr_bytes(item->damage, 2);
  1449. X  wr_byte(item->level);
  1450. X  wr_byte(item->ident);
  1451. X}
  1452. X
  1453. Xstatic void wr_monster(mon)
  1454. Xregister monster_type *mon;
  1455. X{
  1456. X  DEBUG(fprintf (logfile, "MONSTER:\n"));
  1457. X  wr_short((int16u)mon->hp);
  1458. X  wr_short((int16u)mon->csleep);
  1459. X  wr_short((int16u)mon->cspeed);
  1460. X  wr_short(mon->mptr);
  1461. X  wr_byte(mon->fy);
  1462. X  wr_byte(mon->fx);
  1463. X  wr_byte(mon->cdis);
  1464. X  wr_byte(mon->ml);
  1465. X  wr_byte(mon->stunned);
  1466. X  wr_byte(mon->confused);
  1467. X}
  1468. X
  1469. Xstatic void rd_byte(ptr)
  1470. Xint8u *ptr;
  1471. X{
  1472. X  int8u c;
  1473. X
  1474. X  c = getc(fileptr) & 0xFF;
  1475. X  *ptr = c ^ xor_byte;
  1476. X  xor_byte = c;
  1477. X  DEBUG(fprintf (logfile, "BYTE:  %02X = %d\n", (int) c, (int) *ptr));
  1478. X}
  1479. X
  1480. Xstatic void rd_short(ptr)
  1481. Xint16u *ptr;
  1482. X{
  1483. X  int8u c;
  1484. X  int16u s;
  1485. X
  1486. X  c = (getc(fileptr) & 0xFF);
  1487. X  s = c ^ xor_byte;
  1488. X  xor_byte = (getc(fileptr) & 0xFF);
  1489. X  s |= (int16u)(c ^ xor_byte) << 8;
  1490. X  *ptr = s;
  1491. X  DEBUG(fprintf (logfile, "SHORT: %02X %02X = %d\n", (int) c, (int) xor_byte,\
  1492. X         (int) s));
  1493. X}
  1494. X
  1495. Xstatic void rd_long(ptr)
  1496. Xint32u *ptr;
  1497. X{
  1498. X  register int32u l;
  1499. X  register int8u c;
  1500. X
  1501. X  c = (getc(fileptr) & 0xFF);
  1502. X  l = c ^ xor_byte;
  1503. X  xor_byte = (getc(fileptr) & 0xFF);
  1504. X  l |= (int32u)(c ^ xor_byte) << 8;
  1505. X  DEBUG(fprintf (logfile, "LONG:  %02X %02X ", (int) c, (int) xor_byte));
  1506. X  c = (getc(fileptr) & 0xFF);
  1507. X  l |= (int32u)(c ^ xor_byte) << 16;
  1508. X  xor_byte = (getc(fileptr) & 0xFF);
  1509. X  l |= (int32u)(c ^ xor_byte) << 24;
  1510. X  *ptr = l;
  1511. X  DEBUG(fprintf (logfile, "%02X %02X = %ld\n", (int) c, (int) xor_byte,\
  1512. X         (long) l));
  1513. X}
  1514. X
  1515. Xstatic void rd_bytes(ch_ptr, count)
  1516. Xint8u *ch_ptr;
  1517. Xregister int count;
  1518. X{
  1519. X  register int i;
  1520. X  register int8u *ptr;
  1521. X  register int8u c;
  1522. X
  1523. X  DEBUG(fprintf (logfile, "%d BYTES:", count));
  1524. X  ptr = ch_ptr;
  1525. X  for (i = 0; i < count; i++)
  1526. X    {
  1527. X      c = (getc(fileptr) & 0xFF);
  1528. X      *ptr++ = c ^ xor_byte;
  1529. X      xor_byte = c;
  1530. X      DEBUG(fprintf (logfile, "  %02X = %d", (int) c, (int) ptr[-1]));
  1531. X    }
  1532. X  DEBUG(fprintf (logfile, "\n"));
  1533. X}
  1534. X
  1535. Xstatic void rd_string(str)
  1536. Xchar *str;
  1537. X{
  1538. X  register int8u c;
  1539. X
  1540. X  DEBUG(char *s = str);
  1541. X  DEBUG(fprintf (logfile, "STRING: "));
  1542. X  do
  1543. X    {
  1544. X      c = (getc(fileptr) & 0xFF);
  1545. X      *str = c ^ xor_byte;
  1546. X      xor_byte = c;
  1547. X      DEBUG(fprintf (logfile, "%02X ", (int) c));
  1548. X    }
  1549. X  while (*str++ != '\0');
  1550. X  DEBUG(fprintf (logfile, "= \"%s\"\n", s));
  1551. X}
  1552. X
  1553. Xstatic void rd_shorts(ptr, count)
  1554. Xint16u *ptr;
  1555. Xregister int count;
  1556. X{
  1557. X  register int i;
  1558. X  register int16u *sptr;
  1559. X  register int16u s;
  1560. X  int8u c;
  1561. X
  1562. X  DEBUG(fprintf (logfile, "%d SHORTS:", count));
  1563. X  sptr = ptr;
  1564. X  for (i = 0; i < count; i++)
  1565. X    {
  1566. X      c = (getc(fileptr) & 0xFF);
  1567. X      s = c ^ xor_byte;
  1568. X      xor_byte = (getc(fileptr) & 0xFF);
  1569. X      s |= (int16u)(c ^ xor_byte) << 8;
  1570. X      *sptr++ = s;
  1571. X      DEBUG(fprintf (logfile, "  %02X %02X = %d", (int) c, (int) xor_byte,\
  1572. X             (int) s));
  1573. X    }
  1574. X  DEBUG(fprintf (logfile, "\n"));
  1575. X}
  1576. X
  1577. Xstatic void rd_item(item)
  1578. Xregister inven_type *item;
  1579. X{
  1580. X  DEBUG(fprintf (logfile, "ITEM:\n"));
  1581. X  rd_short(&item->index);
  1582. X  rd_byte(&item->name2);
  1583. X  rd_string(item->inscrip);
  1584. X  rd_long(&item->flags);
  1585. X  rd_byte(&item->tval);
  1586. X  rd_byte(&item->tchar);
  1587. X  rd_short((int16u *)&item->p1);
  1588. X  rd_long((int32u *)&item->cost);
  1589. X  rd_byte(&item->subval);
  1590. X  rd_byte(&item->number);
  1591. X  rd_short(&item->weight);
  1592. X  rd_short((int16u *)&item->tohit);
  1593. X  rd_short((int16u *)&item->todam);
  1594. X  rd_short((int16u *)&item->ac);
  1595. X  rd_short((int16u *)&item->toac);
  1596. X  rd_bytes(item->damage, 2);
  1597. X  rd_byte(&item->level);
  1598. X  rd_byte(&item->ident);
  1599. X}
  1600. X
  1601. Xstatic void rd_monster(mon)
  1602. Xregister monster_type *mon;
  1603. X{
  1604. X  DEBUG(fprintf (logfile, "MONSTER:\n"));
  1605. X  rd_short((int16u *)&mon->hp);
  1606. X  rd_short((int16u *)&mon->csleep);
  1607. X  rd_short((int16u *)&mon->cspeed);
  1608. X  rd_short(&mon->mptr);
  1609. X  rd_byte(&mon->fy);
  1610. X  rd_byte(&mon->fx);
  1611. X  rd_byte(&mon->cdis);
  1612. X  rd_byte(&mon->ml);
  1613. X  rd_byte(&mon->stunned);
  1614. X  rd_byte(&mon->confused);
  1615. X}
  1616. X
  1617. X/* functions called from death.c to implement the score file */
  1618. X
  1619. X/* set the local fileptr to the scorefile fileptr */
  1620. Xvoid set_fileptr(file)
  1621. XFILE *file;
  1622. X{
  1623. X  fileptr = file;
  1624. X}
  1625. X
  1626. Xvoid wr_highscore(score)
  1627. Xhigh_scores *score;
  1628. X{
  1629. X  DEBUG(logfile = fopen ("IO_LOG", "a"));
  1630. X  DEBUG(fprintf (logfile, "Saving score:\n"));
  1631. X  /* Save the encryption byte for robustness.  */
  1632. X  wr_byte(xor_byte);
  1633. X
  1634. X  wr_long((int32u) score->points);
  1635. X  wr_long((int32u) score->birth_date);
  1636. X  wr_short((int16u) score->uid);
  1637. X  wr_short((int16u) score->mhp);
  1638. X  wr_short((int16u) score->chp);
  1639. X  wr_byte(score->dun_level);
  1640. X  wr_byte(score->lev);
  1641. X  wr_byte(score->max_dlv);
  1642. X  wr_byte(score->sex);
  1643. X  wr_byte(score->race);
  1644. X  wr_byte(score->class);
  1645. X  wr_bytes((int8u *)score->name, PLAYER_NAME_SIZE);
  1646. X  wr_bytes((int8u *)score->died_from, 25);
  1647. X  DEBUG(fclose (logfile));
  1648. X}
  1649. X
  1650. Xvoid rd_highscore(score)
  1651. Xhigh_scores *score;
  1652. X{
  1653. X  DEBUG(logfile = fopen ("IO_LOG", "a"));
  1654. X  DEBUG(fprintf (logfile, "Reading score:\n"));
  1655. X  /* Read the encryption byte.  */
  1656. X  rd_byte (&xor_byte);
  1657. X
  1658. X  rd_long((int32u *)&score->points);
  1659. X  rd_long((int32u *)&score->birth_date);
  1660. X  rd_short((int16u *)&score->uid);
  1661. X  rd_short((int16u *)&score->mhp);
  1662. X  rd_short((int16u *)&score->chp);
  1663. X  rd_byte(&score->dun_level);
  1664. X  rd_byte(&score->lev);
  1665. X  rd_byte(&score->max_dlv);
  1666. X  rd_byte(&score->sex);
  1667. X  rd_byte(&score->race);
  1668. X  rd_byte(&score->class);
  1669. X  rd_bytes((int8u *)score->name, PLAYER_NAME_SIZE);
  1670. X  rd_bytes((int8u *)score->died_from, 25);
  1671. X  DEBUG(fclose (logfile));
  1672. X}
  1673. END_OF_FILE
  1674. if test 41704 -ne `wc -c <'source/save.c'`; then
  1675.     echo shar: \"'source/save.c'\" unpacked with wrong size!
  1676. fi
  1677. # end of 'source/save.c'
  1678. fi
  1679. if test -f 'source/tables.c' -a "${1}" != "-c" ; then 
  1680.   echo shar: Will not clobber existing file \"'source/tables.c'\"
  1681. else
  1682. echo shar: Extracting \"'source/tables.c'\" \(10747 characters\)
  1683. sed "s/^X//" >'source/tables.c' <<'END_OF_FILE'
  1684. X/* source/tables.c: store/attack/RNG/etc tables and variables
  1685. X
  1686. X   Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  1687. X
  1688. X   This software may be copied and distributed for educational, research, and
  1689. X   not for profit purposes provided that this copyright and statement are
  1690. X   included in all such copies. */
  1691. X
  1692. X#include "config.h"
  1693. X#include "constant.h"
  1694. X#include "types.h"
  1695. X
  1696. X#ifdef MORIA_HOU
  1697. X/* Operating hours for Moria                -RAK-    */
  1698. X/*     X = Open; . = Closed                    */
  1699. Xchar  days[7][29] = { "SUN:XXXXXXXXXXXXXXXXXXXXXXXX",
  1700. X            "MON:XXXXXXXX.........XXXXXXX",
  1701. X            "TUE:XXXXXXXX.........XXXXXXX",
  1702. X            "WED:XXXXXXXX.........XXXXXXX",
  1703. X            "THU:XXXXXXXX.........XXXXXXX",
  1704. X            "FRI:XXXXXXXX.........XXXXXXX",
  1705. X            "SAT:XXXXXXXXXXXXXXXXXXXXXXXX" };
  1706. X#endif
  1707. X
  1708. X#ifdef MAC
  1709. Xstore_type *store;
  1710. X#else
  1711. Xstore_type store[MAX_STORES];
  1712. X#endif
  1713. X
  1714. X/* Store owners have different characteristics for pricing and haggling*/
  1715. X/* Note: Store owners should be added in groups, one for each store    */
  1716. X#ifdef MACGAME
  1717. Xowner_type *owners;
  1718. X#else
  1719. Xowner_type owners[MAX_OWNERS] = {
  1720. X{"Erick the Honest       (Human)      General Store",
  1721. X      250,    175,  108,    4, 0, 12},
  1722. X{"Mauglin the Grumpy     (Dwarf)      Armory"        ,
  1723. X    32000,    200,  112,    4, 5,  5},
  1724. X{"Arndal Beast-Slayer    (Half-Elf)   Weaponsmith"  ,
  1725. X    10000,    185,  110,    5, 1,  8},
  1726. X{"Hardblow the Humble    (Human)      Temple"        ,
  1727. X     3500,    175,  109,    6, 0, 15},
  1728. X{"Ga-nat the Greedy      (Gnome)      Alchemist"    ,
  1729. X    12000,    220,  115,    4, 4,  9},
  1730. X{"Valeria Starshine      (Elf)        Magic Shop"   ,
  1731. X    32000,    175,  110,    5, 2, 11},
  1732. X{"Andy the Friendly      (Halfling)   General Store",
  1733. X      200,    170,  108,    5, 3, 15},
  1734. X{"Darg-Low the Grim      (Human)      Armory"        ,
  1735. X    10000,    190,  111,    4, 0,  9},
  1736. X{"Oglign Dragon-Slayer   (Dwarf)      Weaponsmith"  ,
  1737. X    32000,    195,  112,    4, 5,  8},
  1738. X{"Gunnar the Paladin     (Human)      Temple"        ,
  1739. X     5000,    185,  110,    5, 0, 23},
  1740. X{"Mauser the Chemist     (Half-Elf)   Alchemist"    ,
  1741. X    10000,    190,  111,    5, 1,  8},
  1742. X{"Gopher the Great!      (Gnome)      Magic Shop"   ,
  1743. X    20000,    215,  113,    6, 4, 10},
  1744. X{"Lyar-el the Comely     (Elf)        General Store",
  1745. X      300,    165,  107,    6, 2, 18},
  1746. X{"Mauglim the Horrible   (Half-Orc)   Armory"        ,
  1747. X     3000,    200,  113,    5, 6,  9},
  1748. X{"Ithyl-Mak the Beastly  (Half-Troll) Weaponsmith"  ,
  1749. X     3000,    210,  115,    6, 7,  8},
  1750. X{"Delilah the Pure       (Half-Elf)   Temple"        ,
  1751. X    25000,    180,  107,    6, 1, 20},
  1752. X{"Wizzle the Chaotic     (Halfling)   Alchemist"    ,
  1753. X    10000,    190,  110,    6, 3,  8},
  1754. X{"Inglorian the Mage     (Human?)     Magic Shop"   ,
  1755. X    32000,    200,  110,    7, 0, 10}
  1756. X};
  1757. X#endif
  1758. X
  1759. X/* Buying and selling adjustments for character race VS store    */
  1760. X/* owner race                             */
  1761. Xint8u rgold_adj[MAX_RACES][MAX_RACES] = {
  1762. X            /*  Hum,  HfE,    Elf,  Hal,  Gno,  Dwa,    HfO,  HfT*/
  1763. X/*Human         */      {  100,  105,     105,  110,  113,  115,     120,  125},
  1764. X/*Half-Elf     */      {  110,  100,     100,  105,  110,  120,     125,  130},
  1765. X/*Elf         */      {  110,  105,     100,  105,  110,  120,     125,  130},
  1766. X/*Halfling     */      {  115,  110,     105,    95,  105,  110,     115,  130},
  1767. X/*Gnome         */      {  115,  115,     110,  105,   95,  110,     115,  130},
  1768. X/*Dwarf         */      {  115,  120,     120,  110,  110,   95,     125,  135},
  1769. X/*Half-Orc     */      {  115,  120,     125,  115,  115,  130,     110,  115},
  1770. X/*Half-Troll     */      {  110,  115,     115,  110,  110,  130,     110,  110}
  1771. X            };
  1772. X/* object_list[] index of objects that may appear in the store */
  1773. Xint16u store_choice[MAX_STORES][STORE_CHOICES] = {
  1774. X    /* General Store */
  1775. X{366,365,364,84,84,365,123,366,365,350,349,348,347,346,346,345,345,345,
  1776. X    344,344,344,344,344,344,344,344},
  1777. X    /* Armory     */
  1778. X{94,95,96,109,103,104,105,106,110,111,112,114,116,124,125,126,127,129,103,
  1779. X    104,124,125,91,92,95,96},
  1780. X    /* Weaponsmith     */
  1781. X{29,30,34,37,45,49,57,58,59,65,67,68,73,74,75,77,79,80,81,83,29,30,80,83,
  1782. X    80,83},
  1783. X    /* Temple     */
  1784. X{322,323,324,325,180,180,233,237,240,241,361,362,57,58,59,260,358,359,265,
  1785. X    237,237,240,240,241,323,359},
  1786. X    /* Alchemy shop     */
  1787. X{173,174,175,351,351,352,353,354,355,356,357,206,227,230,236,252,253,352,
  1788. X    353,354,355,356,359,363,359,359},
  1789. X    /* Magic-User store*/
  1790. X{318,141,142,153,164,167,168,140,319,320,320,321,269,270,282,286,287,292,
  1791. X    293,294,295,308,269,290,319,282}
  1792. X};
  1793. X
  1794. X#ifndef MAC
  1795. X/* MPW doesn't seem to handle this very well, so replace store_buy array
  1796. X   with a function call on mac */
  1797. X/* functions defined in sets.c */
  1798. Xextern int general_store(), armory(), weaponsmith(), temple(),
  1799. X  alchemist(), magic_shop();
  1800. X
  1801. X/* Each store will buy only certain items, based on TVAL */
  1802. Xint (*store_buy[MAX_STORES])() = {
  1803. X       general_store, armory, weaponsmith, temple, alchemist, magic_shop};
  1804. X#endif
  1805. X
  1806. X/* Following are arrays for descriptive pieces            */
  1807. X
  1808. X#ifdef MACGAME
  1809. X
  1810. Xchar **colors;
  1811. Xchar **mushrooms;
  1812. Xchar **woods;
  1813. Xchar **metals;
  1814. Xchar **rocks;
  1815. Xchar **amulets;
  1816. Xchar **syllables;
  1817. X
  1818. X#else
  1819. X
  1820. Xchar *colors[MAX_COLORS] = {
  1821. X/* Do not move the first three */
  1822. X  "Icky Green", "Light Brown", "Clear",
  1823. X  "Azure","Blue","Blue Speckled","Black","Brown","Brown Speckled","Bubbling",
  1824. X  "Chartreuse","Cloudy","Copper Speckled","Crimson","Cyan","Dark Blue",
  1825. X  "Dark Green","Dark Red","Gold Speckled","Green","Green Speckled","Grey",
  1826. X  "Grey Speckled","Hazy","Indigo","Light Blue","Light Green","Magenta",
  1827. X  "Metallic Blue","Metallic Red","Metallic Green","Metallic Purple","Misty",
  1828. X  "Orange","Orange Speckled","Pink","Pink Speckled","Puce","Purple",
  1829. X  "Purple Speckled","Red","Red Speckled","Silver Speckled","Smoky",
  1830. X  "Tangerine","Violet","Vermilion","White","Yellow"
  1831. X};
  1832. X
  1833. Xchar *mushrooms[MAX_MUSH] = {
  1834. X  "Blue","Black","Black Spotted","Brown","Dark Blue","Dark Green","Dark Red",
  1835. X  "Ecru","Furry","Green","Grey","Light Blue","Light Green","Plaid","Red",
  1836. X  "Slimy","Tan","White","White Spotted","Wooden","Wrinkled","Yellow",
  1837. X};
  1838. X
  1839. Xchar *woods[MAX_WOODS] = {
  1840. X  "Aspen","Balsa","Banyan","Birch","Cedar","Cottonwood","Cypress","Dogwood",
  1841. X  "Elm","Eucalyptus","Hemlock","Hickory","Ironwood","Locust","Mahogany",
  1842. X  "Maple","Mulberry","Oak","Pine","Redwood","Rosewood","Spruce","Sycamore",
  1843. X  "Teak","Walnut",
  1844. X};
  1845. X
  1846. Xchar *metals[MAX_METALS] = {
  1847. X  "Aluminum","Cast Iron","Chromium","Copper","Gold","Iron","Magnesium",
  1848. X  "Molybdenum","Nickel","Rusty","Silver","Steel","Tin","Titanium","Tungsten",
  1849. X  "Zirconium","Zinc","Aluminum-Plated","Copper-Plated","Gold-Plated",
  1850. X  "Nickel-Plated","Silver-Plated","Steel-Plated","Tin-Plated","Zinc-Plated"
  1851. X};
  1852. X
  1853. Xchar *rocks[MAX_ROCKS] = {
  1854. X  "Alexandrite","Amethyst","Aquamarine","Azurite","Beryl","Bloodstone",
  1855. X  "Calcite","Carnelian","Corundum","Diamond","Emerald","Fluorite","Garnet",
  1856. X  "Granite","Jade","Jasper","Lapis Lazuli","Malachite","Marble","Moonstone",
  1857. X  "Onyx","Opal","Pearl","Quartz","Quartzite","Rhodonite","Ruby","Sapphire",
  1858. X  "Tiger Eye","Topaz","Turquoise","Zircon"
  1859. X};
  1860. X
  1861. Xchar *amulets[MAX_AMULETS] = {
  1862. X  "Amber","Driftwood","Coral","Agate","Ivory","Obsidian",
  1863. X  "Bone","Brass","Bronze","Pewter","Tortoise Shell"
  1864. X};
  1865. X
  1866. Xchar *syllables[MAX_SYLLABLES] = {
  1867. X  "a","ab","ag","aks","ala","an","ankh","app",
  1868. X  "arg","arze","ash","aus","ban","bar","bat","bek",
  1869. X  "bie","bin","bit","bjor","blu","bot","bu",
  1870. X  "byt","comp","con","cos","cre","dalf","dan",
  1871. X  "den","doe","dok","eep","el","eng","er","ere","erk",
  1872. X  "esh","evs","fa","fid","for","fri","fu","gan",
  1873. X  "gar","glen","gop","gre","ha","he","hyd","i",
  1874. X  "ing","ion","ip","ish","it","ite","iv","jo",
  1875. X  "kho","kli","klis","la","lech","man","mar",
  1876. X  "me","mi","mic","mik","mon","mung","mur","nej",
  1877. X  "nelg","nep","ner","nes","nis","nih","nin","o",
  1878. X  "od","ood","org","orn","ox","oxy","pay","pet",
  1879. X  "ple","plu","po","pot","prok","re","rea","rhov",
  1880. X  "ri","ro","rog","rok","rol","sa","san","sat",
  1881. X  "see","sef","seh","shu","ski","sna","sne","snik",
  1882. X  "sno","so","sol","sri","sta","sun","ta","tab",
  1883. X  "tem","ther","ti","tox","trol","tue","turs","u",
  1884. X  "ulk","um","un","uni","ur","val","viv","vly",
  1885. X  "vom","wah","wed","werg","wex","whon","wun","x",
  1886. X  "yerg","yp","zun"
  1887. X};
  1888. X#endif
  1889. X
  1890. X/* used to calculate the number of blows the player gets in combat */
  1891. Xint8u blows_table[7][6] = {
  1892. X/* STR/W:       9  18  67 107 117 118   : DEX */
  1893. X/* <2 */    {  1,  1,  1,  1,  1,  1 },
  1894. X/* <3 */    {  1,  1,  1,  1,  2,  2 },
  1895. X/* <4 */    {  1,  1,  1,  2,  2,  3 },
  1896. X/* <5 */    {  1,  1,  2,  2,  3,  3 },
  1897. X/* <7 */    {  1,  2,  2,  3,  3,  4 },
  1898. X/* <9 */    {  1,  2,  2,  3,  4,  4 },
  1899. X/* >9 */    {  2,  2,  3,  3,  4,  4 }
  1900. X};
  1901. X
  1902. X/* this table is used to generate a psuedo-normal distribution.     See the
  1903. X   function randnor() in misc1.c, this is much faster than calling
  1904. X   transcendental function to calculate a true normal distribution */
  1905. Xint16u normal_table[NORMAL_TABLE_SIZE] = {
  1906. X     206,     613,    1022,    1430,    1838,     2245,      2652,       3058,
  1907. X    3463,    3867,    4271,    4673,    5075,     5475,      5874,       6271,
  1908. X    6667,    7061,    7454,    7845,    8234,     8621,      9006,       9389,
  1909. X    9770,   10148,   10524,   10898,   11269,    11638,     12004,      12367,
  1910. X   12727,   13085,   13440,   13792,   14140,    14486,     14828,      15168,
  1911. X   15504,   15836,   16166,   16492,   16814,    17133,     17449,      17761,
  1912. X   18069,   18374,   18675,   18972,   19266,    19556,     19842,      20124,
  1913. X   20403,   20678,   20949,   21216,   21479,    21738,     21994,      22245,
  1914. X   22493,   22737,   22977,   23213,   23446,    23674,     23899,      24120,
  1915. X   24336,   24550,   24759,   24965,   25166,    25365,     25559,      25750,
  1916. X   25937,   26120,   26300,   26476,   26649,    26818,     26983,      27146,
  1917. X   27304,   27460,   27612,   27760,   27906,    28048,     28187,      28323,
  1918. X   28455,   28585,   28711,   28835,   28955,    29073,     29188,      29299,
  1919. X   29409,   29515,   29619,   29720,   29818,    29914,     30007,      30098,
  1920. X   30186,   30272,   30356,   30437,   30516,    30593,     30668,      30740,
  1921. X   30810,   30879,   30945,   31010,   31072,    31133,     31192,      31249,
  1922. X   31304,   31358,   31410,   31460,   31509,    31556,     31601,      31646,
  1923. X   31688,   31730,   31770,   31808,   31846,    31882,     31917,      31950,
  1924. X   31983,   32014,   32044,   32074,   32102,    32129,     32155,      32180,
  1925. X   32205,   32228,   32251,   32273,   32294,    32314,     32333,      32352,
  1926. X   32370,   32387,   32404,   32420,   32435,    32450,     32464,      32477,
  1927. X   32490,   32503,   32515,   32526,   32537,    32548,     32558,      32568,
  1928. X   32577,   32586,   32595,   32603,   32611,    32618,     32625,      32632,
  1929. X   32639,   32645,   32651,   32657,   32662,    32667,     32672,      32677,
  1930. X   32682,   32686,   32690,   32694,   32698,    32702,     32705,      32708,
  1931. X   32711,   32714,   32717,   32720,   32722,    32725,     32727,      32729,
  1932. X   32731,   32733,   32735,   32737,   32739,    32740,     32742,      32743,
  1933. X   32745,   32746,   32747,   32748,   32749,    32750,     32751,      32752,
  1934. X   32753,   32754,   32755,   32756,   32757,    32757,     32758,      32758,
  1935. X   32759,   32760,   32760,   32761,   32761,    32761,     32762,      32762,
  1936. X   32763,   32763,   32763,   32764,   32764,    32764,     32764,      32765,
  1937. X   32765,   32765,   32765,   32766,   32766,    32766,     32766,      32766,
  1938. X};
  1939. END_OF_FILE
  1940. if test 10747 -ne `wc -c <'source/tables.c'`; then
  1941.     echo shar: \"'source/tables.c'\" unpacked with wrong size!
  1942. fi
  1943. # end of 'source/tables.c'
  1944. fi
  1945. echo shar: End of archive 8 \(of 39\).
  1946. cp /dev/null ark8isdone
  1947. MISSING=""
  1948. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 ; do
  1949.     if test ! -f ark${I}isdone ; then
  1950.     MISSING="${MISSING} ${I}"
  1951.     fi
  1952. done
  1953. if test "${MISSING}" = "" ; then
  1954.     echo You have unpacked all 39 archives.
  1955.     echo "Now run "bldfiles.sh" to build split files"
  1956.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1957. else
  1958.     echo You still need to unpack the following archives:
  1959.     echo "        " ${MISSING}
  1960. fi
  1961. ##  End of shell archive.
  1962. exit 0
  1963.