home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume14 / umoria4 / part14 < 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: v14i046:  umoria4 - single player dungeon simulation (ver. 5.5), Part14/39
  5. Message-ID: <3404@master.CNA.TEK.COM>
  6. Date: 20 Aug 92 18:04:40 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2327
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: grabiner@math.harvard.edu (David Grabiner)
  12. Posting-number: Volume 14, Issue 46
  13. Archive-name: umoria4/Part14
  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 14 (of 39)."
  26. # Contents:  source/generate.c source/recall.c
  27. # Wrapped by billr@saab on Thu Aug 20 09:11:29 1992
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'source/generate.c' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'source/generate.c'\"
  31. else
  32. echo shar: Extracting \"'source/generate.c'\" \(35484 characters\)
  33. sed "s/^X//" >'source/generate.c' <<'END_OF_FILE'
  34. X/* source/generate.c: initialize/create a dungeon or town level
  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#include "config.h"
  43. X#include "constant.h"
  44. X#include "types.h"
  45. X#include "externs.h"
  46. X
  47. X#if defined(USG) && !defined(VMS) && !defined(MAC)
  48. X#if !defined(ATARIST_MWC) && !defined(AMIGA)
  49. X#if !defined(__TURBOC__)
  50. X#include <memory.h>
  51. X#else
  52. X#ifndef ATARIST_TC
  53. X#include <mem.h>
  54. X#endif
  55. X#endif
  56. X#endif
  57. X#endif
  58. X
  59. X#if defined(MAC)
  60. X#include <string.h>
  61. X#endif
  62. X
  63. X#ifdef ATARIST_TC
  64. X#include <string.h>
  65. X#endif
  66. X
  67. Xtypedef struct coords {
  68. X  int x, y;
  69. X} coords;
  70. X
  71. X#if defined(LINT_ARGS)
  72. Xstatic void correct_dir(int *, int * , int, int, int, int);
  73. Xstatic void rand_dir(int *,int *);
  74. Xstatic void blank_cave(void);
  75. Xstatic void fill_cave(int);
  76. Xstatic void place_boundary(void);
  77. Xstatic void place_streamer(int, int);
  78. Xstatic void place_open_door(int, int);
  79. Xstatic void place_broken_door(int, int);
  80. Xstatic void place_closed_door(int, int);
  81. Xstatic void place_locked_door(int, int);
  82. Xstatic void place_stuck_door(int, int);
  83. Xstatic void place_secret_door(int, int);
  84. Xstatic void place_door(int, int);
  85. Xstatic void place_up_stairs(int, int);
  86. Xstatic void place_down_stairs(int, int);
  87. Xstatic void place_stairs(int, int, int);
  88. Xstatic void vault_trap(int, int, int, int, int);
  89. Xstatic void vault_monster(int, int, int);
  90. Xstatic void build_room(int, int);
  91. Xstatic void build_type1(int, int);
  92. Xstatic void build_type2(int, int);
  93. Xstatic void build_type3(int, int);
  94. Xstatic void build_tunnel(int, int, int, int);
  95. Xstatic int next_to(int, int);
  96. Xstatic void try_door(int, int);
  97. Xstatic void new_spot(int16 *, int16 *);
  98. Xstatic void cave_gen(void);
  99. Xstatic void build_store(int, int, int);
  100. Xstatic void tlink(void);
  101. Xstatic void mlink(void);
  102. Xstatic void town_gen(void);
  103. X#endif
  104. X
  105. Xstatic coords doorstk[100];
  106. Xstatic int doorindex;
  107. X
  108. X
  109. X/* Always picks a correct direction        */
  110. Xstatic void correct_dir(rdir, cdir, y1, x1, y2, x2)
  111. Xint *rdir, *cdir;
  112. Xregister int y1, x1, y2, x2;
  113. X{
  114. X  if (y1 < y2)
  115. X    *rdir =  1;
  116. X  else if (y1 == y2)
  117. X    *rdir =  0;
  118. X  else
  119. X    *rdir = -1;
  120. X  if (x1 < x2)
  121. X    *cdir =  1;
  122. X  else if (x1 == x2)
  123. X    *cdir =  0;
  124. X  else
  125. X    *cdir = -1;
  126. X  if ((*rdir != 0) && (*cdir != 0))
  127. X    {
  128. X      if (randint (2) == 1)
  129. X    *rdir = 0;
  130. X      else
  131. X    *cdir = 0;
  132. X    }
  133. X}
  134. X
  135. X
  136. X/* Chance of wandering direction            */
  137. Xstatic void rand_dir(rdir, cdir)
  138. Xint *rdir, *cdir;
  139. X{
  140. X  register int tmp;
  141. X
  142. X  tmp = randint(4);
  143. X  if (tmp < 3)
  144. X    {
  145. X      *cdir = 0;
  146. X      *rdir = -3 + (tmp << 1); /* tmp=1 -> *rdir=-1; tmp=2 -> *rdir=1 */
  147. X    }
  148. X  else
  149. X    {
  150. X      *rdir = 0;
  151. X      *cdir = -7 + (tmp << 1); /* tmp=3 -> *cdir=-1; tmp=4 -> *cdir=1 */
  152. X    }
  153. X}
  154. X
  155. X
  156. X/* Blanks out entire cave                -RAK-    */
  157. Xstatic void blank_cave()
  158. X{
  159. X#ifndef USG
  160. X  bzero ((char *)&cave[0][0], sizeof (cave));
  161. X#else
  162. X#ifdef MAC
  163. X  /* On the mac, cave is a pointer, so sizeof(cave) = 4! */
  164. X  (void)memset((char *)&cave[0][0], 0,
  165. X           (long) sizeof(cave_type) * MAX_HEIGHT * MAX_WIDTH);
  166. X#else
  167. X  (void)memset((char *)&cave[0][0], 0, sizeof (cave));
  168. X#endif
  169. X#endif
  170. X}
  171. X
  172. X
  173. X/* Fills in empty spots with desired rock        -RAK-    */
  174. X/* Note: 9 is a temporary value.                */
  175. Xstatic void fill_cave(fval)
  176. Xregister int fval;
  177. X{
  178. X  register int i, j;
  179. X  register cave_type *c_ptr;
  180. X
  181. X  /* no need to check the border of the cave */
  182. X
  183. X  for (i = cur_height - 2; i > 0; i--)
  184. X    {
  185. X      c_ptr = &cave[i][1];
  186. X      for (j = cur_width - 2; j > 0; j--)
  187. X    {
  188. X      if ((c_ptr->fval == NULL_WALL) || (c_ptr->fval == TMP1_WALL) ||
  189. X          (c_ptr->fval == TMP2_WALL))
  190. X        c_ptr->fval = fval;
  191. X      c_ptr++;
  192. X    }
  193. X    }
  194. X}
  195. X
  196. X#ifdef DEBUG
  197. X#include <assert.h>
  198. X#endif
  199. X
  200. X/* Places indestructible rock around edges of dungeon    -RAK-    */
  201. Xstatic void place_boundary()
  202. X{
  203. X  register int i;
  204. X  register cave_type *top_ptr, *bottom_ptr;
  205. X  cave_type (*left_ptr)[MAX_WIDTH];
  206. X  cave_type (*right_ptr)[MAX_WIDTH];
  207. X
  208. X  /* put permanent wall on leftmost row and rightmost row */
  209. X  left_ptr = (cave_type (*)[MAX_WIDTH]) &cave[0][0];
  210. X  right_ptr = (cave_type (*)[MAX_WIDTH]) &cave[0][cur_width - 1];
  211. X
  212. X  for (i = 0; i < cur_height; i++)
  213. X    {
  214. X#ifdef DEBUG
  215. X      assert ((cave_type *)left_ptr == &cave[i][0]);
  216. X      assert ((cave_type *)right_ptr == &cave[i][cur_width-1]);
  217. X#endif
  218. X
  219. X      ((cave_type *)left_ptr)->fval    = BOUNDARY_WALL;
  220. X      left_ptr++;
  221. X      ((cave_type *)right_ptr)->fval    = BOUNDARY_WALL;
  222. X      right_ptr++;
  223. X    }
  224. X
  225. X  /* put permanent wall on top row and bottom row */
  226. X  top_ptr = &cave[0][0];
  227. X  bottom_ptr = &cave[cur_height - 1][0];
  228. X
  229. X  for (i = 0; i < cur_width; i++)
  230. X    {
  231. X#ifdef DEBUG
  232. X      assert (top_ptr == &cave[0][i]);
  233. X      assert (bottom_ptr == &cave[cur_height - 1][i]);
  234. X#endif
  235. X
  236. X      top_ptr->fval    = BOUNDARY_WALL;
  237. X      top_ptr++;
  238. X      bottom_ptr->fval    = BOUNDARY_WALL;
  239. X      bottom_ptr++;
  240. X    }
  241. X}
  242. X
  243. X
  244. X/* Places "streamers" of rock through dungeon        -RAK-    */
  245. Xstatic void place_streamer(fval, treas_chance)
  246. Xint fval;
  247. Xint treas_chance;
  248. X{
  249. X  register int i, tx, ty;
  250. X  int y, x, t1, t2, dir;
  251. X  register cave_type *c_ptr;
  252. X
  253. X  /* Choose starting point and direction        */
  254. X  y = (cur_height / 2) + 11 - randint(23);
  255. X  x = (cur_width / 2)  + 16 - randint(33);
  256. X
  257. X  dir = randint(8);    /* Number 1-4, 6-9    */
  258. X  if (dir > 4)
  259. X    dir = dir + 1;
  260. X
  261. X  /* Place streamer into dungeon            */
  262. X  t1 = 2*DUN_STR_RNG + 1;    /* Constants    */
  263. X  t2 =     DUN_STR_RNG + 1;
  264. X  do
  265. X    {
  266. X      for (i = 0; i < DUN_STR_DEN; i++)
  267. X    {
  268. X      ty = y + randint(t1) - t2;
  269. X      tx = x + randint(t1) - t2;
  270. X      if (in_bounds(ty, tx))
  271. X        {
  272. X          c_ptr = &cave[ty][tx];
  273. X          if (c_ptr->fval == GRANITE_WALL)
  274. X        {
  275. X          c_ptr->fval = fval;
  276. X          if (randint(treas_chance) == 1)
  277. X            place_gold(ty, tx);
  278. X        }
  279. X        }
  280. X    }
  281. X    }
  282. X  while (mmove(dir, &y, &x));
  283. X}
  284. X
  285. X
  286. Xstatic void place_open_door(y, x)
  287. Xint y, x;
  288. X{
  289. X  register int cur_pos;
  290. X  register cave_type *cave_ptr;
  291. X
  292. X  cur_pos = popt();
  293. X  cave_ptr = &cave[y][x];
  294. X  cave_ptr->tptr = cur_pos;
  295. X  invcopy(&t_list[cur_pos], OBJ_OPEN_DOOR);
  296. X  cave_ptr->fval  = CORR_FLOOR;
  297. X}
  298. X
  299. X
  300. Xstatic void place_broken_door(y, x)
  301. Xint y, x;
  302. X{
  303. X  register int cur_pos;
  304. X  register cave_type *cave_ptr;
  305. X
  306. X  cur_pos = popt();
  307. X  cave_ptr = &cave[y][x];
  308. X  cave_ptr->tptr = cur_pos;
  309. X  invcopy(&t_list[cur_pos], OBJ_OPEN_DOOR);
  310. X  cave_ptr->fval  = CORR_FLOOR;
  311. X  t_list[cur_pos].p1 = 1;
  312. X}
  313. X
  314. X
  315. Xstatic void place_closed_door(y, x)
  316. Xint y, x;
  317. X{
  318. X  register int cur_pos;
  319. X  register cave_type *cave_ptr;
  320. X
  321. X  cur_pos = popt();
  322. X  cave_ptr = &cave[y][x];
  323. X  cave_ptr->tptr = cur_pos;
  324. X  invcopy(&t_list[cur_pos], OBJ_CLOSED_DOOR);
  325. X  cave_ptr->fval  = BLOCKED_FLOOR;
  326. X}
  327. X
  328. X
  329. Xstatic void place_locked_door(y, x)
  330. Xint y, x;
  331. X{
  332. X  register int cur_pos;
  333. X  register cave_type *cave_ptr;
  334. X
  335. X  cur_pos = popt();
  336. X  cave_ptr = &cave[y][x];
  337. X  cave_ptr->tptr = cur_pos;
  338. X  invcopy(&t_list[cur_pos], OBJ_CLOSED_DOOR);
  339. X  cave_ptr->fval  = BLOCKED_FLOOR;
  340. X  t_list[cur_pos].p1 = randint(10) + 10;
  341. X}
  342. X
  343. X
  344. Xstatic void place_stuck_door(y, x)
  345. Xint y, x;
  346. X{
  347. X  register int cur_pos;
  348. X  register cave_type *cave_ptr;
  349. X
  350. X  cur_pos = popt();
  351. X  cave_ptr = &cave[y][x];
  352. X  cave_ptr->tptr = cur_pos;
  353. X  invcopy(&t_list[cur_pos], OBJ_CLOSED_DOOR);
  354. X  cave_ptr->fval  = BLOCKED_FLOOR;
  355. X  t_list[cur_pos].p1 = -randint(10) - 10;
  356. X}
  357. X
  358. X
  359. Xstatic void place_secret_door(y, x)
  360. Xint y, x;
  361. X{
  362. X  register int cur_pos;
  363. X  register cave_type *cave_ptr;
  364. X
  365. X  cur_pos = popt();
  366. X  cave_ptr = &cave[y][x];
  367. X  cave_ptr->tptr = cur_pos;
  368. X  invcopy(&t_list[cur_pos], OBJ_SECRET_DOOR);
  369. X  cave_ptr->fval  = BLOCKED_FLOOR;
  370. X}
  371. X
  372. X
  373. Xstatic void place_door(y, x)
  374. Xint y, x;
  375. X{
  376. X  register int tmp;
  377. X
  378. X  tmp = randint(3);
  379. X  if (tmp == 1)
  380. X    {
  381. X      if (randint(4) == 1)
  382. X    place_broken_door(y, x);
  383. X      else
  384. X    place_open_door(y, x);
  385. X    }
  386. X  else if (tmp == 2)
  387. X    {
  388. X      tmp = randint(12);
  389. X      if (tmp > 3)
  390. X    place_closed_door(y, x);
  391. X      else if (tmp == 3)
  392. X    place_stuck_door(y, x);
  393. X      else
  394. X    place_locked_door(y, x);
  395. X    }
  396. X  else
  397. X    place_secret_door(y, x);
  398. X}
  399. X
  400. X
  401. X/* Place an up staircase at given y, x            -RAK-    */
  402. Xstatic void place_up_stairs(y, x)
  403. Xint y, x;
  404. X{
  405. X  register int cur_pos;
  406. X  register cave_type *cave_ptr;
  407. X
  408. X  cave_ptr = &cave[y][x];
  409. X  if (cave_ptr->tptr != 0)
  410. X    (void) delete_object(y, x);
  411. X  cur_pos = popt();
  412. X  cave_ptr->tptr = cur_pos;
  413. X  invcopy(&t_list[cur_pos], OBJ_UP_STAIR);
  414. X}
  415. X
  416. X
  417. X/* Place a down staircase at given y, x            -RAK-    */
  418. Xstatic void place_down_stairs(y, x)
  419. Xint y, x;
  420. X{
  421. X  register int cur_pos;
  422. X  register cave_type *cave_ptr;
  423. X
  424. X  cave_ptr = &cave[y][x];
  425. X  if (cave_ptr->tptr != 0)
  426. X    (void) delete_object(y, x);
  427. X  cur_pos = popt();
  428. X  cave_ptr->tptr = cur_pos;
  429. X  invcopy(&t_list[cur_pos], OBJ_DOWN_STAIR);
  430. X}
  431. X
  432. X
  433. X/* Places a staircase 1=up, 2=down            -RAK-    */
  434. Xstatic void place_stairs(typ, num, walls)
  435. Xint typ, num, walls;
  436. X{
  437. X  register cave_type *cave_ptr;
  438. X  int i, j, flag;
  439. X  register int y1, x1, y2, x2;
  440. X
  441. X  for (i = 0; i < num; i++)
  442. X    {
  443. X      flag = FALSE;
  444. X      do
  445. X    {
  446. X      j = 0;
  447. X      do
  448. X        {
  449. X          /* Note: don't let y1/x1 be zero, and don't let y2/x2 be equal
  450. X         to cur_height-1/cur_width-1, these values are always
  451. X         BOUNDARY_ROCK. */
  452. X          y1 = randint(cur_height - 14);
  453. X          x1 = randint(cur_width  - 14);
  454. X          y2 = y1 + 12;
  455. X          x2 = x1 + 12;
  456. X          do
  457. X        {
  458. X          do
  459. X            {
  460. X              cave_ptr = &cave[y1][x1];
  461. X              if (cave_ptr->fval <= MAX_OPEN_SPACE
  462. X              && (cave_ptr->tptr == 0)
  463. X              && (next_to_walls(y1, x1) >= walls))
  464. X            {
  465. X              flag = TRUE;
  466. X              if (typ == 1)
  467. X                place_up_stairs(y1, x1);
  468. X              else
  469. X                place_down_stairs(y1, x1);
  470. X            }
  471. X              x1++;
  472. X            }
  473. X          while ((x1 != x2) && (!flag));
  474. X          x1 = x2 - 12;
  475. X          y1++;
  476. X        }
  477. X          while ((y1 != y2) && (!flag));
  478. X          j++;
  479. X        }
  480. X      while ((!flag) && (j <= 30));
  481. X      walls--;
  482. X    }
  483. X      while (!flag);
  484. X    }
  485. X}
  486. X
  487. X
  488. X/* Place a trap with a given displacement of point    -RAK-    */
  489. Xstatic void vault_trap(y, x, yd, xd, num)
  490. Xint y, x, yd, xd, num;
  491. X{
  492. X  register int count, y1, x1;
  493. X  int i, flag;
  494. X  register cave_type *c_ptr;
  495. X
  496. X  for (i = 0; i < num; i++)
  497. X    {
  498. X      flag = FALSE;
  499. X      count = 0;
  500. X      do
  501. X    {
  502. X      y1 = y - yd - 1 + randint(2*yd+1);
  503. X      x1 = x - xd - 1 + randint(2*xd+1);
  504. X      c_ptr = &cave[y1][x1];
  505. X      if ((c_ptr->fval != NULL_WALL) && (c_ptr->fval <= MAX_CAVE_FLOOR)
  506. X          && (c_ptr->tptr == 0))
  507. X        {
  508. X          place_trap(y1, x1, randint(MAX_TRAP)-1);
  509. X          flag = TRUE;
  510. X        }
  511. X      count++;
  512. X    }
  513. X      while ((!flag) && (count <= 5));
  514. X    }
  515. X}
  516. X
  517. X
  518. X/* Place a trap with a given displacement of point    -RAK-    */
  519. Xstatic void vault_monster(y, x, num)
  520. Xint y, x, num;
  521. X{
  522. X  register int i;
  523. X  int y1, x1;
  524. X
  525. X  for (i = 0; i < num; i++)
  526. X    {
  527. X      y1 = y;
  528. X      x1 = x;
  529. X      (void) summon_monster(&y1, &x1, TRUE);
  530. X    }
  531. X}
  532. X
  533. X
  534. X/* Builds a room at a row, column coordinate        -RAK-    */
  535. Xstatic void build_room(yval, xval)
  536. Xint yval, xval;
  537. X{
  538. X  register int i, j, y_depth, x_right;
  539. X  int y_height, x_left;
  540. X  int8u floor;
  541. X  register cave_type *c_ptr, *d_ptr;
  542. X
  543. X  if (dun_level <= randint(25))
  544. X    floor = LIGHT_FLOOR;    /* Floor with light    */
  545. X  else
  546. X    floor = DARK_FLOOR;        /* Dark floor        */
  547. X
  548. X  y_height = yval - randint(4);
  549. X  y_depth  = yval + randint(3);
  550. X  x_left   = xval - randint(11);
  551. X  x_right  = xval + randint(11);
  552. X
  553. X  /* the x dim of rooms tends to be much larger than the y dim, so don't
  554. X     bother rewriting the y loop */
  555. X
  556. X  for (i = y_height; i <= y_depth; i++)
  557. X    {
  558. X      c_ptr = &cave[i][x_left];
  559. X      for (j = x_left; j <= x_right; j++)
  560. X    {
  561. X      c_ptr->fval  = floor;
  562. X      c_ptr->lr = TRUE;
  563. X      c_ptr++;
  564. X    }
  565. X    }
  566. X
  567. X  for (i = (y_height - 1); i <= (y_depth + 1); i++)
  568. X    {
  569. X      c_ptr = &cave[i][x_left-1];
  570. X      c_ptr->fval   = GRANITE_WALL;
  571. X      c_ptr->lr = TRUE;
  572. X      c_ptr = &cave[i][x_right+1];
  573. X      c_ptr->fval  = GRANITE_WALL;
  574. X      c_ptr->lr = TRUE;
  575. X    }
  576. X
  577. X  c_ptr = &cave[y_height - 1][x_left];
  578. X  d_ptr = &cave[y_depth + 1][x_left];
  579. X  for (i = x_left; i <= x_right; i++)
  580. X    {
  581. X      c_ptr->fval  = GRANITE_WALL;
  582. X      c_ptr->lr = TRUE;
  583. X      c_ptr++;
  584. X      d_ptr->fval   = GRANITE_WALL;
  585. X      d_ptr->lr = TRUE;
  586. X      d_ptr++;
  587. X    }
  588. X}
  589. X
  590. X
  591. X/* Builds a room at a row, column coordinate        -RAK-    */
  592. X/* Type 1 unusual rooms are several overlapping rectangular ones    */
  593. Xstatic void build_type1(yval, xval)
  594. Xint yval, xval;
  595. X{
  596. X  int y_height, y_depth;
  597. X  int x_left, x_right, limit;
  598. X  register int i0, i, j;
  599. X  int8u floor;
  600. X  register cave_type *c_ptr, *d_ptr;
  601. X
  602. X  if (dun_level <= randint(25))
  603. X    floor = LIGHT_FLOOR;    /* Floor with light    */
  604. X  else
  605. X    floor = DARK_FLOOR;        /* Dark floor        */
  606. X  limit = 1 + randint(2);
  607. X  for (i0 = 0; i0 < limit; i0++)
  608. X    {
  609. X      y_height = yval - randint(4);
  610. X      y_depth  = yval + randint(3);
  611. X      x_left   = xval - randint(11);
  612. X      x_right  = xval + randint(11);
  613. X
  614. X      /* the x dim of rooms tends to be much larger than the y dim, so don't
  615. X     bother rewriting the y loop */
  616. X
  617. X      for (i = y_height; i <= y_depth; i++)
  618. X    {
  619. X      c_ptr = &cave[i][x_left];
  620. X      for (j = x_left; j <= x_right; j++)
  621. X        {
  622. X          c_ptr->fval  = floor;
  623. X          c_ptr->lr = TRUE;
  624. X          c_ptr++;
  625. X        }
  626. X    }
  627. X      for (i = (y_height - 1); i <= (y_depth + 1); i++)
  628. X    {
  629. X      c_ptr = &cave[i][x_left-1];
  630. X      if (c_ptr->fval != floor)
  631. X        {
  632. X          c_ptr->fval  = GRANITE_WALL;
  633. X          c_ptr->lr = TRUE;
  634. X        }
  635. X      c_ptr = &cave[i][x_right+1];
  636. X      if (c_ptr->fval != floor)
  637. X        {
  638. X          c_ptr->fval  = GRANITE_WALL;
  639. X          c_ptr->lr = TRUE;
  640. X        }
  641. X    }
  642. X      c_ptr = &cave[y_height - 1][x_left];
  643. X      d_ptr = &cave[y_depth + 1][x_left];
  644. X      for (i = x_left; i <= x_right; i++)
  645. X    {
  646. X      if (c_ptr->fval != floor)
  647. X        {
  648. X          c_ptr->fval  = GRANITE_WALL;
  649. X          c_ptr->lr = TRUE;
  650. X        }
  651. X      c_ptr++;
  652. X      if (d_ptr->fval != floor)
  653. X        {
  654. X          d_ptr->fval  = GRANITE_WALL;
  655. X          d_ptr->lr = TRUE;
  656. X        }
  657. X      d_ptr++;
  658. X    }
  659. X    }
  660. X}
  661. X
  662. X
  663. X/* Builds an unusual room at a row, column coordinate    -RAK-    */
  664. X/* Type 2 unusual rooms all have an inner room:            */
  665. X/*   1 - Just an inner room with one door            */
  666. X/*   2 - An inner room within an inner room            */
  667. X/*   3 - An inner room with pillar(s)                */
  668. X/*   4 - Inner room has a maze                    */
  669. X/*   5 - A set of four inner rooms                */
  670. Xstatic void build_type2(yval, xval)
  671. Xint yval, xval;
  672. X{
  673. X  register int i, j, y_height, x_left;
  674. X  int y_depth, x_right, tmp;
  675. X  int8u floor;
  676. X  register cave_type *c_ptr, *d_ptr;
  677. X
  678. X  if (dun_level <= randint(25))
  679. X    floor = LIGHT_FLOOR;    /* Floor with light    */
  680. X  else
  681. X    floor = DARK_FLOOR;        /* Dark floor        */
  682. X  y_height = yval - 4;
  683. X  y_depth  = yval + 4;
  684. X  x_left   = xval - 11;
  685. X  x_right  = xval + 11;
  686. X
  687. X  /* the x dim of rooms tends to be much larger than the y dim, so don't
  688. X     bother rewriting the y loop */
  689. X
  690. X  for (i = y_height; i <= y_depth; i++)
  691. X    {
  692. X      c_ptr = &cave[i][x_left];
  693. X      for (j = x_left; j <= x_right; j++)
  694. X    {
  695. X      c_ptr->fval  = floor;
  696. X      c_ptr->lr = TRUE;
  697. X      c_ptr++;
  698. X    }
  699. X    }
  700. X  for (i = (y_height - 1); i <= (y_depth + 1); i++)
  701. X    {
  702. X      c_ptr = &cave[i][x_left-1];
  703. X      c_ptr->fval   = GRANITE_WALL;
  704. X      c_ptr->lr = TRUE;
  705. X      c_ptr = &cave[i][x_right+1];
  706. X      c_ptr->fval  = GRANITE_WALL;
  707. X      c_ptr->lr = TRUE;
  708. X    }
  709. X  c_ptr = &cave[y_height - 1][x_left];
  710. X  d_ptr = &cave[y_depth + 1][x_left];
  711. X  for (i = x_left; i <= x_right; i++)
  712. X    {
  713. X      c_ptr->fval  = GRANITE_WALL;
  714. X      c_ptr->lr = TRUE;
  715. X      c_ptr++;
  716. X      d_ptr->fval   = GRANITE_WALL;
  717. X      d_ptr->lr = TRUE;
  718. X      d_ptr++;
  719. X    }
  720. X  /* The inner room        */
  721. X  y_height = y_height + 2;
  722. X  y_depth  = y_depth  - 2;
  723. X  x_left   = x_left   + 2;
  724. X  x_right  = x_right  - 2;
  725. X  for (i = (y_height - 1); i <= (y_depth + 1); i++)
  726. X    {
  727. X      cave[i][x_left-1].fval = TMP1_WALL;
  728. X      cave[i][x_right+1].fval = TMP1_WALL;
  729. X    }
  730. X  c_ptr = &cave[y_height-1][x_left];
  731. X  d_ptr = &cave[y_depth+1][x_left];
  732. X  for (i = x_left; i <= x_right; i++)
  733. X    {
  734. X      c_ptr->fval = TMP1_WALL;
  735. X      c_ptr++;
  736. X      d_ptr->fval = TMP1_WALL;
  737. X      d_ptr++;
  738. X    }
  739. X  /* Inner room variations        */
  740. X  switch(randint(5))
  741. X    {
  742. X    case 1:    /* Just an inner room.    */
  743. X      tmp = randint(4);
  744. X      if (tmp < 3) {    /* Place a door    */
  745. X    if (tmp == 1) place_secret_door(y_height-1, xval);
  746. X    else          place_secret_door(y_depth+1, xval);
  747. X      } else {
  748. X    if (tmp == 3) place_secret_door(yval, x_left-1);
  749. X    else          place_secret_door(yval, x_right+1);
  750. X      }
  751. X      vault_monster(yval, xval, 1);
  752. X      break;
  753. X
  754. X    case 2:    /* Treasure Vault    */
  755. X      tmp = randint(4);
  756. X      if (tmp < 3) {    /* Place a door    */
  757. X    if (tmp == 1) place_secret_door(y_height-1, xval);
  758. X    else          place_secret_door(y_depth+1, xval);
  759. X      } else {
  760. X    if (tmp == 3) place_secret_door(yval, x_left-1);
  761. X    else          place_secret_door(yval, x_right+1);
  762. X      }
  763. X
  764. X      for (i = yval-1; i <= yval+1; i++)
  765. X    {
  766. X      cave[i][xval-1].fval     = TMP1_WALL;
  767. X      cave[i][xval+1].fval     = TMP1_WALL;
  768. X    }
  769. X      cave[yval-1][xval].fval  = TMP1_WALL;
  770. X      cave[yval+1][xval].fval  = TMP1_WALL;
  771. X
  772. X      tmp = randint(4);    /* Place a door    */
  773. X      if (tmp < 3)
  774. X    place_locked_door(yval-3+(tmp<<1), xval); /* 1 -> yval-1; 2 -> yval+1*/
  775. X      else
  776. X    place_locked_door(yval, xval-7+(tmp<<1));
  777. X
  778. X      /* Place an object in the treasure vault    */
  779. X      tmp = randint(10);
  780. X      if (tmp > 2)
  781. X    place_object(yval, xval);
  782. X      else if (tmp == 2)
  783. X    place_down_stairs(yval, xval);
  784. X      else
  785. X    place_up_stairs(yval, xval);
  786. X
  787. X      /* Guard the treasure well        */
  788. X      vault_monster(yval, xval, 2+randint(3));
  789. X      /* If the monsters don't get 'em.    */
  790. X      vault_trap(yval, xval, 4, 10, 2+randint(3));
  791. X      break;
  792. X
  793. X    case 3:    /* Inner pillar(s).    */
  794. X      tmp = randint(4);
  795. X      if (tmp < 3) {    /* Place a door    */
  796. X    if (tmp == 1) place_secret_door(y_height-1, xval);
  797. X    else          place_secret_door(y_depth+1, xval);
  798. X      } else {
  799. X    if (tmp == 3) place_secret_door(yval, x_left-1);
  800. X    else          place_secret_door(yval, x_right+1);
  801. X      }
  802. X
  803. X      for (i = yval-1; i <= yval+1; i++)
  804. X    {
  805. X      c_ptr = &cave[i][xval-1];
  806. X      for (j = xval-1; j <= xval+1; j++)
  807. X        {
  808. X          c_ptr->fval = TMP1_WALL;
  809. X          c_ptr++;
  810. X        }
  811. X    }
  812. X      if (randint(2) == 1)
  813. X    {
  814. X      tmp = randint(2);
  815. X      for (i = yval-1; i <= yval+1; i++)
  816. X        {
  817. X          c_ptr = &cave[i][xval-5-tmp];
  818. X          for (j = xval-5-tmp; j <= xval-3-tmp; j++)
  819. X        {
  820. X          c_ptr->fval = TMP1_WALL;
  821. X          c_ptr++;
  822. X        }
  823. X        }
  824. X      for (i = yval-1; i <= yval+1; i++)
  825. X        {
  826. X          c_ptr = &cave[i][xval+3+tmp];
  827. X          for (j = xval+3+tmp; j <= xval+5+tmp; j++)
  828. X        {
  829. X          c_ptr->fval  = TMP1_WALL;
  830. X          c_ptr++;
  831. X        }
  832. X        }
  833. X    }
  834. X
  835. X      if (randint(3) == 1)    /* Inner rooms    */
  836. X    {
  837. X      c_ptr = &cave[yval-1][xval-5];
  838. X      d_ptr = &cave[yval+1][xval-5];
  839. X      for (i = xval-5; i <= xval+5; i++)
  840. X        {
  841. X          c_ptr->fval  = TMP1_WALL;
  842. X          c_ptr++;
  843. X          d_ptr->fval  = TMP1_WALL;
  844. X          d_ptr++;
  845. X        }
  846. X      cave[yval][xval-5].fval = TMP1_WALL;
  847. X      cave[yval][xval+5].fval = TMP1_WALL;
  848. X      place_secret_door(yval-3+(randint(2)<<1), xval-3);
  849. X      place_secret_door(yval-3+(randint(2)<<1), xval+3);
  850. X      if (randint(3) == 1)    place_object(yval, xval-2);
  851. X      if (randint(3) == 1)    place_object(yval, xval+2);
  852. X      vault_monster(yval, xval-2, randint(2));
  853. X      vault_monster(yval, xval+2, randint(2));
  854. X    }
  855. X      break;
  856. X
  857. X    case 4:    /* Maze inside.    */
  858. X      tmp = randint(4);
  859. X      if (tmp < 3) {    /* Place a door    */
  860. X    if (tmp == 1) place_secret_door(y_height-1, xval);
  861. X    else          place_secret_door(y_depth+1, xval);
  862. X      } else {
  863. X    if (tmp == 3) place_secret_door(yval, x_left-1);
  864. X    else          place_secret_door(yval, x_right+1);
  865. X      }
  866. X
  867. X      for (i = y_height; i <= y_depth; i++)
  868. X    for (j = x_left; j <= x_right; j++)
  869. X      if (0x1 & (j+i))
  870. X        cave[i][j].fval = TMP1_WALL;
  871. X
  872. X      /* Monsters just love mazes.        */
  873. X      vault_monster(yval, xval-5, randint(3));
  874. X      vault_monster(yval, xval+5, randint(3));
  875. X      /* Traps make them entertaining.    */
  876. X      vault_trap(yval, xval-3, 2, 8, randint(3));
  877. X      vault_trap(yval, xval+3, 2, 8, randint(3));
  878. X      /* Mazes should have some treasure too..    */
  879. X      for (i = 0; i < 3; i++)
  880. X    random_object(yval, xval, 1);
  881. X      break;
  882. X
  883. X    case 5:    /* Four small rooms.    */
  884. X      for (i = y_height; i <= y_depth; i++)
  885. X    cave[i][xval].fval = TMP1_WALL;
  886. X
  887. X      c_ptr = &cave[yval][x_left];
  888. X      for (i = x_left; i <= x_right; i++)
  889. X    {
  890. X      c_ptr->fval = TMP1_WALL;
  891. X      c_ptr++;
  892. X    }
  893. X
  894. X      if (randint(2) == 1)
  895. X    {
  896. X      i = randint(10);
  897. X      place_secret_door(y_height-1, xval-i);
  898. X      place_secret_door(y_height-1, xval+i);
  899. X      place_secret_door(y_depth+1, xval-i);
  900. X      place_secret_door(y_depth+1, xval+i);
  901. X    }
  902. X      else
  903. X    {
  904. X      i = randint(3);
  905. X      place_secret_door(yval+i, x_left-1);
  906. X      place_secret_door(yval-i, x_left-1);
  907. X      place_secret_door(yval+i, x_right+1);
  908. X      place_secret_door(yval-i, x_right+1);
  909. X    }
  910. X
  911. X      /* Treasure in each one.        */
  912. X      random_object(yval, xval, 2+randint(2));
  913. X      /* Gotta have some monsters.        */
  914. X      vault_monster(yval+2, xval-4, randint(2));
  915. X      vault_monster(yval+2, xval+4, randint(2));
  916. X      vault_monster(yval-2, xval-4, randint(2));
  917. X      vault_monster(yval-2, xval+4, randint(2));
  918. X      break;
  919. X    }
  920. X}
  921. X
  922. X
  923. X/* Builds a room at a row, column coordinate        -RAK-    */
  924. X/* Type 3 unusual rooms are cross shaped                */
  925. Xstatic void build_type3(yval, xval)
  926. Xint yval, xval;
  927. X{
  928. X  int y_height, y_depth;
  929. X  int x_left, x_right;
  930. X  register int tmp, i, j;
  931. X  int8u floor;
  932. X  register cave_type *c_ptr;
  933. X
  934. X  if (dun_level <= randint(25))
  935. X    floor = LIGHT_FLOOR;    /* Floor with light    */
  936. X  else
  937. X    floor = DARK_FLOOR;        /* Dark floor        */
  938. X  tmp = 2 + randint(2);
  939. X  y_height = yval - tmp;
  940. X  y_depth  = yval + tmp;
  941. X  x_left   = xval - 1;
  942. X  x_right  = xval + 1;
  943. X  for (i = y_height; i <= y_depth; i++)
  944. X    for (j = x_left; j <= x_right; j++)
  945. X      {
  946. X    c_ptr = &cave[i][j];
  947. X    c_ptr->fval = floor;
  948. X    c_ptr->lr = TRUE;
  949. X      }
  950. X  for (i = (y_height - 1); i <= (y_depth + 1); i++)
  951. X    {
  952. X      c_ptr = &cave[i][x_left-1];
  953. X      c_ptr->fval  = GRANITE_WALL;
  954. X      c_ptr->lr = TRUE;
  955. X      c_ptr = &cave[i][x_right+1];
  956. X      c_ptr->fval  = GRANITE_WALL;
  957. X      c_ptr->lr = TRUE;
  958. X    }
  959. X  for (i = x_left; i <= x_right; i++)
  960. X    {
  961. X      c_ptr = &cave[y_height-1][i];
  962. X      c_ptr->fval  = GRANITE_WALL;
  963. X      c_ptr->lr = TRUE;
  964. X      c_ptr = &cave[y_depth+1][i];
  965. X      c_ptr->fval  = GRANITE_WALL;
  966. X      c_ptr->lr = TRUE;
  967. X    }
  968. X  tmp = 2 + randint(9);
  969. X  y_height = yval - 1;
  970. X  y_depth  = yval + 1;
  971. X  x_left   = xval - tmp;
  972. X  x_right  = xval + tmp;
  973. X  for (i = y_height; i <= y_depth; i++)
  974. X    for (j = x_left; j <= x_right; j++)
  975. X      {
  976. X    c_ptr = &cave[i][j];
  977. X    c_ptr->fval = floor;
  978. X    c_ptr->lr = TRUE;
  979. X      }
  980. X  for (i = (y_height - 1); i <= (y_depth + 1); i++)
  981. X    {
  982. X      c_ptr = &cave[i][x_left-1];
  983. X      if (c_ptr->fval != floor)
  984. X    {
  985. X      c_ptr->fval  = GRANITE_WALL;
  986. X      c_ptr->lr = TRUE;
  987. X    }
  988. X      c_ptr = &cave[i][x_right+1];
  989. X      if (c_ptr->fval != floor)
  990. X    {
  991. X      c_ptr->fval  = GRANITE_WALL;
  992. X      c_ptr->lr = TRUE;
  993. X    }
  994. X    }
  995. X  for (i = x_left; i <= x_right; i++)
  996. X    {
  997. X      c_ptr = &cave[y_height-1][i];
  998. X      if (c_ptr->fval != floor)
  999. X    {
  1000. X      c_ptr->fval  = GRANITE_WALL;
  1001. X      c_ptr->lr = TRUE;
  1002. X    }
  1003. X      c_ptr = &cave[y_depth+1][i];
  1004. X      if (c_ptr->fval != floor)
  1005. X    {
  1006. X      c_ptr->fval  = GRANITE_WALL;
  1007. X      c_ptr->lr = TRUE;
  1008. X    }
  1009. X    }
  1010. X  /* Special features.            */
  1011. X  switch(randint(4))
  1012. X    {
  1013. X    case 1:    /* Large middle pillar        */
  1014. X      for (i = yval-1; i <= yval+1; i++)
  1015. X    {
  1016. X      c_ptr = &cave[i][xval-1];
  1017. X      for (j = xval-1; j <= xval+1; j++)
  1018. X        {
  1019. X          c_ptr->fval = TMP1_WALL;
  1020. X          c_ptr++;
  1021. X        }
  1022. X    }
  1023. X      break;
  1024. X
  1025. X    case 2:    /* Inner treasure vault        */
  1026. X      for (i = yval-1; i <= yval+1; i++)
  1027. X    {
  1028. X      cave[i][xval-1].fval     = TMP1_WALL;
  1029. X      cave[i][xval+1].fval     = TMP1_WALL;
  1030. X    }
  1031. X      cave[yval-1][xval].fval  = TMP1_WALL;
  1032. X      cave[yval+1][xval].fval  = TMP1_WALL;
  1033. X
  1034. X      tmp = randint(4);    /* Place a door    */
  1035. X      if (tmp < 3)
  1036. X    place_secret_door(yval-3+(tmp<<1), xval);
  1037. X      else
  1038. X    place_secret_door(yval, xval-7+(tmp<<1));
  1039. X
  1040. X      /* Place a treasure in the vault        */
  1041. X      place_object(yval, xval);
  1042. X      /* Let's guard the treasure well.    */
  1043. X      vault_monster(yval, xval, 2+randint(2));
  1044. X      /* Traps naturally            */
  1045. X      vault_trap(yval, xval, 4, 4, 1+randint(3));
  1046. X      break;
  1047. X
  1048. X    case 3:
  1049. X      if (randint(3) == 1)
  1050. X    {
  1051. X      cave[yval-1][xval-2].fval = TMP1_WALL;
  1052. X      cave[yval+1][xval-2].fval = TMP1_WALL;
  1053. X      cave[yval-1][xval+2].fval = TMP1_WALL;
  1054. X      cave[yval+1][xval+2].fval = TMP1_WALL;
  1055. X      cave[yval-2][xval-1].fval = TMP1_WALL;
  1056. X      cave[yval-2][xval+1].fval = TMP1_WALL;
  1057. X      cave[yval+2][xval-1].fval = TMP1_WALL;
  1058. X      cave[yval+2][xval+1].fval = TMP1_WALL;
  1059. X      if (randint(3) == 1)
  1060. X        {
  1061. X          place_secret_door(yval, xval-2);
  1062. X          place_secret_door(yval, xval+2);
  1063. X          place_secret_door(yval-2, xval);
  1064. X          place_secret_door(yval+2, xval);
  1065. X        }
  1066. X    }
  1067. X      else if (randint(3) == 1)
  1068. X    {
  1069. X      cave[yval][xval].fval = TMP1_WALL;
  1070. X      cave[yval-1][xval].fval = TMP1_WALL;
  1071. X      cave[yval+1][xval].fval = TMP1_WALL;
  1072. X      cave[yval][xval-1].fval = TMP1_WALL;
  1073. X      cave[yval][xval+1].fval = TMP1_WALL;
  1074. X    }
  1075. X      else if (randint(3) == 1)
  1076. X    cave[yval][xval].fval = TMP1_WALL;
  1077. X      break;
  1078. X
  1079. X    case 4:
  1080. X      break;
  1081. X    }
  1082. X}
  1083. X
  1084. X
  1085. X/* Constructs a tunnel between two points        */
  1086. Xstatic void build_tunnel(row1, col1, row2, col2)
  1087. Xint row1, col1, row2, col2;
  1088. X{
  1089. X  register int tmp_row, tmp_col, i, j;
  1090. X  register cave_type *c_ptr;
  1091. X  cave_type *d_ptr;
  1092. X  coords tunstk[1000], wallstk[1000];
  1093. X  coords *tun_ptr;
  1094. X  int row_dir, col_dir, tunindex, wallindex;
  1095. X  int stop_flag, door_flag, main_loop_count;
  1096. X  int start_row, start_col;
  1097. X
  1098. X  /* Main procedure for Tunnel            */
  1099. X  /* Note: 9 is a temporary value        */
  1100. X  stop_flag = FALSE;
  1101. X  door_flag = FALSE;
  1102. X  tunindex    = 0;
  1103. X  wallindex   = 0;
  1104. X  main_loop_count = 0;
  1105. X  start_row = row1;
  1106. X  start_col = col1;
  1107. X  correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
  1108. X
  1109. X  do
  1110. X    {
  1111. X      /* prevent infinite loops, just in case */
  1112. X      main_loop_count++;
  1113. X      if (main_loop_count > 2000)
  1114. X    stop_flag = TRUE;
  1115. X
  1116. X      if (randint(100) > DUN_TUN_CHG)
  1117. X    {
  1118. X      if (randint(DUN_TUN_RND) == 1)
  1119. X        rand_dir(&row_dir, &col_dir);
  1120. X      else
  1121. X        correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
  1122. X    }
  1123. X      tmp_row = row1 + row_dir;
  1124. X      tmp_col = col1 + col_dir;
  1125. X      while (!in_bounds(tmp_row, tmp_col))
  1126. X    {
  1127. X      if (randint(DUN_TUN_RND) == 1)
  1128. X        rand_dir(&row_dir, &col_dir);
  1129. X      else
  1130. X        correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
  1131. X      tmp_row = row1 + row_dir;
  1132. X      tmp_col = col1 + col_dir;
  1133. X    }
  1134. X      c_ptr = &cave[tmp_row][tmp_col];
  1135. X      if (c_ptr->fval == NULL_WALL)
  1136. X    {
  1137. X      row1 = tmp_row;
  1138. X      col1 = tmp_col;
  1139. X      if (tunindex < 1000)
  1140. X        {
  1141. X          tunstk[tunindex].y = row1;
  1142. X          tunstk[tunindex].x = col1;
  1143. X          tunindex++;
  1144. X        }
  1145. X      door_flag = FALSE;
  1146. X    }
  1147. X      else if (c_ptr->fval == TMP2_WALL)
  1148. X    /* do nothing */
  1149. X    ;
  1150. X      else if (c_ptr->fval == GRANITE_WALL)
  1151. X    {
  1152. X      row1 = tmp_row;
  1153. X      col1 = tmp_col;
  1154. X      if (wallindex < 1000)
  1155. X        {
  1156. X          wallstk[wallindex].y = row1;
  1157. X          wallstk[wallindex].x = col1;
  1158. X          wallindex++;
  1159. X        }
  1160. X      for (i = row1-1; i <= row1+1; i++)
  1161. X        for (j = col1-1; j <= col1+1; j++)
  1162. X          if (in_bounds(i, j))
  1163. X        {
  1164. X          d_ptr = &cave[i][j];
  1165. X          /* values 11 and 12 are impossible here, place_streamer
  1166. X             is never run before build_tunnel */
  1167. X          if (d_ptr->fval == GRANITE_WALL)
  1168. X            d_ptr->fval = TMP2_WALL;
  1169. X        }
  1170. X    }
  1171. X      else if (c_ptr->fval == CORR_FLOOR || c_ptr->fval == BLOCKED_FLOOR)
  1172. X    {
  1173. X      row1 = tmp_row;
  1174. X      col1 = tmp_col;
  1175. X      if (!door_flag)
  1176. X        {
  1177. X          if (doorindex < 100)
  1178. X        {
  1179. X          doorstk[doorindex].y = row1;
  1180. X          doorstk[doorindex].x = col1;
  1181. X          doorindex++;
  1182. X        }
  1183. X          door_flag = TRUE;
  1184. X        }
  1185. X      if (randint(100) > DUN_TUN_CON)
  1186. X        {
  1187. X          /* make sure that tunnel has gone a reasonable distance
  1188. X         before stopping it, this helps prevent isolated rooms */
  1189. X          tmp_row = row1 - start_row;
  1190. X          if (tmp_row < 0) tmp_row = -tmp_row;
  1191. X          tmp_col = col1 - start_col;
  1192. X          if (tmp_col < 0) tmp_col = -tmp_col;
  1193. X          if (tmp_row > 10 || tmp_col > 10)
  1194. X        stop_flag = TRUE;
  1195. X        }
  1196. X    }
  1197. X      else  /* c_ptr->fval != NULL, TMP2, GRANITE, CORR */
  1198. X    {
  1199. X      row1 = tmp_row;
  1200. X      col1 = tmp_col;
  1201. X    }
  1202. X    }
  1203. X  while (((row1 != row2) || (col1 != col2)) && (!stop_flag));
  1204. X
  1205. X  tun_ptr = &tunstk[0];
  1206. X  for (i = 0; i < tunindex; i++)
  1207. X    {
  1208. X      d_ptr = &cave[tun_ptr->y][tun_ptr->x];
  1209. X      d_ptr->fval  = CORR_FLOOR;
  1210. X      tun_ptr++;
  1211. X    }
  1212. X  for (i = 0; i < wallindex; i++)
  1213. X    {
  1214. X      c_ptr = &cave[wallstk[i].y][wallstk[i].x];
  1215. X      if (c_ptr->fval == TMP2_WALL)
  1216. X    {
  1217. X      if (randint(100) < DUN_TUN_PEN)
  1218. X        place_door(wallstk[i].y, wallstk[i].x);
  1219. X      else
  1220. X        {
  1221. X          /* these have to be doorways to rooms */
  1222. X          c_ptr->fval  = CORR_FLOOR;
  1223. X        }
  1224. X    }
  1225. X    }
  1226. X}
  1227. X
  1228. X
  1229. Xstatic int next_to(y, x)
  1230. Xregister int y, x;
  1231. X{
  1232. X  register int next;
  1233. X
  1234. X  if (next_to_corr(y, x) > 2)
  1235. X    if ((cave[y-1][x].fval >= MIN_CAVE_WALL)
  1236. X    && (cave[y+1][x].fval >= MIN_CAVE_WALL))
  1237. X      next = TRUE;
  1238. X    else if ((cave[y][x-1].fval >= MIN_CAVE_WALL)
  1239. X         && (cave[y][x+1].fval >= MIN_CAVE_WALL))
  1240. X      next = TRUE;
  1241. X    else
  1242. X      next = FALSE;
  1243. X  else
  1244. X    next = FALSE;
  1245. X  return(next);
  1246. X}
  1247. X
  1248. X/* Places door at y, x position if at least 2 walls found    */
  1249. Xstatic void try_door(y, x)
  1250. Xregister int y, x;
  1251. X{
  1252. X  if ((cave[y][x].fval == CORR_FLOOR) && (randint(100) > DUN_TUN_JCT)
  1253. X      && next_to(y, x))
  1254. X    place_door(y, x);
  1255. X}
  1256. X
  1257. X
  1258. X/* Returns random co-ordinates                -RAK-    */
  1259. Xstatic void new_spot(y, x)
  1260. Xint16 *y, *x;
  1261. X{
  1262. X  register int i, j;
  1263. X  register cave_type *c_ptr;
  1264. X
  1265. X  do
  1266. X    {
  1267. X      i = randint(cur_height - 2);
  1268. X      j = randint(cur_width - 2);
  1269. X      c_ptr = &cave[i][j];
  1270. X    }
  1271. X  while (c_ptr->fval >= MIN_CLOSED_SPACE || (c_ptr->cptr != 0)
  1272. X     || (c_ptr->tptr != 0));
  1273. X  *y = i;
  1274. X  *x = j;
  1275. X}
  1276. X
  1277. X
  1278. X/* Cave logic flow for generation of new dungeon        */
  1279. Xstatic void cave_gen()
  1280. X{
  1281. X  struct spot_type
  1282. X    {
  1283. X      int endx;
  1284. X      int endy;
  1285. X    };
  1286. X  int room_map[20][20];
  1287. X  register int i, j, k;
  1288. X  int y1, x1, y2, x2, pick1, pick2, tmp;
  1289. X  int row_rooms, col_rooms, alloc_level;
  1290. X  int16 yloc[400], xloc[400];
  1291. X
  1292. X  row_rooms = 2*(cur_height/SCREEN_HEIGHT);
  1293. X  col_rooms = 2*(cur_width /SCREEN_WIDTH);
  1294. X  for (i = 0; i < row_rooms; i++)
  1295. X    for (j = 0; j < col_rooms; j++)
  1296. X      room_map[i][j] = FALSE;
  1297. X  k = randnor(DUN_ROO_MEA, 2);
  1298. X  for (i = 0; i < k; i++)
  1299. X    room_map[randint(row_rooms)-1][randint(col_rooms)-1] = TRUE;
  1300. X  k = 0;
  1301. X  for (i = 0; i < row_rooms; i++)
  1302. X    for (j = 0; j < col_rooms; j++)
  1303. X      if (room_map[i][j] == TRUE)
  1304. X    {
  1305. X      yloc[k] = i * (SCREEN_HEIGHT >> 1) + QUART_HEIGHT;
  1306. X      xloc[k] = j * (SCREEN_WIDTH >> 1) + QUART_WIDTH;
  1307. X      if (dun_level > randint(DUN_UNUSUAL))
  1308. X        {
  1309. X          tmp = randint(3);
  1310. X          if (tmp == 1)     build_type1(yloc[k], xloc[k]);
  1311. X          else if (tmp == 2) build_type2(yloc[k], xloc[k]);
  1312. X          else         build_type3(yloc[k], xloc[k]);
  1313. X        }
  1314. X      else
  1315. X        build_room(yloc[k], xloc[k]);
  1316. X      k++;
  1317. X#ifdef MAC
  1318. X      SystemTask ();
  1319. X#endif
  1320. X    }
  1321. X  for (i = 0; i < k; i++)
  1322. X    {
  1323. X      pick1 = randint(k) - 1;
  1324. X      pick2 = randint(k) - 1;
  1325. X      y1 = yloc[pick1];
  1326. X      x1 = xloc[pick1];
  1327. X      yloc[pick1] = yloc[pick2];
  1328. X      xloc[pick1] = xloc[pick2];
  1329. X      yloc[pick2] = y1;
  1330. X      xloc[pick2] = x1;
  1331. X      }
  1332. X  doorindex = 0;
  1333. X  /* move zero entry to k, so that can call build_tunnel all k times */
  1334. X  yloc[k] = yloc[0];
  1335. X  xloc[k] = xloc[0];
  1336. X  for (i = 0; i < k; i++)
  1337. X    {
  1338. X      y1 = yloc[i];
  1339. X      x1 = xloc[i];
  1340. X      y2 = yloc[i+1];
  1341. X      x2 = xloc[i+1];
  1342. X      build_tunnel(y2, x2, y1, x1);
  1343. X    }
  1344. X#ifdef MAC
  1345. X  SystemTask ();
  1346. X#endif
  1347. X  fill_cave(GRANITE_WALL);
  1348. X  for (i = 0; i < DUN_STR_MAG; i++)
  1349. X    place_streamer(MAGMA_WALL, DUN_STR_MC);
  1350. X  for (i = 0; i < DUN_STR_QUA; i++)
  1351. X    place_streamer(QUARTZ_WALL, DUN_STR_QC);
  1352. X  place_boundary();
  1353. X  /* Place intersection doors    */
  1354. X  for (i = 0; i < doorindex; i++)
  1355. X    {
  1356. X      try_door(doorstk[i].y, doorstk[i].x-1);
  1357. X      try_door(doorstk[i].y, doorstk[i].x+1);
  1358. X      try_door(doorstk[i].y-1, doorstk[i].x);
  1359. X      try_door(doorstk[i].y+1, doorstk[i].x);
  1360. X    }
  1361. X#ifdef MAC
  1362. X  SystemTask ();
  1363. X#endif
  1364. X  alloc_level = (dun_level/3);
  1365. X  if (alloc_level < 2)
  1366. X    alloc_level = 2;
  1367. X  else if (alloc_level > 10)
  1368. X    alloc_level = 10;
  1369. X  place_stairs(2, randint(2)+2, 3);
  1370. X  place_stairs(1, randint(2), 3);
  1371. X  /* Set up the character co-ords, used by alloc_monster, place_win_monster */
  1372. X  new_spot(&char_row, &char_col);
  1373. X  alloc_monster((randint(8)+MIN_MALLOC_LEVEL+alloc_level), 0, TRUE);
  1374. X  alloc_object(set_corr, 3, randint(alloc_level));
  1375. X  alloc_object(set_room, 5, randnor(TREAS_ROOM_ALLOC, 3));
  1376. X  alloc_object(set_floor, 5, randnor(TREAS_ANY_ALLOC, 3));
  1377. X  alloc_object(set_floor, 4, randnor(TREAS_GOLD_ALLOC, 3));
  1378. X  alloc_object(set_floor, 1, randint(alloc_level));
  1379. X  if (dun_level >= WIN_MON_APPEAR)  place_win_monster();
  1380. X}
  1381. X
  1382. X
  1383. X/* Builds a store at a row, column coordinate            */
  1384. Xstatic void build_store(store_num, y, x)
  1385. Xint store_num, y, x;
  1386. X{
  1387. X  int yval, y_height, y_depth;
  1388. X  int xval, x_left, x_right;
  1389. X  register int i, j;
  1390. X  int cur_pos, tmp;
  1391. X  register cave_type *c_ptr;
  1392. X
  1393. X  yval       = y*10 + 5;
  1394. X  xval       = x*16 + 16;
  1395. X  y_height = yval - randint(3);
  1396. X  y_depth  = yval + randint(4);
  1397. X  x_left   = xval - randint(6);
  1398. X  x_right  = xval + randint(6);
  1399. X  for (i = y_height; i <= y_depth; i++)
  1400. X    for (j = x_left; j <= x_right; j++)
  1401. X      cave[i][j].fval     = BOUNDARY_WALL;
  1402. X  tmp = randint(4);
  1403. X  if (tmp < 3)
  1404. X    {
  1405. X      i = randint(y_depth-y_height) + y_height - 1;
  1406. X      if (tmp == 1) j = x_left;
  1407. X      else        j = x_right;
  1408. X    }
  1409. X  else
  1410. X    {
  1411. X      j = randint(x_right-x_left) + x_left - 1;
  1412. X      if (tmp == 3) i = y_depth;
  1413. X      else        i = y_height;
  1414. X    }
  1415. X  c_ptr = &cave[i][j];
  1416. X  c_ptr->fval  = CORR_FLOOR;
  1417. X  cur_pos = popt();
  1418. X  c_ptr->tptr = cur_pos;
  1419. X  invcopy(&t_list[cur_pos], OBJ_STORE_DOOR + store_num);
  1420. X}
  1421. X
  1422. X
  1423. X/* Link all free space in treasure list together        */
  1424. Xstatic void tlink()
  1425. X{
  1426. X  register int i;
  1427. X
  1428. X  for (i = 0; i < MAX_TALLOC; i++)
  1429. X    invcopy(&t_list[i], OBJ_NOTHING);
  1430. X  tcptr = MIN_TRIX;
  1431. X}
  1432. X
  1433. X
  1434. X/* Link all free space in monster list together            */
  1435. Xstatic void mlink()
  1436. X{
  1437. X  register int i;
  1438. X
  1439. X  for (i = 0; i < MAX_MALLOC; i++)
  1440. X      m_list[i] = blank_monster;
  1441. X  mfptr = MIN_MONIX;
  1442. X}
  1443. X
  1444. X
  1445. X/* Town logic flow for generation of new town        */
  1446. Xstatic void town_gen()
  1447. X{
  1448. X  register int i, j, l, m;
  1449. X  register cave_type *c_ptr;
  1450. X  int rooms[6], k;
  1451. X
  1452. X  set_seed(town_seed);
  1453. X  for (i = 0; i < 6; i++)
  1454. X    rooms[i] = i;
  1455. X  l = 6;
  1456. X  for (i = 0; i < 2; i++)
  1457. X    for (j = 0; j < 3; j++)
  1458. X      {
  1459. X    k = randint(l) - 1;
  1460. X    build_store(rooms[k], i, j);
  1461. X    for (m = k; m < l-1; m++)
  1462. X      rooms[m] = rooms[m+1];
  1463. X    l--;
  1464. X      }
  1465. X  fill_cave(DARK_FLOOR);
  1466. X  /* make stairs before reset_seed, so that they don't move around */
  1467. X  place_boundary();
  1468. X  place_stairs(2, 1, 0);
  1469. X  reset_seed();
  1470. X  /* Set up the character co-ords, used by alloc_monster below */
  1471. X  new_spot(&char_row, &char_col);
  1472. X  if (0x1 & (turn / 5000))
  1473. X    {        /* Night    */
  1474. X      for (i = 0; i < cur_height; i++)
  1475. X    {
  1476. X      c_ptr = &cave[i][0];
  1477. X      for (j = 0; j < cur_width; j++)
  1478. X        {
  1479. X          if (c_ptr->fval != DARK_FLOOR)
  1480. X        c_ptr->pl = TRUE;
  1481. X          c_ptr++;
  1482. X        }
  1483. X#ifdef MAC
  1484. X      SystemTask ();
  1485. X#endif
  1486. X    }
  1487. X      alloc_monster(MIN_MALLOC_TN, 3, TRUE);
  1488. X    }
  1489. X  else
  1490. X    {        /* Day    */
  1491. X      for (i = 0; i < cur_height; i++)
  1492. X    {
  1493. X      c_ptr = &cave[i][0];
  1494. X      for (j = 0; j < cur_width; j++)
  1495. X        {
  1496. X          c_ptr->pl = TRUE;
  1497. X          c_ptr++;
  1498. X        }
  1499. X#ifdef MAC
  1500. X      SystemTask ();
  1501. X#endif
  1502. X    }
  1503. X      alloc_monster(MIN_MALLOC_TD, 3, TRUE);
  1504. X    }
  1505. X  store_maint();
  1506. X}
  1507. X
  1508. X
  1509. X/* Generates a random dungeon level            -RAK-    */
  1510. Xvoid generate_cave()
  1511. X{
  1512. X  panel_row_min    = 0;
  1513. X  panel_row_max    = 0;
  1514. X  panel_col_min    = 0;
  1515. X  panel_col_max    = 0;
  1516. X  char_row = -1;
  1517. X  char_col = -1;
  1518. X
  1519. X#ifdef MAC
  1520. X  macbeginwait ();
  1521. X#endif
  1522. X
  1523. X  tlink();
  1524. X  mlink();
  1525. X  blank_cave();
  1526. X
  1527. X  if (dun_level == 0)
  1528. X    {
  1529. X      cur_height = SCREEN_HEIGHT;
  1530. X      cur_width     = SCREEN_WIDTH;
  1531. X      max_panel_rows = (cur_height/SCREEN_HEIGHT)*2 - 2;
  1532. X      max_panel_cols = (cur_width /SCREEN_WIDTH )*2 - 2;
  1533. X      panel_row = max_panel_rows;
  1534. X      panel_col = max_panel_cols;
  1535. X      town_gen();
  1536. X    }
  1537. X  else
  1538. X    {
  1539. X      cur_height = MAX_HEIGHT;
  1540. X      cur_width     = MAX_WIDTH;
  1541. X      max_panel_rows = (cur_height/SCREEN_HEIGHT)*2 - 2;
  1542. X      max_panel_cols = (cur_width /SCREEN_WIDTH )*2 - 2;
  1543. X      panel_row = max_panel_rows;
  1544. X      panel_col = max_panel_cols;
  1545. X      cave_gen();
  1546. X    }
  1547. X#ifdef MAC
  1548. X  macendwait ();
  1549. X#endif
  1550. X}
  1551. END_OF_FILE
  1552. if test 35484 -ne `wc -c <'source/generate.c'`; then
  1553.     echo shar: \"'source/generate.c'\" unpacked with wrong size!
  1554. fi
  1555. # end of 'source/generate.c'
  1556. fi
  1557. if test -f 'source/recall.c' -a "${1}" != "-c" ; then 
  1558.   echo shar: Will not clobber existing file \"'source/recall.c'\"
  1559. else
  1560. echo shar: Extracting \"'source/recall.c'\" \(17032 characters\)
  1561. sed "s/^X//" >'source/recall.c' <<'END_OF_FILE'
  1562. X/* source/recall.c: print out monster memory info            -CJS-
  1563. X
  1564. X   Copyright (c) 1989-92 James E. Wilson, Christopher J. Stuart
  1565. X
  1566. X   This software may be copied and distributed for educational, research, and
  1567. X   not for profit purposes provided that this copyright and statement are
  1568. X   included in all such copies. */
  1569. X
  1570. X#ifdef __TURBOC__
  1571. X#include    <stdio.h>
  1572. X#endif /* __TURBOC__ */
  1573. X#include "config.h"
  1574. X#include "constant.h"
  1575. X#include "types.h"
  1576. X#include "externs.h"
  1577. X
  1578. X#if defined(LINT_ARGS)
  1579. Xstatic void roff(char *);
  1580. X#else
  1581. Xstatic void roff();
  1582. X#endif
  1583. X
  1584. Xstatic char *desc_atype[] = {
  1585. X  "do something undefined",
  1586. X  "attack",
  1587. X  "weaken",
  1588. X  "confuse",
  1589. X  "terrify",
  1590. X  "shoot flames",
  1591. X  "shoot acid",
  1592. X  "freeze",
  1593. X  "shoot lightning",
  1594. X  "corrode",
  1595. X  "blind",
  1596. X  "paralyse",
  1597. X  "steal money",
  1598. X  "steal things",
  1599. X  "poison",
  1600. X  "reduce dexterity",
  1601. X  "reduce constitution",
  1602. X  "drain intelligence",
  1603. X  "drain wisdom",
  1604. X  "lower experience",
  1605. X  "call for help",
  1606. X  "disenchant",
  1607. X  "eat your food",
  1608. X  "absorb light",
  1609. X  "absorb charges" };
  1610. Xstatic char *desc_amethod[] = {
  1611. X  "make an undefined advance",
  1612. X  "hit",
  1613. X  "bite",
  1614. X  "claw",
  1615. X  "sting",
  1616. X  "touch",
  1617. X  "kick",
  1618. X  "gaze",
  1619. X  "breathe",
  1620. X  "spit",
  1621. X  "wail",
  1622. X  "embrace",
  1623. X  "crawl on you",
  1624. X  "release spores",
  1625. X  "beg",
  1626. X  "slime you",
  1627. X  "crush",
  1628. X  "trample",
  1629. X  "drool",
  1630. X  "insult" };
  1631. Xstatic char *desc_howmuch[] = {
  1632. X  " not at all",
  1633. X  " a bit",
  1634. X  "",
  1635. X  " quite",
  1636. X  " very",
  1637. X  " most",
  1638. X  " highly",
  1639. X  " extremely" };
  1640. X
  1641. Xstatic char *desc_move[] = {
  1642. X  "move invisibly",
  1643. X  "open doors",
  1644. X  "pass through walls",
  1645. X  "kill weaker creatures",
  1646. X  "pick up objects",
  1647. X  "breed explosively" };
  1648. Xstatic char *desc_spell[] = {
  1649. X  "teleport short distances",
  1650. X  "teleport long distances",
  1651. X  "teleport its prey",
  1652. X  "cause light wounds",
  1653. X  "cause serious wounds",
  1654. X  "paralyse its prey",
  1655. X  "induce blindness",
  1656. X  "confuse",
  1657. X  "terrify",
  1658. X  "summon a monster",
  1659. X  "summon the undead",
  1660. X  "slow its prey",
  1661. X  "drain mana",
  1662. X  "unknown 1",
  1663. X  "unknown 2" };
  1664. Xstatic char *desc_breath[] = {
  1665. X  "lightning",
  1666. X  "poison gases",
  1667. X  "acid",
  1668. X  "frost",
  1669. X  "fire" };
  1670. Xstatic char *desc_weakness[] = {
  1671. X  "frost",
  1672. X  "fire",
  1673. X  "poison",
  1674. X  "acid",
  1675. X  "bright light",
  1676. X  "rock remover" };
  1677. X
  1678. Xstatic vtype roffbuf;        /* Line buffer. */
  1679. Xstatic char *roffp;        /* Pointer into line buffer. */
  1680. Xstatic int roffpline;        /* Place to print line now being loaded. */
  1681. X
  1682. X#define plural(c, ss, sp)    ((c) == 1 ? ss : sp)
  1683. X
  1684. X/* Number of kills needed for information. */
  1685. X
  1686. X/* the higher the level of the monster, the fewer the kills you need */
  1687. X#define knowarmor(l,d)        ((d) > 304 / (4 + (l)))
  1688. X/* the higher the level of the monster, the fewer the attacks you need,
  1689. X   the more damage an attack does, the more attacks you need */
  1690. X#define knowdamage(l,a,d)    ((4 + (l))*(a) > 80 * (d))
  1691. X
  1692. X/* Do we know anything about this monster? */
  1693. Xint bool_roff_recall(mon_num)
  1694. Xint mon_num;
  1695. X{
  1696. X  register recall_type *mp;
  1697. X  register int i;
  1698. X
  1699. X  if (wizard)
  1700. X    return TRUE;
  1701. X  mp = &c_recall[mon_num];
  1702. X  if (mp->r_cmove || mp->r_cdefense || mp->r_kills || mp->r_spells
  1703. X      || mp->r_deaths)
  1704. X    return TRUE;
  1705. X  for (i = 0; i < 4; i++)
  1706. X    if (mp->r_attacks[i])
  1707. X      return TRUE;
  1708. X  return FALSE;
  1709. X}
  1710. X
  1711. X/* Print out what we have discovered about this monster. */
  1712. Xint roff_recall(mon_num)
  1713. Xint mon_num;
  1714. X{
  1715. X  char *p, *q;
  1716. X  int8u *pu;
  1717. X  vtype temp;
  1718. X  register recall_type *mp;
  1719. X  register creature_type *cp;
  1720. X  register int i, k;
  1721. X  register int32u j;
  1722. X  int32 templong;
  1723. X  int mspeed;
  1724. X  int32u rcmove, rspells;
  1725. X  int16u rcdefense;
  1726. X  recall_type save_mem;
  1727. X#ifdef ATARIST_MWC
  1728. X  int32u holder;
  1729. X  int32u holder2;
  1730. X#endif
  1731. X
  1732. X  mp = &c_recall[mon_num];
  1733. X  cp = &c_list[mon_num];
  1734. X  if (wizard)
  1735. X    {
  1736. X      save_mem = *mp;
  1737. X      mp->r_kills = MAX_SHORT;
  1738. X      mp->r_wake = mp->r_ignore = MAX_UCHAR;
  1739. X#ifdef ATARIST_MWC
  1740. X      j = (((cp->cmove & (holder = CM_4D2_OBJ)) != 0) * 8) +
  1741. X    (((cp->cmove & (holder = CM_2D2_OBJ)) != 0) * 4) +
  1742. X      (((cp->cmove & (holder = CM_1D2_OBJ)) != 0) * 2) +
  1743. X        ((cp->cmove & (holder = CM_90_RANDOM)) != 0) +
  1744. X          ((cp->cmove & (holder = CM_60_RANDOM)) != 0);
  1745. X      holder = CM_TREASURE;
  1746. X      mp->r_cmove = (cp->cmove & ~holder) | (j << CM_TR_SHIFT);
  1747. X#else
  1748. X      j = (((cp->cmove & CM_4D2_OBJ) != 0) * 8) +
  1749. X    (((cp->cmove & CM_2D2_OBJ) != 0) * 4) +
  1750. X      (((cp->cmove & CM_1D2_OBJ) != 0) * 2) +
  1751. X        ((cp->cmove & CM_90_RANDOM) != 0) +
  1752. X          ((cp->cmove & CM_60_RANDOM) != 0);
  1753. X      mp->r_cmove = (cp->cmove & ~CM_TREASURE) | (j << CM_TR_SHIFT);
  1754. X#endif
  1755. X      mp->r_cdefense = cp->cdefense;
  1756. X      mp->r_spells = cp->spells | CS_FREQ;
  1757. X      j = 0;
  1758. X      pu = cp->damage;
  1759. X      while (*pu != 0 && j < 4)
  1760. X    {
  1761. X      /* Turbo C needs a 16 bit int for the array index.  */
  1762. X      mp->r_attacks[(int)j] = MAX_UCHAR;
  1763. X      j++;
  1764. X      pu++;
  1765. X    }
  1766. X      /* A little hack to enable the display of info for Quylthulgs.  */
  1767. X      if (mp->r_cmove & CM_ONLY_MAGIC)
  1768. X    mp->r_attacks[0] = MAX_UCHAR;
  1769. X    }
  1770. X  roffpline = 0;
  1771. X  roffp = roffbuf;
  1772. X#ifdef ATARIST_MWC
  1773. X  holder = ~CS_FREQ;
  1774. X  rspells = mp->r_spells & cp->spells & holder;
  1775. X  /* the CM_WIN property is always known, set it if a win monster */
  1776. X  holder = CM_WIN;
  1777. X  rcmove = mp->r_cmove | (holder & cp->cmove);
  1778. X#else
  1779. X  rspells = mp->r_spells & cp->spells & ~CS_FREQ;
  1780. X  /* the CM_WIN property is always known, set it if a win monster */
  1781. X  rcmove = mp->r_cmove | (CM_WIN & cp->cmove);
  1782. X#endif
  1783. X  rcdefense = mp->r_cdefense & cp->cdefense;
  1784. X  (void) sprintf(temp, "The %s:\n", cp->name);
  1785. X  roff(temp);
  1786. X  /* Conflict history. */
  1787. X  if(mp->r_deaths)
  1788. X    {
  1789. X      (void) sprintf(temp,
  1790. X             "%d of the contributors to your monster memory %s",
  1791. X             mp->r_deaths, plural(mp->r_deaths, "has", "have") );
  1792. X      roff(temp);
  1793. X      roff(" been killed by this creature, and ");
  1794. X      if (mp->r_kills == 0)
  1795. X    roff("it is not ever known to have been defeated.");
  1796. X      else
  1797. X    {
  1798. X      (void) sprintf(temp,
  1799. X             "at least %d of the beasts %s been exterminated.",
  1800. X             mp->r_kills, plural(mp->r_kills, "has", "have") );
  1801. X      roff(temp);
  1802. X    }
  1803. X    }
  1804. X  else if (mp->r_kills)
  1805. X    {
  1806. X      (void) sprintf(temp, "At least %d of these creatures %s",
  1807. X             mp->r_kills, plural(mp->r_kills, "has", "have") );
  1808. X      roff(temp);
  1809. X      roff(" been killed by contributors to your monster memory.");
  1810. X    }
  1811. X  else
  1812. X    roff("No known battles to the death are recalled.");
  1813. X  /* Immediately obvious. */
  1814. X  k = FALSE;
  1815. X  if (cp->level == 0)
  1816. X    {
  1817. X      roff(" It lives in the town");
  1818. X      k = TRUE;
  1819. X    }
  1820. X  else if (mp->r_kills)
  1821. X    {
  1822. X      /* The Balrog is a level 100 monster, but appears at 50 feet.  */
  1823. X      i = cp->level;
  1824. X      if (i > WIN_MON_APPEAR)
  1825. X    i = WIN_MON_APPEAR;
  1826. X      (void) sprintf(temp, " It is normally found at depths of %d feet",
  1827. X             i * 50);
  1828. X      roff(temp);
  1829. X      k = TRUE;
  1830. X    }
  1831. X  /* the c_list speed value is 10 greater, so that it can be a int8u */
  1832. X  mspeed = cp->speed - 10;
  1833. X  if (rcmove & CM_ALL_MV_FLAGS)
  1834. X    {
  1835. X      if (k)
  1836. X    roff(", and");
  1837. X      else
  1838. X    {
  1839. X      roff(" It");
  1840. X      k = TRUE;
  1841. X    }
  1842. X      roff(" moves");
  1843. X      if (rcmove & CM_RANDOM_MOVE)
  1844. X    {
  1845. X      /* Turbo C needs a 16 bit int for the array index.  */
  1846. X      roff(desc_howmuch[(int)((rcmove & CM_RANDOM_MOVE) >> 3)]);
  1847. X      roff(" erratically");
  1848. X    }
  1849. X      if (mspeed == 1)
  1850. X    roff(" at normal speed");
  1851. X      else
  1852. X    {
  1853. X      if (rcmove & CM_RANDOM_MOVE)
  1854. X        roff(", and");
  1855. X      if (mspeed <= 0)
  1856. X        {
  1857. X          if (mspeed == -1)
  1858. X        roff(" very");
  1859. X          else if (mspeed < -1)
  1860. X        roff(" incredibly");
  1861. X          roff(" slowly");
  1862. X        }
  1863. X      else
  1864. X        {
  1865. X          if (mspeed == 3)
  1866. X        roff(" very");
  1867. X          else if (mspeed > 3)
  1868. X        roff(" unbelievably");
  1869. X          roff(" quickly");
  1870. X        }
  1871. X    }
  1872. X    }
  1873. X  if (rcmove & CM_ATTACK_ONLY)
  1874. X    {
  1875. X      if(k)
  1876. X    roff(", but");
  1877. X      else
  1878. X    {
  1879. X      roff(" It");
  1880. X      k = TRUE;
  1881. X    }
  1882. X      roff(" does not deign to chase intruders");
  1883. X    }
  1884. X  if (rcmove & CM_ONLY_MAGIC)
  1885. X    {
  1886. X      if (k)
  1887. X    roff (", but");
  1888. X      else
  1889. X    {
  1890. X      roff (" It");
  1891. X      k = TRUE;
  1892. X    }
  1893. X      roff (" always moves and attacks by using magic");
  1894. X    }
  1895. X  if(k)
  1896. X    roff(".");
  1897. X  /* Kill it once to know experience, and quality (evil, undead, monsterous).
  1898. X     The quality of being a dragon is obvious. */
  1899. X  if (mp->r_kills)
  1900. X    {
  1901. X      roff(" A kill of this");
  1902. X      if (cp->cdefense & CD_ANIMAL)
  1903. X    roff(" natural");
  1904. X      if (cp->cdefense & CD_EVIL)
  1905. X    roff(" evil");
  1906. X      if (cp->cdefense & CD_UNDEAD)
  1907. X    roff(" undead");
  1908. X
  1909. X      /* calculate the integer exp part, can be larger than 64K when first
  1910. X     level character looks at Balrog info, so must store in long */
  1911. X      templong = (long)cp->mexp * cp->level / py.misc.lev;
  1912. X      /* calculate the fractional exp part scaled by 100,
  1913. X     must use long arithmetic to avoid overflow */
  1914. X      j = (((long)cp->mexp * cp->level % py.misc.lev) * (long)1000 /
  1915. X       py.misc.lev+5) / 10;
  1916. X
  1917. X      (void) sprintf(temp, " creature is worth %ld.%02ld point%s", templong,
  1918. X             j, (templong == 1 && j == 0 ? "" : "s"));
  1919. X      roff(temp);
  1920. X
  1921. X      if (py.misc.lev / 10 == 1) p = "th";
  1922. X      else
  1923. X    {
  1924. X      i = py.misc.lev % 10;
  1925. X      if (i == 1)        p = "st";
  1926. X      else if (i == 2)    p = "nd";
  1927. X      else if (i == 3)      p = "rd";
  1928. X      else            p = "th";
  1929. X    }
  1930. X      i = py.misc.lev;
  1931. X      if (i == 8 || i == 11 || i == 18) q = "n";
  1932. X      else                q = "";
  1933. X      (void) sprintf(temp, " for a%s %d%s level character.", q, i, p);
  1934. X      roff(temp);
  1935. X    }
  1936. X  /* Spells known, if have been used against us. */
  1937. X  k = TRUE;
  1938. X  j = rspells;
  1939. X#ifdef ATARIST_MWC
  1940. X  holder = CS_BREATHE;
  1941. X  holder2 = CS_BR_LIGHT;
  1942. X  for (i = 0; j & holder; i++)
  1943. X#else
  1944. X  for (i = 0; j & CS_BREATHE; i++)
  1945. X#endif
  1946. X    {
  1947. X#ifdef ATARIST_MWC
  1948. X      if (j & (holder2 << i))
  1949. X#else
  1950. X      if (j & (CS_BR_LIGHT << i))
  1951. X#endif
  1952. X    {
  1953. X#ifdef ATARIST_MWC
  1954. X      j &= ~(holder2 << i);
  1955. X#else
  1956. X      j &= ~(CS_BR_LIGHT << i);
  1957. X#endif
  1958. X      if (k)
  1959. X        {
  1960. X          roff(" It can breathe ");
  1961. X          k = FALSE;
  1962. X        }
  1963. X#ifdef ATARIST_MWC
  1964. X      else if (j & holder)
  1965. X#else
  1966. X      else if (j & CS_BREATHE)
  1967. X#endif
  1968. X        roff(", ");
  1969. X      else
  1970. X        roff(" and ");
  1971. X      roff(desc_breath[i]);
  1972. X    }
  1973. X    }
  1974. X  k = TRUE;
  1975. X#ifdef ATARIST_MWC
  1976. X  holder = CS_SPELLS;
  1977. X  for (i = 0; j & holder; i++)
  1978. X#else
  1979. X  for (i = 0; j & CS_SPELLS; i++)
  1980. X#endif
  1981. X    {
  1982. X      if (j & (CS_TEL_SHORT << i))
  1983. X    {
  1984. X      j &= ~(CS_TEL_SHORT << i);
  1985. X      if (k)
  1986. X        {
  1987. X#ifdef ATARIST_MWC
  1988. X          holder2 = CS_BREATHE;
  1989. X          if (rspells & holder2)
  1990. X#else
  1991. X          if (rspells & CS_BREATHE)
  1992. X#endif
  1993. X        roff(", and is also");
  1994. X          else
  1995. X        roff(" It is");
  1996. X          roff(" magical, casting spells which ");
  1997. X          k = FALSE;
  1998. X        }
  1999. X#ifdef ATARIST_MWC
  2000. X      else if (j & holder)
  2001. X#else
  2002. X      else if (j & CS_SPELLS)
  2003. X#endif
  2004. X        roff(", ");
  2005. X      else
  2006. X        roff(" or ");
  2007. X      roff(desc_spell[i]);
  2008. X    }
  2009. X    }
  2010. X#ifdef ATARIST_MWC
  2011. X  holder = CS_BREATHE|CS_SPELLS;
  2012. X  if (rspells & holder)
  2013. X#else
  2014. X  if (rspells & (CS_BREATHE|CS_SPELLS))
  2015. X#endif
  2016. X    {
  2017. X      if ((mp->r_spells & CS_FREQ) > 5)
  2018. X    {    /* Could offset by level */
  2019. X      (void) sprintf(temp, "; 1 time in %ld", cp->spells & CS_FREQ);
  2020. X      roff(temp);
  2021. X    }
  2022. X      roff(".");
  2023. X    }
  2024. X  /* Do we know how hard they are to kill? Armor class, hit die. */
  2025. X  if (knowarmor(cp->level, mp->r_kills))
  2026. X    {
  2027. X      (void) sprintf(temp, " It has an armor rating of %d", cp->ac);
  2028. X      roff(temp);
  2029. X      (void) sprintf(temp, " and a%s life rating of %dd%d.",
  2030. X             ((cp->cdefense & CD_MAX_HP) ? " maximized" : ""),
  2031. X             cp->hd[0], cp->hd[1]);
  2032. X      roff(temp);
  2033. X    }
  2034. X  /* Do we know how clever they are? Special abilities. */
  2035. X  k = TRUE;
  2036. X  j = rcmove;
  2037. X#ifdef ATARIST_MWC
  2038. X  holder = CM_SPECIAL;
  2039. X  holder2 = CM_INVISIBLE;
  2040. X  for (i = 0; j & holder; i++)
  2041. X#else
  2042. X  for (i = 0; j & CM_SPECIAL; i++)
  2043. X#endif
  2044. X    {
  2045. X#ifdef ATARIST_MWC
  2046. X      if (j & (holder2 << i))
  2047. X#else
  2048. X      if (j & (CM_INVISIBLE << i))
  2049. X#endif
  2050. X    {
  2051. X#ifdef ATARIST_MWC
  2052. X      j &= ~(holder2 << i);
  2053. X#else
  2054. X      j &= ~(CM_INVISIBLE << i);
  2055. X#endif
  2056. X      if (k)
  2057. X        {
  2058. X          roff(" It can ");
  2059. X          k = FALSE;
  2060. X        }
  2061. X#ifdef ATARIST_MWC
  2062. X      else if (j & holder)
  2063. X#else
  2064. X      else if (j & CM_SPECIAL)
  2065. X#endif
  2066. X        roff(", ");
  2067. X      else
  2068. X        roff(" and ");
  2069. X      roff(desc_move[i]);
  2070. X    }
  2071. X    }
  2072. X  if (!k)
  2073. X    roff(".");
  2074. X  /* Do we know its special weaknesses? Most cdefense flags. */
  2075. X  k = TRUE;
  2076. X  j = rcdefense;
  2077. X  for (i = 0; j & CD_WEAKNESS; i++)
  2078. X    {
  2079. X      if (j & (CD_FROST << i))
  2080. X    {
  2081. X      j &= ~(CD_FROST << i);
  2082. X      if (k)
  2083. X        {
  2084. X          roff(" It is susceptible to ");
  2085. X          k = FALSE;
  2086. X        }
  2087. X      else if (j & CD_WEAKNESS)
  2088. X        roff(", ");
  2089. X      else
  2090. X        roff(" and ");
  2091. X      roff(desc_weakness[i]);
  2092. X    }
  2093. X    }
  2094. X  if (!k)
  2095. X    roff(".");
  2096. X  if (rcdefense & CD_INFRA)
  2097. X    roff(" It is warm blooded");
  2098. X  if (rcdefense & CD_NO_SLEEP)
  2099. X    {
  2100. X      if (rcdefense & CD_INFRA)
  2101. X    roff(", and");
  2102. X      else
  2103. X    roff(" It");
  2104. X      roff(" cannot be charmed or slept");
  2105. X    }
  2106. X  if (rcdefense & (CD_NO_SLEEP|CD_INFRA))
  2107. X    roff(".");
  2108. X  /* Do we know how aware it is? */
  2109. X  if (((mp->r_wake * mp->r_wake) > cp->sleep) || mp->r_ignore == MAX_UCHAR ||
  2110. X      (cp->sleep == 0 && mp->r_kills >= 10))
  2111. X    {
  2112. X      roff(" It ");
  2113. X      if(cp->sleep > 200)
  2114. X    roff("prefers to ignore");
  2115. X      else if(cp->sleep > 95)
  2116. X    roff("pays very little attention to");
  2117. X      else if(cp->sleep > 75)
  2118. X    roff("pays little attention to");
  2119. X      else if(cp->sleep > 45)
  2120. X    roff("tends to overlook");
  2121. X      else if(cp->sleep > 25)
  2122. X    roff("takes quite a while to see");
  2123. X      else if(cp->sleep > 10)
  2124. X    roff("takes a while to see");
  2125. X      else if(cp->sleep > 5)
  2126. X    roff("is fairly observant of");
  2127. X      else if(cp->sleep > 3)
  2128. X    roff("is observant of");
  2129. X      else if(cp->sleep > 1)
  2130. X    roff("is very observant of");
  2131. X      else if(cp->sleep != 0)
  2132. X    roff("is vigilant for");
  2133. X      else
  2134. X    roff("is ever vigilant for");
  2135. X      (void) sprintf(temp, " intruders, which it may notice from %d feet.",
  2136. X             10 * cp->aaf);
  2137. X      roff(temp);
  2138. X    }
  2139. X  /* Do we know what it might carry? */
  2140. X#ifdef ATARIST_MWC
  2141. X  holder = CM_CARRY_OBJ|CM_CARRY_BOLD;
  2142. X  if (rcmove & holder)
  2143. X#else
  2144. X  if (rcmove & (CM_CARRY_OBJ|CM_CARRY_GOLD))
  2145. X#endif
  2146. X    {
  2147. X      roff(" It may");
  2148. X#ifdef ATARIST_MWC
  2149. X      j = (rcmove & (holder = CM_TREASURE)) >> CM_TR_SHIFT;
  2150. X#else
  2151. X      j = (rcmove & CM_TREASURE) >> CM_TR_SHIFT;
  2152. X#endif
  2153. X      if (j == 1)
  2154. X    {
  2155. X#ifdef ATARIST_MWC
  2156. X      if ((cp->cmove & (holder = CM_TREASURE)) == CM_60_RANDOM)
  2157. X#else
  2158. X      if ((cp->cmove & CM_TREASURE) == CM_60_RANDOM)
  2159. X#endif
  2160. X        roff(" sometimes");
  2161. X      else
  2162. X        roff(" often");
  2163. X    }
  2164. X#ifdef ATARIST_MWC
  2165. X      else if ((j == 2) && ((cp->cmove & (holder = CM_TREASURE)) ==
  2166. X#else
  2167. X      else if ((j == 2) && ((cp->cmove & CM_TREASURE) ==
  2168. X#endif
  2169. X                (CM_60_RANDOM|CM_90_RANDOM)))
  2170. X    roff (" often");
  2171. X      roff(" carry");
  2172. X      p = " objects";
  2173. X      if (j == 1)
  2174. X    p = " an object";
  2175. X      else if (j == 2)
  2176. X    roff(" one or two");
  2177. X      else
  2178. X    {
  2179. X      (void) sprintf(temp, " up to %ld", j);
  2180. X      roff(temp);
  2181. X    }
  2182. X#ifdef ATARIST_MWC
  2183. X      if (rcmove & (holder = CM_CARRY_OBJ))
  2184. X#else
  2185. X      if (rcmove & CM_CARRY_OBJ)
  2186. X#endif
  2187. X    {
  2188. X      roff(p);
  2189. X#ifdef ATARIST_MWC
  2190. X      if (rcmove & (holder = CM_CARRY_GOLD))
  2191. X#else
  2192. X      if (rcmove & CM_CARRY_GOLD)
  2193. X#endif
  2194. X        {
  2195. X          roff(" or treasure");
  2196. X          if (j > 1)
  2197. X        roff("s");
  2198. X        }
  2199. X      roff(".");
  2200. X    }
  2201. X      else if (j != 1)
  2202. X    roff(" treasures.");
  2203. X      else
  2204. X    roff(" treasure.");
  2205. X    }
  2206. X
  2207. X  /* We know about attacks it has used on us, and maybe the damage they do. */
  2208. X  /* k is the total number of known attacks, used for punctuation */
  2209. X  k = 0;
  2210. X  for (j = 0; j < 4; j++)
  2211. X    /* Turbo C needs a 16 bit int for the array index.  */
  2212. X    if (mp->r_attacks[(int)j])
  2213. X      k++;
  2214. X  pu = cp->damage;
  2215. X  /* j counts the attacks as printed, used for punctuation */
  2216. X  j = 0;
  2217. X  for (i = 0; *pu != 0 && i < 4; pu++, i++)
  2218. X    {
  2219. X      int att_type, att_how, d1, d2;
  2220. X
  2221. X      /* don't print out unknown attacks */
  2222. X      if (!mp->r_attacks[i])
  2223. X    continue;
  2224. X
  2225. X      att_type = monster_attacks[*pu].attack_type;
  2226. X      att_how = monster_attacks[*pu].attack_desc;
  2227. X      d1 = monster_attacks[*pu].attack_dice;
  2228. X      d2 = monster_attacks[*pu].attack_sides;
  2229. X
  2230. X      j++;
  2231. X      if (j == 1)
  2232. X    roff(" It can ");
  2233. X      else if (j == k)
  2234. X    roff(", and ");
  2235. X      else
  2236. X    roff(", ");
  2237. X
  2238. X      if (att_how > 19)
  2239. X    att_how = 0;
  2240. X      roff(desc_amethod[att_how]);
  2241. X      if (att_type != 1 || d1 > 0 && d2 > 0)
  2242. X    {
  2243. X      roff(" to ");
  2244. X      if (att_type > 24)
  2245. X        att_type = 0;
  2246. X      roff(desc_atype[att_type]);
  2247. X      if (d1 && d2)
  2248. X        {
  2249. X          if (knowdamage(cp->level, mp->r_attacks[i], d1*d2))
  2250. X        {
  2251. X          if (att_type == 19)    /* Loss of experience */
  2252. X            roff(" by");
  2253. X          else
  2254. X            roff(" with damage");
  2255. X          (void) sprintf(temp, " %dd%d", d1, d2 );
  2256. X          roff(temp);
  2257. X        }
  2258. X        }
  2259. X    }
  2260. X    }
  2261. X  if (j)
  2262. X    roff(".");
  2263. X  else if (k > 0 && mp->r_attacks[0] >= 10)
  2264. X    roff(" It has no physical attacks.");
  2265. X  else
  2266. X    roff(" Nothing is known about its attack.");
  2267. X  /* Always know the win creature. */
  2268. X#ifdef ATARIST_MWC
  2269. X  if (cp->cmove & (holder = CM_WIN))
  2270. X#else
  2271. X  if (cp->cmove & CM_WIN)
  2272. X#endif
  2273. X    roff(" Killing one of these wins the game!");
  2274. X  roff("\n");
  2275. X  prt("--pause--", roffpline, 0);
  2276. X  if (wizard)
  2277. X    *mp = save_mem;
  2278. X  return inkey();
  2279. X}
  2280. X
  2281. X/* Print out strings, filling up lines as we go. */
  2282. Xstatic void roff(p)
  2283. Xregister char *p;
  2284. X{
  2285. X  register char *q, *r;
  2286. X
  2287. X  while (*p)
  2288. X    {
  2289. X      *roffp = *p;
  2290. X      if (*p == '\n' || roffp >= roffbuf + sizeof(roffbuf)-1)
  2291. X    {
  2292. X      q = roffp;
  2293. X      if (*p != '\n')
  2294. X        while (*q != ' ')
  2295. X          q--;
  2296. X      *q = 0;
  2297. X      prt(roffbuf, roffpline, 0);
  2298. X      roffpline++;
  2299. X      r = roffbuf;
  2300. X      while (q < roffp)
  2301. X        {
  2302. X          q++;
  2303. X          *r = *q;
  2304. X          r++;
  2305. X        }
  2306. X      roffp = r;
  2307. X    }
  2308. X      else
  2309. X    roffp++;
  2310. X      p++;
  2311. X    }
  2312. X}
  2313. END_OF_FILE
  2314. if test 17032 -ne `wc -c <'source/recall.c'`; then
  2315.     echo shar: \"'source/recall.c'\" unpacked with wrong size!
  2316. fi
  2317. # end of 'source/recall.c'
  2318. fi
  2319. echo shar: End of archive 14 \(of 39\).
  2320. cp /dev/null ark14isdone
  2321. MISSING=""
  2322. 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
  2323.     if test ! -f ark${I}isdone ; then
  2324.     MISSING="${MISSING} ${I}"
  2325.     fi
  2326. done
  2327. if test "${MISSING}" = "" ; then
  2328.     echo You have unpacked all 39 archives.
  2329.     echo "Now run "bldfiles.sh" to build split files"
  2330.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2331. else
  2332.     echo You still need to unpack the following archives:
  2333.     echo "        " ${MISSING}
  2334. fi
  2335. ##  End of shell archive.
  2336. exit 0
  2337.