home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume9 / umoria3 / part25 < prev    next >
Encoding:
Internet Message Format  |  1990-05-21  |  60.2 KB

  1. Path: uunet!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v09i080:  umoria3 - single player dungeon simulation (ver. 5.2), Part25/31
  5. Message-ID: <5615@tekred.CNA.TEK.COM>
  6. Date: 17 May 90 16:28:20 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 2466
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: wilson@ernie.Berkeley.EDU (Jim Wilson)
  12. Posting-number: Volume 9, Issue 80
  13. Archive-name: umoria3/Part25
  14. Supersedes: umoria2: Volume 5, Issue 32-37,41-52,87
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 25 (of 31)."
  25. # Contents:  mac/macio.c source/create.c source/help.c source/store1.c
  26. #   util/mc/symtab.c
  27. # Wrapped by billr@saab on Wed May 16 11:54:42 1990
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'mac/macio.c' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'mac/macio.c'\"
  31. else
  32. echo shar: Extracting \"'mac/macio.c'\" \(12472 characters\)
  33. sed "s/^X//" >'mac/macio.c' <<'END_OF_FILE'
  34. X/* macio.c: terminal I/O code for the macintosh
  35. X
  36. X   Copyright (c) 1989 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#include <scrnmgr.h>
  43. X
  44. X#include <ctype.h>
  45. X
  46. X#include "constant.h"
  47. X#include "config.h"
  48. X#include "types.h"
  49. X#include "externs.h"
  50. X
  51. X#include <string.h>
  52. X
  53. Xvoid exit();
  54. Xunsigned sleep();
  55. X
  56. X/* Attributes of normal and hilighted characters */
  57. X#define ATTR_NORMAL    attrNormal
  58. X#define ATTR_HILITED    attrReversed
  59. X
  60. X/* initializes curses routines */
  61. Xvoid init_curses()
  62. X{
  63. X  /* Primary initialization is done in mac.c since game is restartable */
  64. X  /* Only need to clear the screen here */
  65. X  Rect scrn;
  66. X  
  67. X  scrn.left = scrn.top = 0;
  68. X  scrn.right = SCRN_COLS;
  69. X  scrn.bottom = SCRN_ROWS;
  70. X  EraseScreen(&scrn);
  71. X  UpdateScreen();
  72. X}
  73. X
  74. X/* Set up the terminal into a suitable state for moria.     -CJS- */
  75. Xvoid moriaterm()
  76. X/* Nothing to do on Mac */
  77. X{
  78. X}
  79. X
  80. X/* Dump IO to buffer                    -RAK-    */
  81. Xvoid put_buffer(out_str, row, col)
  82. Xchar *out_str;
  83. Xint row, col;
  84. X{
  85. X  /* The screen manager handles writes past the edge ok */
  86. X  DSetScreenCursor(col, row);
  87. X  DWriteScreenStringAttr(out_str, ATTR_NORMAL);
  88. X}    
  89. X
  90. X/* Dump the IO buffer to terminal            -RAK-    */
  91. Xvoid put_qio()
  92. X{
  93. X  screen_change = TRUE;        /* Let inven_command know something has changed. */
  94. X  UpdateScreen();
  95. X}
  96. X
  97. X/* Put the terminal in the original mode.               -CJS- */
  98. Xvoid restore_term()
  99. X/* Nothing to do on Mac */
  100. X{
  101. X}
  102. X
  103. Xvoid shell_out()
  104. X{
  105. X  alert_error("This command is not implemented on the Macintosh.");
  106. X}
  107. X
  108. X/* Returns a single character input from the terminal.    This silently -CJS-
  109. X   consumes ^R to redraw the screen and reset the terminal, so that this
  110. X   operation can always be performed at any input prompt.  inkey() never
  111. X   returns ^R.    */
  112. Xchar inkey()
  113. X/* The Mac does not need ^R, so it just consumes it */
  114. X/* This routine does nothing special with direction keys */
  115. X/* Just returns their keypad ascii value (e.g. '0'-'9') */
  116. X/* Compare with inkeydir() below */
  117. X{
  118. X  char ch;
  119. X  int dir;
  120. X  int shift_flag, ctrl_flag;
  121. X  
  122. X  put_qio();
  123. X  command_count = 0;
  124. X  
  125. X  do {
  126. X    macgetkey(&ch, FALSE);
  127. X  } while (ch == CTRL('R'));
  128. X  
  129. X  dir = extractdir(ch, &shift_flag, &ctrl_flag);
  130. X  if (dir != -1)
  131. X    ch = '0' + dir;
  132. X  
  133. X  return(ch);
  134. X}
  135. X
  136. Xchar inkeydir()
  137. X/* The Mac does not need ^R, so it just consumes it */
  138. X/* This routine translates the direction keys in rogue-like mode */
  139. X{
  140. X  char ch;
  141. X  int dir;
  142. X  int shift_flag, ctrl_flag;
  143. X  static char tab[9] = {
  144. X    'b',        'j',        'n',
  145. X    'h',        '.',        'l',
  146. X    'y',        'k',        'u'
  147. X  };
  148. X  static char shifttab[9] = {
  149. X    'B',        'J',        'N',
  150. X    'H',        '.',        'L',
  151. X    'Y',        'K',        'U'
  152. X  };
  153. X  static char ctrltab[9] = {
  154. X    CTRL('B'),    CTRL('J'),    CTRL('N'),
  155. X    CTRL('H'),    '.',        CTRL('L'),
  156. X    CTRL('Y'),    CTRL('K'),    CTRL('U')
  157. X  };
  158. X  
  159. X  put_qio();
  160. X  command_count = 0;
  161. X  
  162. X  do {
  163. X    macgetkey(&ch, FALSE);
  164. X  } while (ch == CTRL('R'));
  165. X  
  166. X  dir = extractdir(ch, &shift_flag, &ctrl_flag);
  167. X  
  168. X  if (dir != -1) {
  169. X    if (!rogue_like_commands) {
  170. X      ch = '0' + dir;
  171. X    }
  172. X    else {
  173. X      if (ctrl_flag)
  174. X    ch = ctrltab[dir - 1];
  175. X      else if (shift_flag)
  176. X    ch = shifttab[dir - 1];
  177. X      else
  178. X    ch = tab[dir - 1];
  179. X    }
  180. X  }
  181. X  
  182. X  return(ch);
  183. X}
  184. X
  185. X/* Flush the buffer                    -RAK-    */
  186. Xvoid flush()
  187. X{
  188. X/* Removed put_qio() call.  Reduces flashing.  Doesn't seem to hurt. */
  189. X  FlushScreenKeys();
  190. X}
  191. X
  192. X/* Clears given line of text                -RAK-    */
  193. Xvoid erase_line(row, col)
  194. Xint row;
  195. Xint col;
  196. X{
  197. X  Rect line;
  198. X  
  199. X  if (row == MSG_LINE && msg_flag)
  200. X    msg_print(NULL);
  201. X    
  202. X  line.left = col;
  203. X  line.top = row;
  204. X  line.right = SCRN_COLS;
  205. X  line.bottom = row + 1;
  206. X  DEraseScreen(&line);
  207. X}
  208. X
  209. X/* Clears screen */
  210. Xvoid clear_screen()
  211. X{
  212. X  Rect area;
  213. X  
  214. X  if (msg_flag)
  215. X    msg_print(NULL);
  216. X    
  217. X  area.left = area.top = 0;
  218. X  area.right = SCRN_COLS;
  219. X  area.bottom = SCRN_ROWS;
  220. X  DEraseScreen(&area);
  221. X}
  222. X
  223. Xvoid clear_from (row)
  224. Xint row;
  225. X{
  226. X  Rect area;
  227. X  
  228. X  area.left = 0;
  229. X  area.top = row;
  230. X  area.right = SCRN_COLS;
  231. X  area.bottom = SCRN_ROWS;
  232. X  DEraseScreen(&area);
  233. X}
  234. X
  235. X/* Outputs a char to a given interpolated y, x position    -RAK-    */
  236. X/* sign bit of a character used to indicate standout mode. -CJS */
  237. Xvoid print(ch, row, col)
  238. Xchar ch;
  239. Xint row;
  240. Xint col;
  241. X{
  242. X  char cnow, anow, cnew, anew;
  243. X  
  244. X  row -= panel_row_prt;/* Real co-ords convert to screen positions */
  245. X  col -= panel_col_prt;
  246. X  
  247. X  if (ch & 0x80) {
  248. X    cnew = ch & ~0x80;
  249. X    anew = ATTR_HILITED;
  250. X  }
  251. X  else {
  252. X    cnew = ch;
  253. X    anew = ATTR_NORMAL;
  254. X  }
  255. X  
  256. X  GetScreenCharAttr(&cnow, &anow, col, row);    /* Check current */
  257. X  
  258. X  if ((cnow != ch) || (anow != anew))    /* If char is already set, ignore op */
  259. X    DSetScreenCharAttr(cnew, anew, col, row);
  260. X}
  261. X
  262. X/* Moves the cursor to a given interpolated y, x position    -RAK-    */
  263. Xvoid move_cursor_relative(row, col)
  264. Xint row;
  265. Xint col;
  266. X{
  267. X  row -= panel_row_prt;/* Real co-ords convert to screen positions */
  268. X  col -= panel_col_prt;
  269. X  
  270. X  DSetScreenCursor(col, row);
  271. X}
  272. X
  273. X/* Print a message so as not to interrupt a counted command. -CJS- */
  274. Xvoid count_msg_print(p)
  275. Xchar *p;
  276. X{
  277. X  int i;
  278. X
  279. X  i = command_count;
  280. X  msg_print(p);
  281. X  command_count = i;
  282. X}
  283. X
  284. X/* Outputs a line to a given y, x position        -RAK-    */
  285. Xvoid prt(str_buff, row, col)
  286. Xchar *str_buff;
  287. Xint row;
  288. Xint col;
  289. X{
  290. X  Rect line;
  291. X  
  292. X  if (row == MSG_LINE && msg_flag)
  293. X    msg_print(NULL);
  294. X    
  295. X  line.left = col;
  296. X  line.top = row;
  297. X  line.right = SCRN_COLS;
  298. X  line.bottom = row + 1;
  299. X  DEraseScreen(&line);
  300. X  
  301. X  put_buffer(str_buff, row, col);
  302. X}
  303. X
  304. X/* move cursor to a given y, x position */
  305. Xvoid move_cursor(row, col)
  306. Xint row, col;
  307. X{
  308. X  DSetScreenCursor(col, row);
  309. X}
  310. X
  311. X/* Outputs message to top line of screen                */
  312. X/* These messages are kept for later reference.     */
  313. Xvoid msg_print(str_buff)
  314. Xchar *str_buff;
  315. X{
  316. X  register int old_len;
  317. X  char in_char;
  318. X  Rect line;
  319. X
  320. X  if (msg_flag)
  321. X    {
  322. X      old_len = strlen(old_msg[last_msg]) + 1;
  323. X      /* ensure that the complete -more- message is visible. */
  324. X      if (old_len > 73)
  325. X    old_len = 73;
  326. X      put_buffer(" -more-", MSG_LINE, old_len);
  327. X      /* let sigint handler know that we are waiting for a space */
  328. X      wait_for_more = 1;
  329. X      do
  330. X    {
  331. X      in_char = inkey();
  332. X    }
  333. X      while ((in_char != ' ') && (in_char != ESCAPE) && (in_char != '\n') &&
  334. X         (in_char != '\r'));
  335. X      wait_for_more = 0;
  336. X    }
  337. X  line.left = 0;
  338. X  line.top = MSG_LINE;
  339. X  line.right = SCRN_COLS;
  340. X  line.bottom = MSG_LINE+1;
  341. X  DEraseScreen(&line);
  342. X
  343. X  /* Make the null string a special case.  -CJS- */
  344. X  if (str_buff)
  345. X    {
  346. X      put_buffer(str_buff, MSG_LINE, 0);
  347. X      command_count = 0;
  348. X      last_msg++;
  349. X      if (last_msg >= MAX_SAVE_MSG)
  350. X    last_msg = 0;
  351. X      (void) strncpy(old_msg[last_msg], str_buff, VTYPESIZ);
  352. X      old_msg[last_msg][VTYPESIZ - 1] = '\0';
  353. X      msg_flag = TRUE;
  354. X    }
  355. X  else
  356. X    msg_flag = FALSE;
  357. X}
  358. X
  359. X/* Used to verify a choice - user gets the chance to abort choice.  -CJS- */
  360. Xint get_check(prompt)
  361. Xchar *prompt;
  362. X{
  363. X  int res;
  364. X  int x, y;
  365. X
  366. X  prt(prompt, 0, 0);
  367. X  GetScreenCursor(&x, &y);
  368. X  if (x > 73)
  369. X    DSetScreenCursor(73, y);
  370. X  DWriteScreenStringAttr(" [y/n]", ATTR_NORMAL);
  371. X  do
  372. X    {
  373. X      res = inkey();
  374. X    }
  375. X  while(res == ' ');
  376. X  erase_line(0, 0);
  377. X  if (res == 'Y' || res == 'y')
  378. X    return TRUE;
  379. X  else
  380. X    return FALSE;
  381. X}
  382. X
  383. X/* Prompts (optional) and returns ord value of input char    */
  384. X/* Function returns false if <ESCAPE> is input    */
  385. Xint get_com(prompt, command)
  386. Xchar *prompt;
  387. Xchar *command;
  388. X{
  389. X  int res;
  390. X
  391. X  if (prompt)
  392. X    prt(prompt, 0, 0);
  393. X  *command = inkey();
  394. X  if (*command == 0 || *command == ESCAPE)
  395. X    res = FALSE;
  396. X  else
  397. X    res = TRUE;
  398. X  erase_line(MSG_LINE, 0);
  399. X  return(res);
  400. X}
  401. X
  402. X/* Same as get_com(), but translates direction keys from keypad */
  403. Xint get_comdir(prompt, command)
  404. Xchar *prompt;
  405. Xchar *command;
  406. X{
  407. X  int res;
  408. X
  409. X  if (prompt)
  410. X    prt(prompt, 0, 0);
  411. X  *command = inkeydir();
  412. X  if (*command == 0 || *command == ESCAPE)
  413. X    res = FALSE;
  414. X  else
  415. X    res = TRUE;
  416. X  erase_line(MSG_LINE, 0);
  417. X  return(res);
  418. X}
  419. X
  420. X/* Gets a string terminated by <RETURN>        */
  421. X/* Function returns false if <ESCAPE> is input    */
  422. Xint get_string(in_str, row, column, slen)
  423. Xchar *in_str;
  424. Xint row, column, slen;
  425. X{
  426. X  register int start_col, end_col, i;
  427. X  char *p;
  428. X  int flag, abort;
  429. X  Rect area;
  430. X
  431. X  abort = FALSE;
  432. X  flag    = FALSE;
  433. X  area.left = column;
  434. X  area.top = row;
  435. X  area.right = column + slen;
  436. X  area.bottom = row + 1;
  437. X  DEraseScreen(&area);
  438. X  DSetScreenCursor(column, row);
  439. X  start_col = column;
  440. X  end_col = column + slen - 1;
  441. X  if (end_col > 79)
  442. X    {
  443. X      slen = 80 - column;
  444. X      end_col = 79;
  445. X    }
  446. X  p = in_str;
  447. X  do
  448. X    {
  449. X      i = inkey();
  450. X      switch(i)
  451. X    {
  452. X    case ESCAPE:
  453. X      abort = TRUE;
  454. X      break;
  455. X    case CTRL('J'): case CTRL('M'):
  456. X      flag    = TRUE;
  457. X      break;
  458. X    case DELETE: case CTRL('H'):
  459. X      if (column > start_col)
  460. X        {
  461. X          column--;
  462. X          put_buffer(" ", row, column);
  463. X          move_cursor(row, column);
  464. X          *--p = '\0';
  465. X        }
  466. X      break;
  467. X    default:
  468. X      if (!isprint(i) || column > end_col)
  469. X        bell();
  470. X      else
  471. X        {
  472. X          DSetScreenCursor(column, row);
  473. X          DWriteScreenCharAttr((char) i, ATTR_NORMAL);
  474. X          *p++ = i;
  475. X          column++;
  476. X        }
  477. X      break;
  478. X    }
  479. X    }
  480. X  while ((!flag) && (!abort));
  481. X  if (abort)
  482. X    return(FALSE);
  483. X  /* Remove trailing blanks    */
  484. X  while (p > in_str && p[-1] == ' ')
  485. X    p--;
  486. X  *p = '\0';
  487. X  return(TRUE);
  488. X}
  489. X
  490. X/* Pauses for user response before returning        -RAK-    */
  491. Xvoid pause_line(prt_line)
  492. Xint prt_line;
  493. X{
  494. X  prt("[Press any key to continue.]", prt_line, 23);
  495. X  (void) inkey();
  496. X  erase_line(prt_line, 0);
  497. X}
  498. X
  499. X/* Pauses for user response before returning        -RAK-    */
  500. X/* NOTE: Delay is for players trying to roll up "perfect"    */
  501. X/*    characters.  Make them wait a bit.            */
  502. Xvoid pause_exit(prt_line, delay)
  503. Xint prt_line;
  504. Xint delay;
  505. X{
  506. X  char dummy;
  507. X
  508. X  prt("[Press any key to continue, or Q to exit.]", prt_line, 10);
  509. X  dummy = inkey();
  510. X  if (dummy == 'Q')
  511. X    {
  512. X      erase_line(prt_line, 0);
  513. X      if (delay > 0)  (void) sleep((unsigned)delay);
  514. X      exit_game();
  515. X    }
  516. X  erase_line(prt_line, 0);
  517. X}
  518. X
  519. Xvoid save_screen()
  520. X{
  521. X  mac_save_screen();
  522. X}
  523. X
  524. Xvoid restore_screen()
  525. X{
  526. X  mac_restore_screen();
  527. X}
  528. X
  529. Xvoid bell()
  530. X{
  531. X  put_qio();
  532. X  mac_beep();
  533. X}
  534. X
  535. X/* definitions used by screen_map() */
  536. X/* index into border character array */
  537. X#define TL 0    /* top left */
  538. X#define TR 1
  539. X#define BL 2
  540. X#define BR 3
  541. X#define HE 4    /* horizontal edge */
  542. X#define VE 5
  543. X
  544. X/* Display highest priority object in the RATIO by RATIO area */
  545. X#define    RATIO 3
  546. X
  547. Xvoid screen_map()
  548. X{
  549. X  register int    i, j;
  550. X  static int8u border[6] = {
  551. X    '+', '+', '+', '+', '-', '|'    /* normal chars */
  552. X  };
  553. X  int8u map[MAX_WIDTH / RATIO + 1];
  554. X  int8u tmp;
  555. X  int priority[256];
  556. X  int row, orow, col, myrow, mycol = 0;
  557. X
  558. X  for (i = 0; i < 256; i++)
  559. X    priority[i] = 0;
  560. X  priority['<'] = 5;
  561. X  priority['>'] = 5;
  562. X  priority['@'] = 10;
  563. X  priority['#'] = -5;
  564. X  priority['.'] = -10;
  565. X  priority['\''] = -3;
  566. X  priority[' '] = -15;
  567. X
  568. X  save_screen();
  569. X  clear_screen();
  570. X  DSetScreenCursor(0, 0);
  571. X  DWriteScreenCharAttr(border[TL], ATTR_NORMAL);
  572. X  for (i = 0; i < MAX_WIDTH / RATIO; i++)
  573. X    DWriteScreenCharAttr(border[HE], ATTR_NORMAL);
  574. X  DWriteScreenCharAttr(border[TR], ATTR_NORMAL);
  575. X  orow = -1;
  576. X  map[MAX_WIDTH / RATIO] = '\0';
  577. X  for (i = 0; i < MAX_HEIGHT; i++)
  578. X    {
  579. X      row = i / RATIO;
  580. X      if (row != orow)
  581. X    {
  582. X      if (orow >= 0)
  583. X        {
  584. X          DSetScreenCursor(0, orow+1);
  585. X          DWriteScreenCharAttr(border[VE], ATTR_NORMAL);
  586. X          DWriteScreenString(map);
  587. X          DWriteScreenCharAttr(border[VE], ATTR_NORMAL);
  588. X        }
  589. X      for (j = 0; j < MAX_WIDTH / RATIO; j++)
  590. X        map[j] = ' ';
  591. X      orow = row;
  592. X    }
  593. X      for (j = 0; j < MAX_WIDTH; j++)
  594. X    {
  595. X      col = j / RATIO;
  596. X      tmp = loc_symbol(i, j);
  597. X      /* Attributes are not handled correctly by DWriteScreenString */
  598. X      /* Also, no special priority for the vein character */
  599. X      if (tmp & 0x80)
  600. X        tmp &= ~0x80;
  601. X      if (priority[map[col]] < priority[tmp])
  602. X        map[col] = tmp;
  603. X      if (map[col] == '@')
  604. X        {
  605. X          mycol = col + 1; /* account for border */
  606. X          myrow = row + 1;
  607. X        }
  608. X    }
  609. X    }
  610. X  if (orow >= 0)
  611. X    {
  612. X      DSetScreenCursor(0, orow+1);
  613. X      DWriteScreenCharAttr(border[VE], ATTR_NORMAL);
  614. X      DWriteScreenString(map);
  615. X      DWriteScreenCharAttr(border[VE], ATTR_NORMAL);
  616. X    }
  617. X  DSetScreenCursor(0, orow + 2);
  618. X  DWriteScreenCharAttr(border[BL], ATTR_NORMAL);
  619. X  for (i = 0; i < MAX_WIDTH / RATIO; i++)
  620. X    DWriteScreenCharAttr(border[HE], ATTR_NORMAL);
  621. X  DWriteScreenCharAttr(border[BR], ATTR_NORMAL);
  622. X  DSetScreenCursor(23, 23);
  623. X  DWriteScreenStringAttr("Hit any key to continue", ATTR_NORMAL);
  624. X  if (mycol > 0)
  625. X    DSetScreenCursor(mycol, myrow);
  626. X  (void) inkey();
  627. X  restore_screen();
  628. X}
  629. END_OF_FILE
  630. if test 12472 -ne `wc -c <'mac/macio.c'`; then
  631.     echo shar: \"'mac/macio.c'\" unpacked with wrong size!
  632. fi
  633. # end of 'mac/macio.c'
  634. fi
  635. if test -f 'source/create.c' -a "${1}" != "-c" ; then 
  636.   echo shar: Will not clobber existing file \"'source/create.c'\"
  637. else
  638. echo shar: Extracting \"'source/create.c'\" \(12587 characters\)
  639. sed "s/^X//" >'source/create.c' <<'END_OF_FILE'
  640. X/* create.c: create a player character
  641. X
  642. X   Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
  643. X
  644. X   This software may be copied and distributed for educational, research, and
  645. X   not for profit purposes provided that this copyright and statement are
  646. X   included in all such copies. */
  647. X
  648. X#include "constant.h"
  649. X#include "config.h"
  650. X#include "types.h"
  651. X#include "externs.h"
  652. X
  653. X#ifdef USG
  654. X#ifndef ATARIST_MWC
  655. X#include <string.h>
  656. X#endif
  657. X#else
  658. X#include <strings.h>
  659. X#endif
  660. X
  661. X#if defined(LINT_ARGS)
  662. Xstatic void get_stats(void);
  663. Xstatic void change_stat(int, int8);
  664. Xstatic void get_all_stats(void);
  665. Xstatic void choose_race(void);
  666. Xstatic void print_history(void);
  667. Xstatic void get_history(void);
  668. Xstatic void get_sex(void);
  669. Xstatic void get_ahw(void);
  670. Xstatic void get_class(void);
  671. Xstatic int monval(int8u);
  672. Xstatic void get_money(void);
  673. X#endif
  674. X
  675. X
  676. X/* Generates character's stats                -JWT-    */
  677. Xstatic void get_stats()
  678. X{
  679. X  register int i, tot;
  680. X  int dice[18];
  681. X
  682. X  do
  683. X    {
  684. X      tot = 0;
  685. X      for (i = 0; i < 18; i++)
  686. X    {
  687. X      dice[i] = randint (3 + i % 3);  /* Roll 3,4,5 sided dice once each */
  688. X      tot += dice[i];
  689. X    }
  690. X    }
  691. X  while (tot <= 42 || tot >= 54);
  692. X
  693. X  for (i = 0; i < 6; i++)
  694. X    py.stats.max_stat[i] = 5 + dice[3*i] + dice[3*i+1] + dice[3*i+2];
  695. X}
  696. X
  697. X
  698. X/* Changes stats by given amount                -JWT-    */
  699. Xstatic void change_stat(stat, amount)
  700. Xint stat;
  701. Xint16 amount;
  702. X{
  703. X  register int i;
  704. X  register int tmp_stat;
  705. X
  706. X  tmp_stat = py.stats.max_stat[stat];
  707. X  if (amount < 0)
  708. X    for (i = 0; i > amount; i--)
  709. X      {
  710. X    if (tmp_stat > 108)
  711. X      tmp_stat--;
  712. X    else if (tmp_stat > 88)
  713. X      tmp_stat += -randint(6) - 2;
  714. X    else if (tmp_stat > 18)
  715. X      {
  716. X        tmp_stat += -randint(15) - 5;
  717. X        if (tmp_stat < 18)
  718. X          tmp_stat = 18;
  719. X      }
  720. X    else if (tmp_stat > 3)
  721. X      tmp_stat--;
  722. X      }
  723. X  else
  724. X    for (i = 0; i < amount; i++)
  725. X      {
  726. X    if (tmp_stat < 18)
  727. X      tmp_stat++;
  728. X    else if (tmp_stat < 88)
  729. X      tmp_stat += randint(15) + 5;
  730. X    else if (tmp_stat < 108)
  731. X      tmp_stat += randint(6) + 2;
  732. X    else if (tmp_stat < 118)
  733. X      tmp_stat++;
  734. X      }
  735. X  py.stats.max_stat[stat] = tmp_stat;
  736. X}
  737. X
  738. X
  739. X/* generate all stats and modify for race. needed in a separate module so
  740. X   looping of character selection would be allowed     -RGM- */
  741. Xstatic void get_all_stats ()
  742. X{
  743. X  register player_type *p_ptr;
  744. X  register race_type *r_ptr;
  745. X  register int j;
  746. X
  747. X  p_ptr = &py;
  748. X  r_ptr = &race[p_ptr->misc.prace];
  749. X  get_stats ();
  750. X  change_stat (A_STR, r_ptr->str_adj);
  751. X  change_stat (A_INT, r_ptr->int_adj);
  752. X  change_stat (A_WIS, r_ptr->wis_adj);
  753. X  change_stat (A_DEX, r_ptr->dex_adj);
  754. X  change_stat (A_CON, r_ptr->con_adj);
  755. X  change_stat (A_CHR, r_ptr->chr_adj);
  756. X  for (j = 0; j < 6; j++)
  757. X    {
  758. X      py.stats.cur_stat[j] = py.stats.max_stat[j];
  759. X      set_use_stat (j);
  760. X    }
  761. X
  762. X  p_ptr->misc.srh    = r_ptr->srh;
  763. X  p_ptr->misc.bth    = r_ptr->bth;
  764. X  p_ptr->misc.bthb   = r_ptr->bthb;
  765. X  p_ptr->misc.fos    = r_ptr->fos;
  766. X  p_ptr->misc.stl    = r_ptr->stl;
  767. X  p_ptr->misc.save   = r_ptr->bsav;
  768. X  p_ptr->misc.hitdie = r_ptr->bhitdie;
  769. X  p_ptr->misc.lev    = 1;
  770. X  p_ptr->misc.ptodam = todam_adj();
  771. X  p_ptr->misc.ptohit = tohit_adj();
  772. X  p_ptr->misc.ptoac  = 0;
  773. X  p_ptr->misc.pac    = toac_adj();
  774. X  p_ptr->misc.expfact = r_ptr->b_exp;
  775. X  p_ptr->flags.see_infra = r_ptr->infra;
  776. X}
  777. X
  778. X
  779. X/* Allows player to select a race            -JWT-    */
  780. Xstatic void choose_race()
  781. X{
  782. X  register int j, k;
  783. X  int l, m, exit_flag;
  784. X  char s;
  785. X  char tmp_str[80];
  786. X  register player_type *p_ptr;
  787. X  register race_type *r_ptr;
  788. X
  789. X  j = 0;
  790. X  k = 0;
  791. X  l = 2;
  792. X  m = 21;
  793. X  clear_from (20);
  794. X  put_buffer("Choose a race (? for Help):", 20, 2);
  795. X  do
  796. X    {
  797. X      (void) sprintf(tmp_str, "%c) %s", k+'a', race[j].trace);
  798. X      put_buffer(tmp_str, m, l);
  799. X      k++;
  800. X      l += 15;
  801. X      if (l > 70)
  802. X    {
  803. X      l = 2;
  804. X      m++;
  805. X    }
  806. X      j++;
  807. X    }
  808. X  while (j < MAX_RACES);
  809. X  exit_flag = FALSE;
  810. X  do
  811. X    {
  812. X      move_cursor (20, 30);
  813. X      s = inkey();
  814. X      j = s - 'a';
  815. X      if ((j < MAX_RACES) && (j >= 0))
  816. X    exit_flag = TRUE;
  817. X      else if (s == '?')
  818. X    helpfile (MORIA_WELCOME);
  819. X      else
  820. X    bell ();
  821. X    }
  822. X  while (!exit_flag);
  823. X
  824. X  p_ptr = &py;
  825. X  r_ptr = &race[j];
  826. X  p_ptr->misc.prace  = j;
  827. X  put_buffer(r_ptr->trace, 3, 15);
  828. X}
  829. X
  830. X
  831. X/* Will print the history of a character            -JWT-    */
  832. Xstatic void print_history()
  833. X{
  834. X  register int i;
  835. X
  836. X  put_buffer("Character Background", 14, 27);
  837. X  for (i = 0; i < 4; i++)
  838. X    prt(py.misc.history[i], i+15, 10);
  839. X}
  840. X
  841. X
  842. X/* Get the racial history, determines social class    -RAK-    */
  843. X/* Assumptions:    Each race has init history beginning at        */
  844. X/*        (race-1)*3+1                    */
  845. X/*        All history parts are in ascending order    */
  846. Xstatic void get_history()
  847. X{
  848. X  int hist_ptr, cur_ptr, test_roll, flag;
  849. X  register int start_pos, end_pos, cur_len;
  850. X  int line_ctr, new_start, social_class;
  851. X  char history_block[240];
  852. X  register background_type *b_ptr;
  853. X
  854. X  /* Get a block of history text                */
  855. X  hist_ptr = py.misc.prace*3 + 1;
  856. X  history_block[0] = '\0';
  857. X  social_class = randint(4);
  858. X  cur_ptr = 0;
  859. X  do
  860. X    {
  861. X      flag = FALSE;
  862. X      do
  863. X    {
  864. X      if (background[cur_ptr].chart == hist_ptr)
  865. X        {
  866. X          test_roll = randint(100);
  867. X          while (test_roll > background[cur_ptr].roll)
  868. X        cur_ptr++;
  869. X          b_ptr = &background[cur_ptr];
  870. X          (void) strcat(history_block, b_ptr->info);
  871. X          social_class += b_ptr->bonus - 50;
  872. X          if (hist_ptr > b_ptr->next)
  873. X        cur_ptr = 0;
  874. X          hist_ptr = b_ptr->next;
  875. X          flag = TRUE;
  876. X        }
  877. X      else
  878. X        cur_ptr++;
  879. X    }
  880. X      while (!flag);
  881. X    }
  882. X  while (hist_ptr >= 1);
  883. X
  884. X  /* clear the previous history strings */
  885. X  for (hist_ptr = 0; hist_ptr < 4; hist_ptr++)
  886. X    py.misc.history[hist_ptr][0] = '\0';
  887. X
  888. X  /* Process block of history text for pretty output    */
  889. X  start_pos = 0;
  890. X  end_pos   = strlen(history_block) - 1;
  891. X  line_ctr  = 0;
  892. X  flag = FALSE;
  893. X  while (history_block[end_pos] == ' ')
  894. X    end_pos--;
  895. X  do
  896. X    {
  897. X      while (history_block[start_pos] == ' ')
  898. X    start_pos++;
  899. X      cur_len = end_pos - start_pos + 1;
  900. X      if (cur_len > 60)
  901. X    {
  902. X      cur_len = 60;
  903. X      while (history_block[start_pos+cur_len-1] != ' ')
  904. X        cur_len--;
  905. X      new_start = start_pos + cur_len;
  906. X      while (history_block[start_pos+cur_len-1] == ' ')
  907. X        cur_len--;
  908. X    }
  909. X      else
  910. X    flag = TRUE;
  911. X      (void) strncpy(py.misc.history[line_ctr], &history_block[start_pos],
  912. X             cur_len);
  913. X      py.misc.history[line_ctr][cur_len] = '\0';
  914. X      line_ctr++;
  915. X      start_pos = new_start;
  916. X    }
  917. X  while (!flag);
  918. X
  919. X  /* Compute social class for player            */
  920. X  if (social_class > 100)
  921. X    social_class = 100;
  922. X  else if (social_class < 1)
  923. X    social_class = 1;
  924. X  py.misc.sc = social_class;
  925. X}
  926. X
  927. X
  928. X/* Gets the character's sex                -JWT-    */
  929. Xstatic void get_sex()
  930. X{
  931. X  register int exit_flag;
  932. X  char c;
  933. X
  934. X  exit_flag = FALSE;
  935. X  clear_from (20);
  936. X  put_buffer("Choose a sex (? for Help):", 20, 2);
  937. X  put_buffer("m) Male       f) Female", 21, 2);
  938. X  do
  939. X    {
  940. X      move_cursor (20, 29);
  941. X      /* speed not important here */
  942. X      c = inkey();
  943. X      if (c == 'f' || c == 'F')
  944. X    {
  945. X      py.misc.male = FALSE;
  946. X      put_buffer("Female", 4, 15);
  947. X      exit_flag = TRUE;
  948. X    }
  949. X      else if (c == 'm' || c == 'M')
  950. X    {
  951. X      py.misc.male = TRUE;
  952. X      put_buffer("Male", 4, 15);
  953. X      exit_flag = TRUE;
  954. X    }
  955. X      else if (c == '?')
  956. X    helpfile (MORIA_WELCOME);
  957. X      else
  958. X    bell ();
  959. X    }
  960. X  while (!exit_flag);
  961. X}
  962. X
  963. X
  964. X/* Computes character's age, height, and weight        -JWT-    */
  965. Xstatic void get_ahw()
  966. X{
  967. X  register int i;
  968. X
  969. X  i = py.misc.prace;
  970. X  py.misc.age = race[i].b_age + randint((int)race[i].m_age);
  971. X  if (py.misc.male)
  972. X    {
  973. X      py.misc.ht = randnor((int)race[i].m_b_ht, (int)race[i].m_m_ht);
  974. X      py.misc.wt = randnor((int)race[i].m_b_wt, (int)race[i].m_m_wt);
  975. X    }
  976. X  else
  977. X    {
  978. X      py.misc.ht = randnor((int)race[i].f_b_ht, (int)race[i].f_m_ht);
  979. X      py.misc.wt = randnor((int)race[i].f_b_wt, (int)race[i].f_m_wt);
  980. X    }
  981. X  py.misc.disarm = race[i].b_dis + todis_adj();
  982. X}
  983. X
  984. X
  985. X/* Gets a character class                -JWT-    */
  986. Xstatic void get_class()
  987. X{
  988. X  register int i, j;
  989. X  int k, l, m, min_value, max_value;
  990. X  int cl[MAX_CLASS], exit_flag;
  991. X  register struct misc *m_ptr;
  992. X  register player_type *p_ptr;
  993. X  class_type *c_ptr;
  994. X  char tmp_str[80], s;
  995. X  int32u mask;
  996. X
  997. X  for (j = 0; j < MAX_CLASS; j++)
  998. X    cl[j] = 0;
  999. X  i = py.misc.prace;
  1000. X  j = 0;
  1001. X  k = 0;
  1002. X  l = 2;
  1003. X  m = 21;
  1004. X  mask = 0x1;
  1005. X  clear_from (20);
  1006. X  put_buffer("Choose a class (? for Help):", 20, 2);
  1007. X  do
  1008. X    {
  1009. X      if (race[i].rtclass & mask)
  1010. X    {
  1011. X      (void) sprintf(tmp_str, "%c) %s", k+'a', class[j].title);
  1012. X      put_buffer(tmp_str, m, l);
  1013. X      cl[k] = j;
  1014. X      l += 15;
  1015. X      if (l > 70)
  1016. X        {
  1017. X          l = 2;
  1018. X          m++;
  1019. X        }
  1020. X      k++;
  1021. X    }
  1022. X      j++;
  1023. X      mask <<= 1;
  1024. X    }
  1025. X  while (j < MAX_CLASS);
  1026. X  py.misc.pclass = 0;
  1027. X  exit_flag = FALSE;
  1028. X  do
  1029. X    {
  1030. X      move_cursor (20, 31);
  1031. X      s = inkey();
  1032. X      j = s - 'a';
  1033. X      if ((j < k) && (j >= 0))
  1034. X    {
  1035. X      py.misc.pclass = cl[j];
  1036. X      c_ptr = &class[py.misc.pclass];
  1037. X      exit_flag = TRUE;
  1038. X      clear_from (20);
  1039. X      put_buffer(c_ptr->title, 5, 15);
  1040. X
  1041. X      /* Adjust the stats for the class adjustment        -RAK-    */
  1042. X      p_ptr = &py;
  1043. X      change_stat (A_STR, c_ptr->madj_str);
  1044. X      change_stat (A_INT, c_ptr->madj_int);
  1045. X      change_stat (A_WIS, c_ptr->madj_wis);
  1046. X      change_stat (A_DEX, c_ptr->madj_dex);
  1047. X      change_stat (A_CON, c_ptr->madj_con);
  1048. X      change_stat (A_CHR, c_ptr->madj_chr);
  1049. X      for(i = 0; i < 6; i++)
  1050. X        {
  1051. X          p_ptr->stats.cur_stat[i] = p_ptr->stats.max_stat[i];
  1052. X          set_use_stat(i);
  1053. X        }
  1054. X
  1055. X      p_ptr->misc.ptodam = todam_adj();    /* Real values        */
  1056. X      p_ptr->misc.ptohit = tohit_adj();
  1057. X      p_ptr->misc.ptoac  = toac_adj();
  1058. X      p_ptr->misc.pac    = 0;
  1059. X      p_ptr->misc.dis_td = p_ptr->misc.ptodam; /* Displayed values    */
  1060. X      p_ptr->misc.dis_th = p_ptr->misc.ptohit;
  1061. X      p_ptr->misc.dis_tac= p_ptr->misc.ptoac;
  1062. X      p_ptr->misc.dis_ac = p_ptr->misc.pac + p_ptr->misc.dis_tac;
  1063. X
  1064. X      /* now set misc stats, do this after setting stats because
  1065. X         of con_adj() for hitpoints */
  1066. X      m_ptr = &py.misc;
  1067. X      m_ptr->hitdie += c_ptr->adj_hd;
  1068. X      m_ptr->mhp = con_adj() + m_ptr->hitdie;
  1069. X      m_ptr->chp = m_ptr->mhp;
  1070. X      m_ptr->chp_frac = 0;
  1071. X
  1072. X      /* initialize hit_points array */
  1073. X      /* put bounds on total possible hp, only succeed if it is within
  1074. X         1/8 of average value */
  1075. X      min_value = (MAX_PLAYER_LEVEL*3/8 * (m_ptr->hitdie-1)) +
  1076. X        MAX_PLAYER_LEVEL;
  1077. X      max_value = (MAX_PLAYER_LEVEL*5/8 * (m_ptr->hitdie-1)) +
  1078. X        MAX_PLAYER_LEVEL;
  1079. X      player_hp[0] = m_ptr->hitdie;
  1080. X      do
  1081. X        {
  1082. X          for (i = 1; i < MAX_PLAYER_LEVEL; i++)
  1083. X        {
  1084. X          player_hp[i] = randint((int)m_ptr->hitdie);
  1085. X          player_hp[i] += player_hp[i-1];
  1086. X        }
  1087. X        }
  1088. X      while ((player_hp[MAX_PLAYER_LEVEL-1] < min_value) ||
  1089. X         (player_hp[MAX_PLAYER_LEVEL-1] > max_value));
  1090. X
  1091. X      m_ptr->bth += c_ptr->mbth;
  1092. X      m_ptr->bthb += c_ptr->mbthb;    /*RAK*/
  1093. X      m_ptr->srh += c_ptr->msrh;
  1094. X      m_ptr->disarm += c_ptr->mdis;
  1095. X      m_ptr->fos += c_ptr->mfos;
  1096. X      m_ptr->stl += c_ptr->mstl;
  1097. X      m_ptr->save += c_ptr->msav;
  1098. X      m_ptr->expfact += c_ptr->m_exp;
  1099. X    }
  1100. X      else if (s == '?')
  1101. X    helpfile (MORIA_WELCOME);
  1102. X      else
  1103. X    bell ();
  1104. X    }
  1105. X  while (!exit_flag);
  1106. X}
  1107. X
  1108. X
  1109. X/* Given a stat value, return a monetary value, which affects the amount
  1110. X   of gold a player has. */
  1111. Xstatic int monval (i)
  1112. Xint8u i;
  1113. X{
  1114. X  return 5 * (i - 10);
  1115. X}
  1116. X
  1117. X
  1118. Xstatic void get_money()
  1119. X{
  1120. X  register int tmp, gold;
  1121. X  register int8u *a_ptr;
  1122. X
  1123. X  a_ptr = py.stats.max_stat;
  1124. X  tmp = monval (a_ptr[A_STR]) + monval (a_ptr[A_INT])
  1125. X      + monval (a_ptr[A_WIS]) + monval (a_ptr[A_CON])
  1126. X      + monval (a_ptr[A_DEX]);
  1127. X
  1128. X  gold = py.misc.sc*6 + randint (25) + 325;    /* Social Class adj */
  1129. X  gold -= tmp;                    /* Stat adj */
  1130. X  gold += monval (a_ptr[A_CHR]);        /* Charisma adj    */
  1131. X  if (!py.misc.male)
  1132. X    gold += 50;            /* She charmed the banker into it! -CJS- */
  1133. X  if (gold < 80)
  1134. X    gold = 80;            /* Minimum */
  1135. X  py.misc.au = gold;
  1136. X}
  1137. X
  1138. X
  1139. X/* ---------- M A I N  for Character Creation Routine ---------- */
  1140. X/*                            -JWT-    */
  1141. Xvoid create_character()
  1142. X{
  1143. X  register int exit_flag = 1;
  1144. X  register char c;
  1145. X
  1146. X  put_character();
  1147. X  choose_race();
  1148. X  get_sex();
  1149. X
  1150. X  /* here we start a loop giving a player a choice of characters -RGM- */
  1151. X  get_all_stats ();
  1152. X  get_history();
  1153. X  get_ahw();
  1154. X  print_history();
  1155. X  put_misc1();
  1156. X  put_stats();
  1157. X
  1158. X  clear_from (20);
  1159. X  put_buffer("Hit space to reroll or ESC to accept characteristics: ", 20, 2);
  1160. X  do
  1161. X    {
  1162. X      move_cursor (20, 56);
  1163. X      c = inkey();
  1164. X      if (c == ESCAPE)
  1165. X    exit_flag = 0;
  1166. X      else if (c == ' ')
  1167. X    {
  1168. X      get_all_stats ();
  1169. X      get_history();
  1170. X      get_ahw();
  1171. X      print_history();
  1172. X      put_misc1();
  1173. X      put_stats();
  1174. X    }
  1175. X      else
  1176. X    bell ();
  1177. X    }            /* done with stats generation */
  1178. X  while (exit_flag == 1);
  1179. X
  1180. X  get_class();
  1181. X  get_money();
  1182. X  put_stats();
  1183. X  put_misc2();
  1184. X  put_misc3();
  1185. X  get_name();
  1186. X
  1187. X  /* This delay may be reduced, but is recommended to keep players    */
  1188. X  /* from continuously rolling up characters, which can be VERY    */
  1189. X  /* expensive CPU wise.                        */
  1190. X  pause_exit(23, PLAYER_EXIT_PAUSE);
  1191. X}
  1192. END_OF_FILE
  1193. if test 12587 -ne `wc -c <'source/create.c'`; then
  1194.     echo shar: \"'source/create.c'\" unpacked with wrong size!
  1195. fi
  1196. # end of 'source/create.c'
  1197. fi
  1198. if test -f 'source/help.c' -a "${1}" != "-c" ; then 
  1199.   echo shar: Will not clobber existing file \"'source/help.c'\"
  1200. else
  1201. echo shar: Extracting \"'source/help.c'\" \(6390 characters\)
  1202. sed "s/^X//" >'source/help.c' <<'END_OF_FILE'
  1203. X/* help.c: identify a symbol
  1204. X
  1205. X   Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
  1206. X
  1207. X   This software may be copied and distributed for educational, research, and
  1208. X   not for profit purposes provided that this copyright and statement are
  1209. X   included in all such copies. */
  1210. X
  1211. X#include "constant.h"
  1212. X#include "config.h"
  1213. X#include "types.h"
  1214. X#include "externs.h"
  1215. X
  1216. X
  1217. Xvoid ident_char()
  1218. X{
  1219. X  char command, query;
  1220. X  register int i, n;
  1221. X
  1222. X  if (get_com("Enter character to be identified :", &command))
  1223. X    switch(command)
  1224. X      {
  1225. X    /* every printing ASCII character is listed here, in the order in which
  1226. X       they appear in the ASCII character set */
  1227. X      case ' ': prt("  - An open pit.", 0, 0); break;
  1228. X      case '!': prt("! - A potion.", 0, 0); break;
  1229. X      case '"': prt("\" - An amulet, periapt, or necklace.", 0, 0); break;
  1230. X      case '#': prt("# - A stone wall.", 0, 0); break;
  1231. X      case '$': prt("$ - Treasure.", 0, 0); break;
  1232. X      case '%': 
  1233. X    if (highlight_seams == TRUE)
  1234. X      prt("% - A magma or quartz vein.", 0, 0);
  1235. X    else
  1236. X      prt("% - Not used.", 0, 0);
  1237. X    break;
  1238. X      case '&': prt("& - Treasure chest.", 0, 0); break;
  1239. X      case '\'': prt("' - An open door.", 0, 0); break;
  1240. X      case '(': prt("( - Soft armor.", 0, 0); break;
  1241. X      case ')': prt(") - A shield.", 0, 0); break;
  1242. X      case '*': prt("* - Gems.", 0, 0); break;
  1243. X      case '+': prt("+ - A closed door.", 0, 0); break;
  1244. X      case ',': prt(", - Food or mushroom patch.", 0, 0); break;
  1245. X      case '-': prt("- - A wand", 0, 0); break;
  1246. X      case '.': prt(". - Floor.", 0, 0); break;
  1247. X      case '/': prt("/ - A pole weapon.", 0, 0); break;
  1248. X    /* case '0': prt("0 - Not used.", 0, 0); break; */
  1249. X      case '1': prt("1 - Entrance to General Store.", 0, 0); break;
  1250. X      case '2': prt("2 - Entrance to Armory.", 0, 0); break;
  1251. X      case '3': prt("3 - Entrance to Weaponsmith.", 0, 0); break;
  1252. X      case '4': prt("4 - Entrance to Temple.", 0, 0); break;
  1253. X      case '5': prt("5 - Entrance to Alchemy shop.", 0, 0); break;
  1254. X      case '6': prt("6 - Entrance to Magic-Users store.", 0, 0); break;
  1255. X    /* case '7': prt("7 - Not used.", 0, 0); break; */
  1256. X    /* case '8': prt("8 - Not used.", 0, 0); break; */
  1257. X    /* case '9': prt("9 - Not used.", 0, 0);  break;*/
  1258. X      case ':': prt(": - Rubble.", 0, 0); break;
  1259. X      case ';': prt("; - A loose rock.", 0, 0); break;
  1260. X      case '<': prt("< - An up staircase.", 0, 0); break;
  1261. X      case '=': prt("= - A ring.", 0, 0); break;
  1262. X      case '>': prt("> - A down staircase.", 0, 0); break;
  1263. X      case '?': prt("? - A scroll.", 0, 0); break;
  1264. X      case '@': prt(py.misc.name, 0, 0); break;
  1265. X      case 'A': prt("A - Giant Ant Lion.", 0, 0); break;
  1266. X      case 'B': prt("B - The Balrog.", 0, 0); break;
  1267. X      case 'C': prt("C - Gelatinous Cube.", 0, 0); break;
  1268. X      case 'D': prt("D - An Ancient Dragon (Beware).", 0, 0); break;
  1269. X      case 'E': prt("E - Elemental.", 0, 0); break;
  1270. X      case 'F': prt("F - Giant Fly.", 0, 0); break;
  1271. X      case 'G': prt("G - Ghost.", 0, 0); break;
  1272. X      case 'H': prt("H - Hobgoblin.", 0, 0); break;
  1273. X    /* case 'I': prt("I - Invisible Stalker.", 0, 0); break; */
  1274. X      case 'J': prt("J - Jelly.", 0, 0); break;
  1275. X      case 'K': prt("K - Killer Beetle.", 0, 0); break;
  1276. X      case 'L': prt("L - Lich.", 0, 0); break;
  1277. X      case 'M': prt("M - Mummy.", 0, 0); break;
  1278. X    /* case 'N': prt("N - Not used.", 0, 0); break; */
  1279. X      case 'O': prt("O - Ooze.", 0, 0); break;
  1280. X      case 'P': prt("P - Giant humanoid.", 0, 0); break;
  1281. X      case 'Q': prt("Q - Quylthulg (Pulsing Flesh Mound).", 0, 0); break;
  1282. X      case 'R': prt("R - Reptile.", 0, 0); break;
  1283. X      case 'S': prt("S - Giant Scorpion.", 0, 0); break;
  1284. X      case 'T': prt("T - Troll.", 0, 0); break;
  1285. X      case 'U': prt("U - Umber Hulk.", 0, 0); break;
  1286. X      case 'V': prt("V - Vampire.", 0, 0); break;
  1287. X      case 'W': prt("W - Wight or Wraith.", 0, 0); break;
  1288. X      case 'X': prt("X - Xorn.", 0, 0); break;
  1289. X      case 'Y': prt("Y - Yeti.", 0, 0); break;
  1290. X    /* case 'Z': prt("Z - Not used.", 0, 0); break; */
  1291. X      case '[': prt("[ - Hard armor.", 0, 0); break;
  1292. X      case '\\': prt("\\ - A hafted weapon.", 0, 0); break;
  1293. X      case ']': prt("] - Misc. armor.", 0, 0); break;
  1294. X      case '^': prt("^ - A trap.", 0, 0); break;
  1295. X      case '_': prt("_ - A staff.", 0, 0); break;
  1296. X    /* case '`': prt("` - Not used.", 0, 0); break; */
  1297. X      case 'a': prt("a - Giant Ant.", 0, 0); break;
  1298. X      case 'b': prt("b - Giant Bat.", 0, 0); break;
  1299. X      case 'c': prt("c - Giant Centipede.", 0, 0); break;
  1300. X      case 'd': prt("d - Dragon.", 0, 0); break;
  1301. X      case 'e': prt("e - Floating Eye.", 0, 0); break;
  1302. X      case 'f': prt("f - Giant Frog", 0, 0); break;
  1303. X      case 'g': prt("g - Golem.", 0, 0); break;
  1304. X      case 'h': prt("h - Harpy.", 0, 0); break;
  1305. X      case 'i': prt("i - Icky Thing.", 0, 0); break;
  1306. X      case 'j': prt("j - Jackal.", 0, 0); break;
  1307. X      case 'k': prt("k - Kobold.", 0, 0); break;
  1308. X      case 'l': prt("l - Giant Louse.", 0, 0); break;
  1309. X      case 'm': prt("m - Mold.", 0, 0); break;
  1310. X      case 'n': prt("n - Naga.", 0, 0); break;
  1311. X      case 'o': prt("o - Orc or Ogre.", 0, 0); break;
  1312. X      case 'p': prt("p - Person (Humanoid).", 0, 0); break;
  1313. X      case 'q': prt("q - Quasit.", 0, 0); break;
  1314. X      case 'r': prt("r - Rodent.", 0, 0); break;
  1315. X      case 's': prt("s - Skeleton.", 0, 0); break;
  1316. X      case 't': prt("t - Giant Tick.", 0, 0); break;
  1317. X    /* case 'u': prt("u - Not used.", 0, 0); break; */
  1318. X    /* case 'v': prt("v - Not used.", 0, 0); break; */
  1319. X      case 'w': prt("w - Worm or Worm Mass.", 0, 0); break;
  1320. X    /* case 'x': prt("x - Not used.", 0, 0); break; */
  1321. X      case 'y': prt("y - Yeek.", 0, 0); break;
  1322. X      case 'z': prt("z - Zombie.", 0, 0); break;
  1323. X      case '{': prt("{ - Arrow, bolt, or bullet.", 0, 0); break;
  1324. X      case '|': prt("| - A sword or dagger.", 0, 0); break;
  1325. X      case '}': prt("} - Bow, crossbow, or sling.", 0, 0); break;
  1326. X      case '~': prt("~ - Miscellaneous item.", 0, 0); break;
  1327. X      default:    prt("Not Used.", 0, 0); break;
  1328. X      }
  1329. X
  1330. X  /* Allow access to monster memory. -CJS- */
  1331. X  n = 0;
  1332. X  for (i = MAX_CREATURES-1; i >= 0; i--)
  1333. X    if ((c_list[i].cchar == command) && bool_roff_recall (i))
  1334. X      {
  1335. X    if (n == 0)
  1336. X      {
  1337. X        put_buffer ("You recall those details? [y/n]", 0, 40);
  1338. X        query = inkey();
  1339. X        if (query != 'y' && query != 'Y')
  1340. X          break;
  1341. X        erase_line (0, 40);
  1342. X        save_screen ();
  1343. X      }
  1344. X    n++;
  1345. X    query = roff_recall (i);
  1346. X    restore_screen ();
  1347. X    if (query == ESCAPE)
  1348. X      break;
  1349. X      }
  1350. X}
  1351. END_OF_FILE
  1352. if test 6390 -ne `wc -c <'source/help.c'`; then
  1353.     echo shar: \"'source/help.c'\" unpacked with wrong size!
  1354. fi
  1355. # end of 'source/help.c'
  1356. fi
  1357. if test -f 'source/store1.c' -a "${1}" != "-c" ; then 
  1358.   echo shar: Will not clobber existing file \"'source/store1.c'\"
  1359. else
  1360. echo shar: Extracting \"'source/store1.c'\" \(11806 characters\)
  1361. sed "s/^X//" >'source/store1.c' <<'END_OF_FILE'
  1362. X/* store1.c: store code, updating store inventory, pricing objects
  1363. X
  1364. X   Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
  1365. X
  1366. X   This software may be copied and distributed for educational, research, and
  1367. X   not for profit purposes provided that this copyright and statement are
  1368. X   included in all such copies. */
  1369. X
  1370. X#include "constant.h"
  1371. X#include "config.h"
  1372. X#include "types.h"
  1373. X#include "externs.h"
  1374. X
  1375. X#ifdef USG
  1376. X#ifndef ATARIST_MWC
  1377. X#include <string.h>
  1378. X#endif
  1379. X#else
  1380. X#include <strings.h>
  1381. X#endif
  1382. X
  1383. X#if defined(LINT_ARGS)
  1384. Xstatic void insert_store(int, int, int32, struct inven_type *);
  1385. Xstatic void store_create(int);
  1386. X#else
  1387. Xstatic void insert_store();
  1388. Xstatic void store_create();
  1389. X#endif
  1390. X
  1391. X
  1392. X/* Returns the value for any given object        -RAK-    */
  1393. Xint32 item_value(i_ptr)
  1394. Xregister inven_type *i_ptr;
  1395. X{
  1396. X  register int32 value;
  1397. X
  1398. X  value = i_ptr->cost;
  1399. X  /* don't purchase known cursed items */
  1400. X  if (i_ptr->ident & ID_DAMD)
  1401. X    value = 0;
  1402. X  else if (((i_ptr->tval >= TV_BOW) && (i_ptr->tval <= TV_SWORD)) ||
  1403. X       ((i_ptr->tval >= TV_BOOTS) && (i_ptr->tval <= TV_SOFT_ARMOR)))
  1404. X    {    /* Weapons and armor    */
  1405. X      if (!known2_p(i_ptr))
  1406. X    value = object_list[i_ptr->index].cost;
  1407. X      else if ((i_ptr->tval >= TV_BOW) && (i_ptr->tval <= TV_SWORD))
  1408. X    {
  1409. X      if (i_ptr->tohit < 0)
  1410. X        value = 0;
  1411. X      else if (i_ptr->todam < 0)
  1412. X        value = 0;
  1413. X      else if (i_ptr->toac < 0)
  1414. X        value = 0;
  1415. X      else
  1416. X        value = i_ptr->cost+(i_ptr->tohit+i_ptr->todam+i_ptr->toac)*100;
  1417. X    }
  1418. X      else
  1419. X    {
  1420. X      if (i_ptr->toac < 0)
  1421. X        value = 0;
  1422. X      else
  1423. X        value = i_ptr->cost+i_ptr->toac*100;
  1424. X    }
  1425. X    }
  1426. X  else if ((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_SPIKE))
  1427. X    {    /* Ammo            */
  1428. X      if (!known2_p(i_ptr))
  1429. X    value = object_list[i_ptr->index].cost;
  1430. X      else
  1431. X    {
  1432. X      if (i_ptr->tohit < 0)
  1433. X        value = 0;
  1434. X      else if (i_ptr->todam < 0)
  1435. X        value = 0;
  1436. X      else if (i_ptr->toac < 0)
  1437. X        value = 0;
  1438. X      else
  1439. X        /* use 5, because missiles generally appear in groups of 20,
  1440. X           so 20 * 5 == 100, which is comparable to weapon bonus above */
  1441. X        value = i_ptr->cost+(i_ptr->tohit+i_ptr->todam+i_ptr->toac)*5;
  1442. X    }
  1443. X    }
  1444. X  else if ((i_ptr->tval == TV_SCROLL1) || (i_ptr->tval == TV_SCROLL2) ||
  1445. X       (i_ptr->tval == TV_POTION1) || (i_ptr->tval == TV_POTION2))
  1446. X    {    /* Potions, Scrolls, and Food    */
  1447. X      if (!known1_p(i_ptr))
  1448. X    value = 20;
  1449. X    }
  1450. X  else if (i_ptr->tval == TV_FOOD)
  1451. X    {
  1452. X      if ((i_ptr->subval < (ITEM_SINGLE_STACK_MIN + MAX_MUSH))
  1453. X      && !known1_p(i_ptr))
  1454. X    value = 1;
  1455. X    }
  1456. X  else if ((i_ptr->tval == TV_AMULET) || (i_ptr->tval == TV_RING))
  1457. X    {    /* Rings and amulets    */
  1458. X      if (!known1_p(i_ptr))
  1459. X    /* player does not know what type of ring/amulet this is */
  1460. X    value = 45;
  1461. X      else if (!known2_p(i_ptr))
  1462. X    /* player knows what type of ring, but does not know whether it is
  1463. X       cursed or not, if refuse to buy cursed objects here, then
  1464. X       player can use this to 'identify' cursed objects */
  1465. X    value = object_list[i_ptr->index].cost;
  1466. X    }
  1467. X  else if ((i_ptr->tval == TV_STAFF) || (i_ptr->tval == TV_WAND))
  1468. X    {    /* Wands and staffs*/
  1469. X      if (!known1_p(i_ptr))
  1470. X    {
  1471. X      if (i_ptr->tval == TV_WAND)
  1472. X        value = 50;
  1473. X      else
  1474. X        value = 70;
  1475. X    }
  1476. X      else if (known2_p(i_ptr))
  1477. X    value = i_ptr->cost + (i_ptr->cost / 20) * i_ptr->p1;
  1478. X    }
  1479. X  /* picks and shovels */
  1480. X  else if (i_ptr->tval == TV_DIGGING)
  1481. X    {
  1482. X      if (!known2_p(i_ptr))
  1483. X    value = object_list[i_ptr->index].cost;
  1484. X      else
  1485. X    {
  1486. X      if (i_ptr->p1 < 0)
  1487. X        value = 0;
  1488. X      else
  1489. X        {
  1490. X          /* some digging tools start with non-zero p1 values, so only
  1491. X         multiply the plusses by 100, make sure result is positive */
  1492. X          value = i_ptr->cost
  1493. X        + (i_ptr->p1 - object_list[i_ptr->index].p1) * 100;
  1494. X          if (value < 0)
  1495. X        value = 0;
  1496. X        }
  1497. X    }
  1498. X    }
  1499. X  /* multiply value by number of items if it is a group stack item */
  1500. X  if (i_ptr->subval > ITEM_GROUP_MIN) /* do not include torches here */
  1501. X    value = value * i_ptr->number;
  1502. X  return(value);
  1503. X}
  1504. X
  1505. X
  1506. X/* Asking price for an item                -RAK-    */
  1507. Xint32 sell_price(snum, max_sell, min_sell, item)
  1508. Xint snum;
  1509. Xint32 *max_sell, *min_sell;
  1510. Xinven_type *item;
  1511. X{
  1512. X  register int32 i;
  1513. X  register store_type *s_ptr;
  1514. X
  1515. X  s_ptr = &store[snum];
  1516. X  i = item_value(item);
  1517. X  /* check item->cost in case it is cursed, check i in case it is damaged */
  1518. X  if ((item->cost > 0) && (i > 0))
  1519. X    {
  1520. X      i = i * rgold_adj[owners[s_ptr->owner].owner_race][py.misc.prace] / 100;
  1521. X      if (i < 1)  i = 1;
  1522. X      *max_sell = i * owners[s_ptr->owner].max_inflate / 100;
  1523. X      *min_sell = i * owners[s_ptr->owner].min_inflate / 100;
  1524. X      if (min_sell > max_sell)    min_sell = max_sell;
  1525. X      return(i);
  1526. X    }
  1527. X  else
  1528. X    /* don't let the item get into the store inventory */
  1529. X    return(0);
  1530. X}
  1531. X
  1532. X
  1533. X/* Check to see if he will be carrying too many objects    -RAK-    */
  1534. Xint store_check_num(t_ptr, store_num)
  1535. Xinven_type *t_ptr;
  1536. Xint store_num;
  1537. X{
  1538. X  register int store_check, i;
  1539. X  register store_type *s_ptr;
  1540. X  register inven_type *i_ptr;
  1541. X
  1542. X  store_check = FALSE;
  1543. X  s_ptr = &store[store_num];
  1544. X  if (s_ptr->store_ctr < STORE_INVEN_MAX)
  1545. X    store_check = TRUE;
  1546. X  else if (t_ptr->subval >= ITEM_SINGLE_STACK_MIN)
  1547. X    for (i = 0; i < s_ptr->store_ctr; i++)
  1548. X      {
  1549. X    i_ptr = &s_ptr->store_inven[i].sitem;
  1550. X    /* note: items with subval of gte ITEM_SINGLE_STACK_MAX only stack
  1551. X       if their subvals match */
  1552. X    if (i_ptr->tval == t_ptr->tval && i_ptr->subval == t_ptr->subval
  1553. X        && ((int)i_ptr->number + (int)t_ptr->number < 256)
  1554. X        && (t_ptr->subval < ITEM_GROUP_MIN
  1555. X        || (i_ptr->p1 == t_ptr->p1)))
  1556. X      store_check = TRUE;
  1557. X      }
  1558. X  return(store_check);
  1559. X}
  1560. X
  1561. X
  1562. X/* Insert INVEN_MAX at given location    */
  1563. Xstatic void insert_store(store_num, pos, icost, i_ptr)
  1564. Xregister int pos;
  1565. Xint store_num;
  1566. Xint32 icost;
  1567. Xinven_type *i_ptr;
  1568. X{
  1569. X  register int i;
  1570. X  register store_type *s_ptr;
  1571. X
  1572. X  s_ptr = &store[store_num];
  1573. X  for (i = s_ptr->store_ctr-1; i >= pos; i--)
  1574. X    s_ptr->store_inven[i+1] = s_ptr->store_inven[i];
  1575. X  s_ptr->store_inven[pos].sitem = *i_ptr;
  1576. X  s_ptr->store_inven[pos].scost = -icost;
  1577. X  s_ptr->store_ctr++;
  1578. X}
  1579. X
  1580. X
  1581. X/* Add the item in INVEN_MAX to stores inventory.    -RAK-    */
  1582. Xvoid store_carry(store_num, ipos, t_ptr)
  1583. Xint store_num;
  1584. Xint *ipos;
  1585. Xinven_type *t_ptr;
  1586. X{
  1587. X  int item_num, item_val, flag;
  1588. X  register int typ, subt;
  1589. X  int32 icost, dummy;
  1590. X  register inven_type *i_ptr;
  1591. X  register store_type *s_ptr;
  1592. X
  1593. X  *ipos = -1;
  1594. X  if (sell_price(store_num, &icost, &dummy, t_ptr) > 0)
  1595. X    {
  1596. X      s_ptr = &store[store_num];
  1597. X      item_val = 0;
  1598. X      item_num = t_ptr->number;
  1599. X      flag = FALSE;
  1600. X      typ  = t_ptr->tval;
  1601. X      subt = t_ptr->subval;
  1602. X      do
  1603. X    {
  1604. X      i_ptr = &s_ptr->store_inven[item_val].sitem;
  1605. X      if (typ == i_ptr->tval)
  1606. X        {
  1607. X          if (subt == i_ptr->subval && /* Adds to other item    */
  1608. X          subt >= ITEM_SINGLE_STACK_MIN
  1609. X          && (subt < ITEM_GROUP_MIN || i_ptr->p1 == t_ptr->p1))
  1610. X        {
  1611. X          *ipos = item_val;
  1612. X          i_ptr->number += item_num;
  1613. X          /* must set new scost for group items, do this only for items
  1614. X             strictly greater than group_min, not for torches, this
  1615. X             must be recalculated for entire group */
  1616. X          if (subt > ITEM_GROUP_MIN)
  1617. X            {
  1618. X              (void) sell_price (store_num, &icost, &dummy, i_ptr);
  1619. X              s_ptr->store_inven[item_val].scost = -icost;
  1620. X            }
  1621. X          /* must let group objects (except torches) stack over 24
  1622. X             since there may be more than 24 in the group */
  1623. X          else if (i_ptr->number > 24)
  1624. X            i_ptr->number = 24;
  1625. X          flag = TRUE;
  1626. X        }
  1627. X        }
  1628. X      else if (typ > i_ptr->tval)
  1629. X        {        /* Insert into list        */
  1630. X          insert_store(store_num, item_val, icost, t_ptr);
  1631. X          flag = TRUE;
  1632. X          *ipos = item_val;
  1633. X        }
  1634. X      item_val++;
  1635. X    }
  1636. X      while ((item_val < s_ptr->store_ctr) && (!flag));
  1637. X      if (!flag)    /* Becomes last item in list    */
  1638. X    {
  1639. X      insert_store(store_num, (int)s_ptr->store_ctr, icost, t_ptr);
  1640. X      *ipos = s_ptr->store_ctr - 1;
  1641. X    }
  1642. X    }
  1643. X}
  1644. X
  1645. X/* Destroy an item in the stores inventory.  Note that if    */
  1646. X/* "one_of" is false, an entire slot is destroyed    -RAK-    */
  1647. Xvoid store_destroy(store_num, item_val, one_of)
  1648. Xint store_num, item_val;
  1649. Xint one_of;
  1650. X{
  1651. X  register int j, number;
  1652. X  register store_type *s_ptr;
  1653. X  register inven_type *i_ptr;
  1654. X
  1655. X  s_ptr = &store[store_num];
  1656. X  i_ptr = &s_ptr->store_inven[item_val].sitem;
  1657. X
  1658. X  /* for single stackable objects, only destroy one half on average,
  1659. X     this will help ensure that general store and alchemist have 
  1660. X     reasonable selection of objects */
  1661. X  if ((i_ptr->subval >= ITEM_SINGLE_STACK_MIN) &&
  1662. X      (i_ptr->subval <= ITEM_SINGLE_STACK_MAX))
  1663. X    {
  1664. X      if (one_of)
  1665. X    number = 1;
  1666. X      else
  1667. X    number = randint((int)i_ptr->number);
  1668. X    }
  1669. X  else
  1670. X    number = i_ptr->number;
  1671. X
  1672. X  if (number != i_ptr->number)
  1673. X    i_ptr->number -= number;
  1674. X  else
  1675. X    {
  1676. X      for (j = item_val; j < s_ptr->store_ctr-1; j++)
  1677. X    s_ptr->store_inven[j] = s_ptr->store_inven[j+1];
  1678. X      invcopy(&s_ptr->store_inven[s_ptr->store_ctr-1].sitem, OBJ_NOTHING);
  1679. X      s_ptr->store_inven[s_ptr->store_ctr-1].scost = 0;
  1680. X      s_ptr->store_ctr--;
  1681. X    }
  1682. X}
  1683. X
  1684. X
  1685. X/* Initializes the stores with owners            -RAK-    */
  1686. Xvoid store_init()
  1687. X{
  1688. X  register int i, j, k;
  1689. X  register store_type *s_ptr;
  1690. X
  1691. X  i = MAX_OWNERS / MAX_STORES;
  1692. X  for (j = 0; j < MAX_STORES; j++)
  1693. X    {
  1694. X      s_ptr = &store[j];
  1695. X      s_ptr->owner = MAX_STORES*(randint(i)-1) + j;
  1696. X      s_ptr->insult_cur = 0;
  1697. X      s_ptr->store_open = 0;
  1698. X      s_ptr->store_ctr    = 0;
  1699. X      s_ptr->good_buy = 0;
  1700. X      s_ptr->bad_buy = 0;
  1701. X      for (k = 0; k < STORE_INVEN_MAX; k++)
  1702. X    {
  1703. X      invcopy(&s_ptr->store_inven[k].sitem, OBJ_NOTHING);
  1704. X      s_ptr->store_inven[k].scost = 0;
  1705. X    }
  1706. X    }
  1707. X}
  1708. X
  1709. X
  1710. X/* Creates an item and inserts it into store's inven    -RAK-    */
  1711. Xstatic void store_create(store_num)
  1712. Xint store_num;
  1713. X{
  1714. X  register int i, tries;
  1715. X  int cur_pos, dummy;
  1716. X  register store_type *s_ptr;
  1717. X  register inven_type *t_ptr;
  1718. X
  1719. X  tries = 0;
  1720. X  cur_pos = popt();
  1721. X  s_ptr = &store[store_num];
  1722. X  do
  1723. X    {
  1724. X      i = store_choice[store_num][randint(STORE_CHOICES)-1];
  1725. X      invcopy(&t_list[cur_pos], i);
  1726. X      magic_treasure(cur_pos, OBJ_TOWN_LEVEL);
  1727. X      t_ptr = &t_list[cur_pos];
  1728. X      if (store_check_num(t_ptr, store_num))
  1729. X    {
  1730. X      if ((t_ptr->cost > 0) &&    /* Item must be good    */
  1731. X          (t_ptr->cost < owners[s_ptr->owner].max_cost))
  1732. X        {
  1733. X          /* equivalent to calling ident_spell(), except will not
  1734. X         change the object_ident array */
  1735. X          store_bought(t_ptr);
  1736. X          store_carry(store_num, &dummy, t_ptr);
  1737. X          tries = 10;
  1738. X        }
  1739. X    }
  1740. X      tries++;
  1741. X    }
  1742. X  while (tries <= 3);
  1743. X  pusht((int8u)cur_pos);
  1744. X}
  1745. X
  1746. X
  1747. X/* Initialize and up-keep the store's inventory.        -RAK-    */
  1748. Xvoid store_maint()
  1749. X{
  1750. X  register int i, j;
  1751. X  register store_type *s_ptr;
  1752. X
  1753. X  for (i = 0; i < MAX_STORES; i++)
  1754. X    {
  1755. X      s_ptr = &store[i];
  1756. X      s_ptr->insult_cur = 0;
  1757. X      if (s_ptr->store_ctr >= STORE_MIN_INVEN)
  1758. X    {
  1759. X      j = randint(STORE_TURN_AROUND);
  1760. X      if (s_ptr->store_ctr >= STORE_MAX_INVEN)
  1761. X        j += 1 + s_ptr->store_ctr - STORE_MAX_INVEN;
  1762. X      while (--j >= 0)
  1763. X        store_destroy(i, randint((int)s_ptr->store_ctr)-1, FALSE);
  1764. X    }
  1765. X
  1766. X      if (s_ptr->store_ctr <= STORE_MAX_INVEN)
  1767. X    {
  1768. X      j = randint(STORE_TURN_AROUND);
  1769. X      if (s_ptr->store_ctr < STORE_MIN_INVEN)
  1770. X        j += STORE_MIN_INVEN - s_ptr->store_ctr;
  1771. X      while (--j >= 0)
  1772. X        store_create(i);
  1773. X    }
  1774. X    }
  1775. X}
  1776. X
  1777. X/* eliminate need to bargain if player has haggled well in the past   -DJB- */
  1778. Xint noneedtobargain(store_num, minprice)
  1779. Xint store_num;
  1780. Xint32 minprice;
  1781. X{
  1782. X  register int flagnoneed;
  1783. X  register store_type *s_ptr;
  1784. X
  1785. X  s_ptr = &store[store_num];
  1786. X  flagnoneed = ((s_ptr->good_buy == MAX_SHORT)
  1787. X        || ((s_ptr->good_buy > 3 * s_ptr->bad_buy + 20) &&
  1788. X            (minprice < 1000)));
  1789. X
  1790. X  return (flagnoneed);
  1791. X}
  1792. X
  1793. X
  1794. X/* update the bargin info                    -DJB- */
  1795. Xvoid updatebargain(store_num, price, minprice)
  1796. Xint store_num;
  1797. Xint32 price, minprice;
  1798. X{
  1799. X  register store_type *s_ptr;
  1800. X
  1801. X  s_ptr = &store[store_num];
  1802. X  if ((minprice > 9) && (minprice < 1000))
  1803. X    if (price == minprice)
  1804. X      {
  1805. X    if (s_ptr->good_buy < MAX_SHORT)
  1806. X      s_ptr->good_buy++;
  1807. X      }
  1808. X    else
  1809. X      {
  1810. X    if (s_ptr->bad_buy < MAX_SHORT)
  1811. X      s_ptr->bad_buy++;
  1812. X      }
  1813. X}
  1814. END_OF_FILE
  1815. if test 11806 -ne `wc -c <'source/store1.c'`; then
  1816.     echo shar: \"'source/store1.c'\" unpacked with wrong size!
  1817. fi
  1818. # end of 'source/store1.c'
  1819. fi
  1820. if test -f 'util/mc/symtab.c' -a "${1}" != "-c" ; then 
  1821.   echo shar: Will not clobber existing file \"'util/mc/symtab.c'\"
  1822. else
  1823. echo shar: Extracting \"'util/mc/symtab.c'\" \(12502 characters\)
  1824. sed "s/^X//" >'util/mc/symtab.c' <<'END_OF_FILE'
  1825. X/*
  1826. X * st_symtab.c
  1827. X *
  1828. X * routines for managing symbol tables -- reasonably fast and reasonably
  1829. X * efficient, but not very much of either
  1830. X *
  1831. X * Copyright 1989 by Joseph Hall.
  1832. X * All rights reserved except as stated below.
  1833. X *
  1834. X * Jim Wilson and any other holders of copyright on substantial portions
  1835. X * of Moria are granted rights to use, modify, and distribute this program
  1836. X * as they see fit, so long as the terms of its use, modification and/or
  1837. X * distribution are no less restrictive than those applying to Moria,
  1838. X * version 5.0 or later, itself, and so long as this use is related to
  1839. X * the further development of Moria.
  1840. X *
  1841. X * Anyone having any other use in mind for this code should contact the
  1842. X * author at 4116 Brewster Dr., Raleigh NC 27606 (jnh@ecemwl.ncsu.edu).
  1843. X */
  1844. X
  1845. X
  1846. X#include <stdio.h>
  1847. X#include <string.h>
  1848. X#include <ctype.h>
  1849. X
  1850. X#ifdef ANSI_LIBS
  1851. X#include <stdlib.h>
  1852. X#else
  1853. Xextern char *malloc();
  1854. Xextern char *calloc();
  1855. Xextern void free();
  1856. Xextern void cfree();
  1857. X#endif
  1858. X
  1859. X#include "st.h"
  1860. X
  1861. X/* #define _TESTING_ */
  1862. X
  1863. X/*
  1864. X * There's a symbol table containing all the names of the symbol tables,
  1865. X * and of course it contains its own name ...
  1866. X *
  1867. X * "tnt" stands for "Table Name Table" ...
  1868. X */
  1869. Xstatic st_Table_Pt  tnt_P = NULL;
  1870. X
  1871. X/*
  1872. X * If there are a lot of symbol tables around you might want to increase
  1873. X * TNT_SIZE.  For best results use a prime number.
  1874. X */
  1875. X
  1876. X#define    TNT_SIZE    11
  1877. X
  1878. X/*
  1879. X * Names of basic generic types.
  1880. X */
  1881. X
  1882. X#define NAMES 7
  1883. X
  1884. X/*
  1885. X * Hash--
  1886. X *    Simple, stupid hash function.  Why be great, you know, when you can
  1887. X * be adequate so easily?
  1888. X */
  1889. Xstatic int Hash(s, mod)
  1890. Xregister char *s;
  1891. Xint mod;
  1892. X{
  1893. X    register int h = 0;
  1894. X
  1895. X    while (*s)
  1896. X    h += (unsigned) *s++;
  1897. X
  1898. X    return h % mod;
  1899. X}
  1900. X
  1901. X
  1902. X/*
  1903. X * LookupSym--
  1904. X *    Search for a name in a table.  Returns NULL if not found.
  1905. X */
  1906. Xstatic st_Entry_Pt LookupSym(st_P, name)
  1907. Xst_Table_Pt st_P; 
  1908. Xchar *name;
  1909. X{
  1910. X    st_Entry_Pt    entry_P;
  1911. X    int        h;
  1912. X
  1913. X    h = Hash(name, st_P->size);
  1914. X
  1915. X    for (entry_P = st_P->tab_A[h]; entry_P; entry_P = entry_P->next_P)
  1916. X    if (!strncmp(entry_P->name, name, ST_MAX_SYM_LEN))
  1917. X        break;
  1918. X
  1919. X    return entry_P;
  1920. X}
  1921. X
  1922. X
  1923. X
  1924. X/*
  1925. X * AddSym--
  1926. X *    Add a name to a table and return a pointer to the new entry.
  1927. X * ASSUMES THAT NAME DOESN'T EXIST ALREADY IN TABLE (check with LookupSym
  1928. X * above before calling here).
  1929. X */
  1930. Xstatic st_Entry_Pt AddSym(st_P, name)
  1931. Xst_Table_Pt st_P; 
  1932. Xchar *name;
  1933. X
  1934. X{
  1935. X    int        h;
  1936. X    st_Entry_Pt    new_P;
  1937. X
  1938. X    h = Hash(name, st_P->size);
  1939. X
  1940. X    new_P = (st_Entry_Pt) malloc(sizeof(st_Entry_t));
  1941. X     strncpy(new_P->name, name, ST_MAX_SYM_LEN - 1);
  1942. X    new_P->name[ST_MAX_SYM_LEN - 1] = 0;
  1943. X    new_P->next_P = st_P->tab_A[h];
  1944. X    st_P->tab_A[h] = new_P;
  1945. X
  1946. X    st_P->entryCt++;
  1947. X
  1948. X    return new_P;
  1949. X
  1950. X}
  1951. X
  1952. X
  1953. X/*
  1954. X * St_NewTable--
  1955. X *    Create a new symbol table header.  Returns NULL if name isn't
  1956. X * unique with respect to the symbol tables currently in existence.
  1957. X */
  1958. Xst_Table_Pt St_NewTable(name, size)
  1959. Xchar *name; 
  1960. Xint size;
  1961. X{
  1962. X    st_Table_Pt    st_P;
  1963. X    generic_t    gval;
  1964. X
  1965. X    /*
  1966. X     * Create the name table if doesn't already exist.  Obviously we
  1967. X     * can't use St_NewTable for this ...
  1968. X     */
  1969. X
  1970. X    if (!tnt_P) {
  1971. X    tnt_P = (st_Table_Pt) malloc(sizeof(st_Table_t));
  1972. X
  1973. X     strncpy(tnt_P->name, "_TNT_", ST_MAX_SYM_LEN - 1);
  1974. X    tnt_P->name[ST_MAX_SYM_LEN - 1] = 0;
  1975. X    tnt_P->size = TNT_SIZE;
  1976. X    tnt_P->tab_A = (st_Entry_Pt *) calloc(TNT_SIZE, sizeof(st_Entry_Pt));
  1977. X    tnt_P->entryCt = 0;
  1978. X
  1979. X    gval.v = (char *) tnt_P;
  1980. X     St_DefSym(tnt_P, "_TNT_", GEN_TYPE_VOID_PTR, gval);
  1981. X
  1982. X    }
  1983. X
  1984. X    /*
  1985. X     * See if the new table name is unique.
  1986. X     */
  1987. X
  1988. X    if (LookupSym(tnt_P, name))
  1989. X    return NULL;
  1990. X
  1991. X    /*
  1992. X     * Create the new table.
  1993. X     */
  1994. X
  1995. X    st_P = (st_Table_Pt) malloc(sizeof(st_Table_t));
  1996. X
  1997. X     strncpy(st_P->name, name, ST_MAX_SYM_LEN - 1);
  1998. X    st_P->name[ST_MAX_SYM_LEN - 1] = 0;
  1999. X    st_P->size = size;
  2000. X    st_P->tab_A = (st_Entry_Pt *) calloc((unsigned) size, sizeof(st_Entry_Pt));
  2001. X    st_P->entryCt = 0;
  2002. X
  2003. X    /*
  2004. X     * Add the name of the new table to the "table name table" now.
  2005. X     * gval.v is a pointer to the new table.
  2006. X     */
  2007. X
  2008. X    gval.v = (char *) st_P;
  2009. X     St_DefSym(tnt_P, name, GEN_TYPE_VOID_PTR, gval);
  2010. X
  2011. X    return st_P;
  2012. X}
  2013. X
  2014. X
  2015. X
  2016. X
  2017. X/*
  2018. X * St_DelTable--
  2019. X *    Delete a symbol table and associated storage.  If entries in the
  2020. X * table point to dynamically allocated objects, the user must free these
  2021. X * objects before calling this routine, else the pointers to those objects
  2022. X * will be lost.  (** NOTE: this feature has been removed from the version
  2023. X * accompanying the monster compiler, since it isn't needed --jnh **)
  2024. X */
  2025. Xvoid St_DelTable(st_P)
  2026. Xst_Table_Pt st_P;
  2027. X{
  2028. X    st_Entry_Pt entry_P;
  2029. X    int        i;
  2030. X
  2031. X    if (!st_P)
  2032. X    return;
  2033. X
  2034. X    for (i = 0; i < st_P->size; i++)
  2035. X    for (entry_P = st_P->tab_A[i]; entry_P; entry_P = entry_P->next_P) {
  2036. X        free((char *) entry_P);
  2037. X    }
  2038. X
  2039. X    if (strncmp(st_P->name, "_TNT_", ST_MAX_SYM_LEN))
  2040. X     St_DelSym(tnt_P, st_P->name);
  2041. X
  2042. X    cfree((char *) st_P->tab_A);
  2043. X    cfree((char *) st_P);
  2044. X
  2045. X    return;
  2046. X
  2047. X}
  2048. X
  2049. X
  2050. X
  2051. X
  2052. X/*
  2053. X * St_ListTable--
  2054. X *    Returns an unsorted list of symbols in the table.  The list will be
  2055. X * terminated with a NULL pointer.  This routine frees the storage used by
  2056. X * the last call to St_ListTable or St_SListTable; a call with a NULL 
  2057. X * argument is a convenient way to free storage allocated by a previous call.
  2058. X */
  2059. Xchar **St_ListTable(st_P)
  2060. Xst_Table_Pt st_P;
  2061. X{
  2062. X
  2063. X    st_Entry_Pt entry_P;
  2064. X    int        i, j;
  2065. X    static char    **list_A = NULL, 
  2066. X        *chars_P = NULL;
  2067. X
  2068. X    if (list_A) {
  2069. X    free((char *) list_A);
  2070. X    free((char *) chars_P);
  2071. X    list_A = NULL;
  2072. X    chars_P = NULL;
  2073. X    }
  2074. X
  2075. X    if (!st_P)
  2076. X    return NULL;
  2077. X
  2078. X    list_A = (char **) malloc(sizeof(char *) * (st_P->entryCt + 1));
  2079. X    chars_P = (char *) malloc(sizeof(char) * ST_MAX_SYM_LEN * st_P->entryCt);
  2080. X
  2081. X    for (i = 0; i < st_P->entryCt; i++)
  2082. X    list_A[i] = chars_P + ST_MAX_SYM_LEN * i;
  2083. X    list_A[st_P->entryCt] = NULL;
  2084. X
  2085. X    j = 0;
  2086. X    for (i = 0; i < st_P->size; i++)
  2087. X    for (entry_P = st_P->tab_A[i]; entry_P; entry_P = entry_P->next_P)
  2088. X         strcpy(list_A[j++], entry_P->name);
  2089. X
  2090. X    list_A[st_P->entryCt] = NULL;
  2091. X
  2092. X    return list_A;
  2093. X
  2094. X}
  2095. X
  2096. X
  2097. X/*
  2098. X * St_SListTable--
  2099. X *    Returns a sorted list of symbols in a table.  Otherwise is exactly
  2100. X * like St_ListTable, above.
  2101. X */
  2102. Xchar **St_SListTable(st_P)
  2103. Xst_Table_Pt st_P;
  2104. X{
  2105. X    char    **list_A;
  2106. X
  2107. X    if (!(list_A = St_ListTable(st_P)))
  2108. X    return NULL;
  2109. X
  2110. X    qsort(*list_A, st_P->entryCt, sizeof(char) * ST_MAX_SYM_LEN, strcmp);
  2111. X
  2112. X    return list_A;
  2113. X}
  2114. X
  2115. X
  2116. X    
  2117. X/* 
  2118. X * St_GetSym--
  2119. X *    Look for a symbol in a table.  Return type and ptr to val if found.
  2120. X */
  2121. Xint St_GetSym(st_P, name, type_P, gval_P)
  2122. Xst_Table_Pt st_P; 
  2123. Xchar *name; 
  2124. Xint *type_P; 
  2125. Xgeneric_Pt gval_P;
  2126. X{
  2127. X    st_Entry_Pt    entry_P;
  2128. X
  2129. X    if (!st_P)
  2130. X    return ST_NULL_TABLE;
  2131. X
  2132. X    if (!(entry_P = LookupSym(st_P, name)))
  2133. X    return ST_SYM_NOT_FOUND;
  2134. X
  2135. X    *type_P = entry_P->type;
  2136. X    *gval_P = entry_P->gval;
  2137. X
  2138. X    return ST_SYM_FOUND;
  2139. X}
  2140. X
  2141. X
  2142. X
  2143. X/* 
  2144. X * St_DefSym--
  2145. X *    Add a symbol to a table.  Returns ST_SYM_FOUND and does nothing if
  2146. X * name is already in table.
  2147. X */
  2148. Xint St_DefSym(st_P, name, type, gval)
  2149. Xst_Table_Pt st_P; 
  2150. Xchar *name; 
  2151. Xint type; 
  2152. Xgeneric_t gval;
  2153. X{
  2154. X    st_Entry_Pt entry_P;
  2155. X
  2156. X    if (!st_P)
  2157. X    return ST_NULL_TABLE;
  2158. X
  2159. X    if (LookupSym(st_P, name))
  2160. X    return ST_SYM_FOUND;
  2161. X
  2162. X    entry_P = AddSym(st_P, name);
  2163. X
  2164. X    /*
  2165. X     * Assign data.
  2166. X     */
  2167. X
  2168. X    entry_P->type = type;
  2169. X    entry_P->gval = gval;
  2170. X
  2171. X    return ST_SYM_NOT_FOUND;
  2172. X
  2173. X}
  2174. X
  2175. X
  2176. X/* 
  2177. X * St_ReplSym--
  2178. X *    Add or supersede a symbol in a table.
  2179. X */
  2180. Xint St_ReplSym(st_P, name, type, gval)
  2181. Xst_Table_Pt st_P; 
  2182. Xchar *name; 
  2183. Xint type; 
  2184. Xgeneric_t gval;
  2185. X{
  2186. X    st_Entry_Pt entry_P;
  2187. X    int        status;
  2188. X
  2189. X    if (!st_P)
  2190. X    return ST_NULL_TABLE;
  2191. X
  2192. X    if (!(entry_P = LookupSym(st_P, name))) {
  2193. X    entry_P = AddSym(st_P, name);
  2194. X    status = ST_SYM_NOT_FOUND;
  2195. X    } else {
  2196. X    status = ST_SYM_FOUND;
  2197. X    }
  2198. X
  2199. X    /*
  2200. X     * Assign data.
  2201. X     */
  2202. X
  2203. X    entry_P->type = type;
  2204. X    entry_P->gval = gval;
  2205. X
  2206. X    return status;
  2207. X}
  2208. X
  2209. X
  2210. X
  2211. X
  2212. X/*
  2213. X * St_DelSym--
  2214. X *    Delete a symbol from the table.
  2215. X */
  2216. Xint St_DelSym(st_P, name)
  2217. Xst_Table_Pt st_P; 
  2218. Xchar *name;
  2219. X{
  2220. X    st_Entry_Pt    entry_P, last_P;
  2221. X    int        h;
  2222. X
  2223. X    if (!st_P)
  2224. X    return ST_NULL_TABLE;
  2225. X
  2226. X    h = Hash(name, st_P->size);
  2227. X
  2228. X    for (last_P = NULL, entry_P = st_P->tab_A[h]; entry_P; 
  2229. X                last_P = entry_P, entry_P = entry_P->next_P)
  2230. X    if (!strncmp(entry_P->name, name, ST_MAX_SYM_LEN))
  2231. X        break;
  2232. X
  2233. X    if (!entry_P)
  2234. X    return ST_SYM_NOT_FOUND;
  2235. X
  2236. X    if (last_P)
  2237. X    last_P->next_P = entry_P->next_P;
  2238. X    else
  2239. X    st_P->tab_A[h] = NULL;
  2240. X
  2241. X    cfree((char *) entry_P);
  2242. X    st_P->entryCt--;
  2243. X
  2244. X    return ST_SYM_FOUND;
  2245. X}
  2246. X
  2247. X
  2248. X    
  2249. X/*
  2250. X * St_GetTable--
  2251. X *    Get a table by name
  2252. X */
  2253. Xst_Table_Pt St_GetTable(name)
  2254. Xchar *name;
  2255. X{
  2256. X    int        type;
  2257. X    generic_t    gval;
  2258. X
  2259. X    if (!tnt_P)
  2260. X    return NULL;
  2261. X
  2262. X    if (St_GetSym(tnt_P, name, &type, &gval) != ST_SYM_FOUND)
  2263. X    return NULL;
  2264. X
  2265. X    return (st_Table_Pt) gval.v;
  2266. X}
  2267. X
  2268. X    
  2269. X/* -Jim Wilson-
  2270. X * St_TableSize--
  2271. X *    Returns the number of entries in the table.
  2272. X */
  2273. Xint St_TableSize(st_P)
  2274. Xst_Table_Pt st_P;
  2275. X{
  2276. X  return st_P->entryCt;
  2277. X}
  2278. X
  2279. X
  2280. X/*
  2281. X * St_DumpTable--
  2282. X *    Dump a table (for debugging or utility purposes)
  2283. X */
  2284. Xvoid St_DumpTable(output_F, st_P)
  2285. XFILE *output_F; 
  2286. Xst_Table_Pt st_P;
  2287. X{
  2288. X    st_Entry_Pt    entry_P;
  2289. X    int        bucket;
  2290. X
  2291. X    if (!st_P) {
  2292. X     fprintf(output_F, "Table ptr is NULL.\n");
  2293. X    return;
  2294. X    }
  2295. X
  2296. X     fprintf(output_F, "Dumping table '%s', size = %d, count = %d\n",
  2297. X                st_P->name, st_P->size, st_P->entryCt);
  2298. X
  2299. X    for (bucket = 0; bucket < st_P->size; bucket++) {
  2300. X
  2301. X     fprintf(output_F, " Bucket %d:\n", bucket);
  2302. X
  2303. X    entry_P = st_P->tab_A[bucket];
  2304. X
  2305. X    if (!entry_P) {
  2306. X         fprintf(output_F, "  empty\n");
  2307. X        continue;
  2308. X    }
  2309. X
  2310. X    while (entry_P) {
  2311. X
  2312. X        switch(entry_P->type) {
  2313. X
  2314. X        case GEN_TYPE_INT:
  2315. X         fprintf(output_F, "  '%s' = %d (int)\n", entry_P->name,
  2316. X                            entry_P->gval.i);
  2317. X        break;
  2318. X
  2319. X        case GEN_TYPE_LONG:
  2320. X         fprintf(output_F, "  '%s' = %ld (long)\n", entry_P->name,
  2321. X                            entry_P->gval.l);
  2322. X        break;
  2323. X
  2324. X        case GEN_TYPE_FLOAT:
  2325. X         fprintf(output_F, "  '%s' = %e (float)\n", entry_P->name,
  2326. X                            entry_P->gval.f);
  2327. X        break;
  2328. X
  2329. X        case GEN_TYPE_DOUBLE:
  2330. X         fprintf(output_F, "  '%s' = %e (double)\n",
  2331. X                entry_P->name, entry_P->gval.d);
  2332. X        break;
  2333. X
  2334. X        case GEN_TYPE_CHAR:
  2335. X         fprintf(output_F, "  '%s' = '%c'/%d (char)\n", 
  2336. X                        entry_P->name,
  2337. X                        entry_P->gval.c, entry_P->gval.c);
  2338. X        break;
  2339. X
  2340. X        case GEN_TYPE_STRING:
  2341. X        if (entry_P->gval.s)
  2342. X             fprintf(output_F, "  '%s' = '%s' (string)\n", 
  2343. X                    entry_P->name, entry_P->gval.s);
  2344. X        else
  2345. X             fprintf(output_F, "  '%s' = NULL (string)\n", 
  2346. X                                entry_P->name);
  2347. X        break;
  2348. X
  2349. X        case GEN_TYPE_STRING_A:
  2350. X
  2351. X        if (!entry_P->gval.s_A) {
  2352. X             fprintf(output_F, "  '%s' = NULL (string array)\n",
  2353. X                                entry_P->name);
  2354. X        } else {
  2355. X            char    **s_A;
  2356. X             fprintf(output_F, "  '%s' is string array:\n",
  2357. X                                entry_P->name);
  2358. X            for (s_A = entry_P->gval.s_A; *s_A; s_A++)
  2359. X             fprintf(output_F, "    '%s'\n", *s_A);
  2360. X        }
  2361. X        break;
  2362. X
  2363. X        case GEN_TYPE_VOID_PTR:
  2364. X        if (entry_P->gval.v)
  2365. X             fprintf(output_F, "  '%s' is user type (void ptr)\n",
  2366. X                                entry_P->name);
  2367. X        else
  2368. X     fprintf(output_F, "  '%s' is NULL user type (void ptr)\n",
  2369. X                                entry_P->name);
  2370. X        break;
  2371. X
  2372. X        default:
  2373. X     fprintf(output_F, "  '%s' is unknown type\n", entry_P->name);
  2374. X        break;
  2375. X
  2376. X        }
  2377. X
  2378. X        entry_P = entry_P->next_P;
  2379. X
  2380. X    }
  2381. X
  2382. X    }
  2383. X
  2384. X    return;
  2385. X}
  2386. X
  2387. X
  2388. X
  2389. X#ifdef _TESTING_
  2390. X
  2391. Xmain()
  2392. X{
  2393. X    st_Table_Pt    st_P;
  2394. X    generic_t    gval;
  2395. X    int        type;
  2396. X    static char *s_A[] = {"Joe", "Bloe", NULL};
  2397. X    char    **list_A;
  2398. X
  2399. X    st_P = St_NewTable("Test", 3);
  2400. X
  2401. X    gval.i = 10;
  2402. X     St_DefSym(st_P, "A", GEN_TYPE_INT, gval);
  2403. X
  2404. X    gval.d = 3.14;
  2405. X     St_DefSym(st_P, "PI", GEN_TYPE_DOUBLE, gval);
  2406. X
  2407. X    gval.i = 1;
  2408. X     St_DefSym(st_P, "ONE", GEN_TYPE_INT, gval);
  2409. X
  2410. X    gval.s = "Testing!";
  2411. X     St_DefSym(st_P, "TESTING", GEN_TYPE_STRING, gval);
  2412. X
  2413. X    gval.c = 7;
  2414. X     St_DefSym(st_P, "BELL", GEN_TYPE_CHAR, gval);
  2415. X
  2416. X    gval.s_A = s_A;
  2417. X     St_DefSym(st_P, "JOE BLOE", GEN_TYPE_STRING_A, gval);
  2418. X
  2419. X     St_GetSym(st_P, "A", &type, &gval);
  2420. X     printf("A = %d, type = %d\n", gval.i, type);
  2421. X
  2422. X     St_GetSym(st_P, "PI", &type, &gval);
  2423. X     printf("PI = %f, type = %d\n", gval.d, type);
  2424. X
  2425. X    St_DumpTable(stdout, St_GetTable("Test"));
  2426. X
  2427. X     St_DelSym(st_P, "TESTING");
  2428. X
  2429. X    St_DumpTable(stdout, St_GetTable("Test"));
  2430. X
  2431. X     St_DelSym(st_P, "PI");
  2432. X
  2433. X    gval.s = "Joe Bloe";
  2434. X     St_ReplSym(st_P, "JOE BLOE", GEN_TYPE_STRING, gval);
  2435. X    gval.s = "Jane Bloe";
  2436. X     St_ReplSym(st_P, "JANE BLOE", GEN_TYPE_STRING, gval);
  2437. X
  2438. X    St_DumpTable(stdout, St_GetTable("Test"));
  2439. X   
  2440. X    list_A = St_ListTable(St_GetTable("Test"));
  2441. X
  2442. X    while (*list_A)
  2443. X     printf("'%s'\n", *list_A++);
  2444. X
  2445. X    list_A = St_SListTable(St_GetTable("Test"));
  2446. X
  2447. X    while (*list_A)
  2448. X     printf("'%s'\n", *list_A++);
  2449. X
  2450. X    return 0;
  2451. X}
  2452. X
  2453. X#endif
  2454. END_OF_FILE
  2455. if test 12502 -ne `wc -c <'util/mc/symtab.c'`; then
  2456.     echo shar: \"'util/mc/symtab.c'\" unpacked with wrong size!
  2457. fi
  2458. # end of 'util/mc/symtab.c'
  2459. fi
  2460. echo shar: End of archive 25 \(of 31\).
  2461. cp /dev/null ark25isdone
  2462. MISSING=""
  2463. 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 ; do
  2464.     if test ! -f ark${I}isdone ; then
  2465.     MISSING="${MISSING} ${I}"
  2466.     fi
  2467. done
  2468. if test "${MISSING}" = "" ; then
  2469.     echo You have unpacked all 31 archives.
  2470.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2471. else
  2472.     echo You still need to unpack the following archives:
  2473.     echo "        " ${MISSING}
  2474. fi
  2475. ##  End of shell archive.
  2476. exit 0
  2477.