home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume7 / nethack3 / part20 < prev    next >
Internet Message Format  |  1989-07-31  |  56KB

  1. Path: uunet!zephyr.ens.tek.com!tektronix!tekgen!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v07i075:  NetHack3 -  display oriented dungeons & dragons (Ver. 3.0), Part20/38
  5. Message-ID: <4332@tekred.CNA.TEK.COM>
  6. Date: 24 Jul 89 19:03:03 GMT
  7. Sender: nobody@tekred.CNA.TEK.COM
  8. Lines: 2375
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
  12. Posting-number: Volume 7, Issue 75
  13. Archive-name: NetHack3/Part20
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 20 (of 38)."
  24. # Contents:  include/attrib.h src/lev_comp.y src/mklev.c
  25. # Wrapped by billr@saab on Sun Jul 23 21:33:03 1989
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'include/attrib.h' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'include/attrib.h'\"
  29. else
  30. echo shar: Extracting \"'include/attrib.h'\" \(786 characters\)
  31. sed "s/^X//" >'include/attrib.h' <<'END_OF_FILE'
  32. X/*
  33. X *    attrib.h - Header file for character class processing.
  34. X *
  35. X *    Copyright 1988, M. Stephenson
  36. X */
  37. X/* NetHack may be freely redistributed.  See license for details. */
  38. X
  39. X#ifndef ATTRIB_H
  40. X#define ATTRIB_H
  41. X
  42. X#define    A_STR    0
  43. X#define    A_INT    1
  44. X#define    A_WIS    2
  45. X#define    A_DEX    3
  46. X#define    A_CON    4
  47. X#define    A_CHA    5
  48. X
  49. X#define A_MAX    6    /* used in rn2() selection of attrib */
  50. X
  51. X#define    ABASE(x)    (u.acurr.a[x])
  52. X#define ABON(x)        (u.abon.a[x])
  53. X#define ACURR(x)    (schar) acurr(x)
  54. X/* should be: */
  55. X/* #define    ACURR(x)    (ABON(x) + ATEMP(x) + (u.umonnum == -1) ? ABASE(x) : MBASE(x)) */
  56. X#define    MCURR(x)    (u.macurr.a[x])
  57. X#define    AMAX(x)        (u.amax.a[x])
  58. X#define    MMAX(x)        (u.mamax.a[x])
  59. X
  60. X#define    ATEMP(x)    (u.atemp.a[x])
  61. X#define    ATIME(x)    (u.atime.a[x])
  62. X
  63. Xstruct    attribs {
  64. X
  65. X    schar    a[A_MAX];
  66. X};
  67. X
  68. X#endif /* ATTRIB_H /* */
  69. END_OF_FILE
  70. if test 786 -ne `wc -c <'include/attrib.h'`; then
  71.     echo shar: \"'include/attrib.h'\" unpacked with wrong size!
  72. fi
  73. # end of 'include/attrib.h'
  74. fi
  75. if test -f 'src/lev_comp.y' -a "${1}" != "-c" ; then 
  76.   echo shar: Will not clobber existing file \"'src/lev_comp.y'\"
  77. else
  78. echo shar: Extracting \"'src/lev_comp.y'\" \(23359 characters\)
  79. sed "s/^X//" >'src/lev_comp.y' <<'END_OF_FILE'
  80. X%{ 
  81. X/*    SCCS Id: @(#)lev_comp.c    3.0    89/07/02
  82. X/*    Copyright (c) 1989 by Jean-Christophe Collet */
  83. X/* NetHack may be freely redistributed.  See license for details. */
  84. X
  85. X/*
  86. X * This file contains the Level Compiler code
  87. X * It may handle special mazes & special room-levels
  88. X */
  89. X
  90. X/* block some unused #defines to avoid overloading some cpp's */
  91. X#define MONDATA_H
  92. X#include "hack.h"
  93. X#include "sp_lev.h"
  94. X#include <fcntl.h>
  95. X
  96. X#ifdef AMIGA
  97. Xchar *fgets();
  98. X# define    alloc   malloc
  99. X# undef     fopen
  100. X# undef     printf
  101. X# undef     Printf
  102. X# define    Printf  printf
  103. X# define    memset(addr,val,len)    setmem(addr,len,val)
  104. X#endif
  105. X
  106. X#ifdef MSDOS
  107. X# undef exit
  108. X#endif
  109. X
  110. X#define MAX_REGISTERS    10
  111. X#define ERR        (-1)
  112. X
  113. Xstruct reg {
  114. X    int x1, y1;
  115. X    int x2, y2;
  116. X}        current_region;
  117. X
  118. Xstruct coord {
  119. X    int x;
  120. X    int y;
  121. X}        current_coord;
  122. X
  123. Xstruct {
  124. X    char *name;
  125. X    short type;
  126. X} trap_types[TRAPNUM-1] = {
  127. X    "monster",    MONST_TRAP,
  128. X    "statue",    STATUE_TRAP,
  129. X    "bear",        BEAR_TRAP,
  130. X    "arrow",    ARROW_TRAP,
  131. X    "dart",        DART_TRAP,
  132. X    "trapdoor",    TRAPDOOR,
  133. X    "teleport",    TELEP_TRAP,
  134. X    "pit",        PIT,
  135. X    "sleeping gas",    SLP_GAS_TRAP,
  136. X    "magic",    MGTRP,
  137. X    "board",    SQBRD,
  138. X    "web",        WEB,
  139. X    "spiked pit",    SPIKED_PIT,
  140. X    "level teleport",LEVEL_TELEP,
  141. X#ifdef SPELLS
  142. X    "anti magic",    ANTI_MAGIC,
  143. X#endif
  144. X    "rust",        RUST_TRAP
  145. X#ifdef POLYSELF
  146. X    , "polymorph",    POLY_TRAP
  147. X#endif
  148. X#ifdef ARMY
  149. X    , "land mine",    LANDMINE
  150. X#endif
  151. X  };
  152. X
  153. Xstruct {
  154. X    char *name;
  155. X    int type;
  156. X} room_types[SHOPBASE-1] = {
  157. X    /* for historical reasons, room types are not contiguous numbers */
  158. X    /* (type 1 is skipped) */
  159. X    "ordinary",    OROOM,
  160. X#ifdef THRONES
  161. X    "throne",    COURT,
  162. X#endif
  163. X    "swamp",    SWAMP,
  164. X    "vault",    VAULT,
  165. X    "beehive",    BEEHIVE,
  166. X    "morgue",    MORGUE,
  167. X#ifdef ARMY
  168. X    "barracks",    BARRACKS,
  169. X#endif
  170. X    "zoo",        ZOO,
  171. X    "temple",    TEMPLE,
  172. X    "shop",        SHOPBASE,
  173. X};
  174. X
  175. Xshort db_dirs[4] = {
  176. X    DB_NORTH,
  177. X    DB_EAST,
  178. X    DB_SOUTH,
  179. X    DB_WEST
  180. X};
  181. X
  182. X#ifdef ALTARS
  183. Xstatic altar *tmpaltar[256];
  184. X#endif /* ALTARS /**/
  185. Xstatic lad *tmplad[256];
  186. Xstatic dig *tmpdig[256];
  187. Xstatic char *tmpmap[ROWNO];
  188. Xstatic region *tmpreg[16];
  189. Xstatic door *tmpdoor[256];
  190. Xstatic trap *tmptrap[256];
  191. Xstatic monster *tmpmonst[256];
  192. Xstatic object *tmpobj[256];
  193. Xstatic drawbridge *tmpdb[256];
  194. Xstatic walk *tmpwalk[256];
  195. Xstatic mazepart *tmppart[10];
  196. Xstatic room *tmproom[MAXNROFROOMS];
  197. Xstatic specialmaze maze;
  198. X
  199. Xstatic char olist[MAX_REGISTERS], mlist[MAX_REGISTERS];
  200. Xstatic struct coord plist[MAX_REGISTERS];
  201. Xstatic int n_olist = 0, n_mlist = 0, n_plist = 0;
  202. X
  203. Xunsigned int nreg = 0, ndoor = 0, ntrap = 0, nmons = 0, nobj = 0;
  204. Xunsigned int ndb = 0, nwalk = 0, npart = 0, ndig = 0, nlad = 0;
  205. X#ifdef ALTARS
  206. Xunsigned int naltar = 0;
  207. X#endif /* ALTARS /*/
  208. X
  209. Xunsigned int max_x_map, max_y_map;
  210. X
  211. Xextern int fatal_error;
  212. Xextern char* fname;
  213. X
  214. Xboolean check_monster_char(), check_object_char();
  215. Xvoid scan_map(), store_part(), write_maze();
  216. X
  217. X%}
  218. X
  219. X%union
  220. X{
  221. X    int    i;
  222. X    char*    map;
  223. X}
  224. X
  225. X
  226. X%token    <i> CHAR INTEGER
  227. X%token    <i> MAZE_ID LEVEL_ID GEOMETRY_ID
  228. X%token    <i> OBJECT_ID MONSTER_ID TRAP_ID DOOR_ID DRAWBRIDGE_ID MAZEWALK_ID
  229. X%token    <i> REGION_ID RANDOM_OBJECTS_ID RANDOM_MONSTERS_ID RANDOM_PLACES_ID
  230. X%token    <i> ALTAR_ID LADDER_ID NON_DIGGABLE_ID ROOM_ID 
  231. X%token    <i> DOOR_STATE LIGHT_STATE
  232. X%token    <i> DIRECTION RANDOM_TYPE O_REGISTER M_REGISTER P_REGISTER A_REGISTER
  233. X%token    <i> ALIGNMENT LEFT_OR_RIGHT CENTER TOP_OR_BOT ALTAR_TYPE UP_OR_DOWN
  234. X%token  <i> ',' ':' '(' ')' '[' ']'
  235. X%token    <map> STRING MAP_ID
  236. X%type    <map> string maze_def m_name o_name
  237. X%start    file
  238. X
  239. X%%
  240. Xfile        : /* notthing */
  241. X        | levels ;
  242. X
  243. Xlevels        : level
  244. X        | levels level ;
  245. X
  246. Xlevel        : maze_level ;
  247. X
  248. Xmaze_level    : maze_def regions
  249. X          {
  250. X              int fout, i;
  251. X
  252. X              if (fatal_error > 0)
  253. X                  fprintf(stderr,"%s : %d errors detected. No output created!\n", fname, fatal_error);
  254. X              else {
  255. X                  fout = open($1, O_WRONLY | O_CREAT
  256. X#ifdef MSDOS
  257. X                          | O_BINARY
  258. X#endif /* MSDOS */
  259. X                          , 0644);
  260. X                  if (fout < 0) {
  261. X                      yyerror("Can't open output file!!");
  262. X                      exit(1);
  263. X                  }
  264. X                  maze.numpart = npart;
  265. X                  maze.parts = (mazepart**) alloc(sizeof(mazepart*)*npart);
  266. X                  for(i=0;i<npart;i++)
  267. X                      maze.parts[i] = tmppart[i];
  268. X                  write_maze(fout, &maze);
  269. X                  (void) close(fout);
  270. X                  npart = 0;
  271. X              }
  272. X          }
  273. X
  274. Xmaze_def    : MAZE_ID ':' string
  275. X          {
  276. X              $$ = $3;
  277. X          }
  278. X
  279. Xregions        : aregion
  280. X        | regions aregion;
  281. X
  282. Xaregion        : map_definition reg_init map_details
  283. X          {
  284. X            store_part();
  285. X          }
  286. X
  287. Xmap_definition    : map_geometry MAP_ID
  288. X          {
  289. X            tmppart[npart] = (mazepart *) alloc(sizeof(mazepart));
  290. X            tmppart[npart]->halign = $<i>1 % 10;
  291. X            tmppart[npart]->valign = $<i>1 / 10;
  292. X            tmppart[npart]->nrobjects = 0;
  293. X            tmppart[npart]->nloc = 0;
  294. X            tmppart[npart]->nrmonst = 0;
  295. X            scan_map($2);
  296. X          }
  297. X
  298. Xmap_geometry    : GEOMETRY_ID ':' h_justif ',' v_justif
  299. X          {
  300. X              $<i>$ = $<i>3 + ( $<i>5 * 10 );
  301. X          }
  302. X
  303. Xh_justif    : LEFT_OR_RIGHT
  304. X        | CENTER ;
  305. X
  306. Xv_justif    : TOP_OR_BOT
  307. X        | CENTER ;
  308. X
  309. Xreg_init    : /* nothing */
  310. X        | reg_init init_reg ;
  311. X
  312. Xinit_reg    : RANDOM_OBJECTS_ID ':' object_list
  313. X          {
  314. X              if (tmppart[npart]->nrobjects)
  315. X                  yyerror("Object registers already initialized!");
  316. X              else {
  317. X                  tmppart[npart]->robjects = (char *) alloc(n_olist);
  318. X                  memcpy(tmppart[npart]->robjects, olist, n_olist);
  319. X                  tmppart[npart]->nrobjects = n_olist;
  320. X              }
  321. X          }
  322. X        | RANDOM_PLACES_ID ':' place_list
  323. X          {
  324. X              if (tmppart[npart]->nloc)
  325. X                  yyerror("Location registers already initialized!");
  326. X              else {
  327. X                  register int i;
  328. X                  tmppart[npart]->rloc_x = (char *) alloc(n_plist);
  329. X                  tmppart[npart]->rloc_y = (char *) alloc(n_plist);
  330. X                  for(i=0;i<n_plist;i++) {
  331. X                      tmppart[npart]->rloc_x[i] = plist[i].x;
  332. X                      tmppart[npart]->rloc_y[i] = plist[i].y;
  333. X                  }
  334. X                  tmppart[npart]->nloc = n_plist;
  335. X              }
  336. X          }
  337. X        | RANDOM_MONSTERS_ID ':' monster_list
  338. X          {
  339. X              if (tmppart[npart]->nrmonst)
  340. X                  yyerror("Monster registers already initialized!");
  341. X              else {
  342. X                  tmppart[npart]->rmonst = (char *) alloc(n_mlist);
  343. X                  memcpy(tmppart[npart]->rmonst, mlist, n_mlist);
  344. X                  tmppart[npart]->nrmonst = n_mlist;
  345. X              }
  346. X          }
  347. X
  348. Xobject_list    : object
  349. X          {
  350. X              if (n_olist < MAX_REGISTERS)
  351. X                  olist[n_olist++] = $<i>1;
  352. X              else
  353. X                  yyerror("Object list too long!");
  354. X          }
  355. X        | object_list ',' object
  356. X          {
  357. X              if (n_olist < MAX_REGISTERS)
  358. X                  olist[n_olist++] = $<i>3;
  359. X              else
  360. X                  yyerror("Object list too long!");
  361. X          }
  362. X
  363. Xmonster_list    : monster
  364. X          {
  365. X              if (n_mlist < MAX_REGISTERS)
  366. X                  mlist[n_mlist++] = $<i>1;
  367. X              else
  368. X                  yyerror("Monster list too long!");
  369. X          }
  370. X        | monster_list ',' monster
  371. X          {
  372. X              if (n_mlist < MAX_REGISTERS)
  373. X                  mlist[n_mlist++] = $<i>3;
  374. X              else
  375. X                  yyerror("Monster list too long!");
  376. X          }
  377. X
  378. Xplace_list    : place
  379. X          {
  380. X              if (n_plist < MAX_REGISTERS)
  381. X                  plist[n_plist++] = current_coord;
  382. X              else
  383. X                  yyerror("Location list too long!");
  384. X          }
  385. X        | place_list ',' place
  386. X          {
  387. X              if (n_plist < MAX_REGISTERS)
  388. X                  plist[n_plist++] = current_coord;
  389. X              else
  390. X                  yyerror("Location list too long!");
  391. X          }
  392. X
  393. Xmap_details    : /* nothing */
  394. X        | map_details map_detail ;
  395. X
  396. Xmap_detail    : monster_detail
  397. X        | object_detail
  398. X        | door_detail
  399. X        | trap_detail
  400. X        | drawbridge_detail
  401. X        | region_detail
  402. X        | altar_detail
  403. X        | mazewalk_detail
  404. X        | ladder_detail
  405. X        | diggable_detail ;
  406. X
  407. Xmonster_detail    : MONSTER_ID ':' monster_c ',' m_name ',' coordinate
  408. X          {
  409. X              int token;
  410. X
  411. X              tmpmonst[nmons] = (monster *) alloc(sizeof(monster));
  412. X              tmpmonst[nmons]->x = current_coord.x;
  413. X              tmpmonst[nmons]->y = current_coord.y;
  414. X              tmpmonst[nmons]->class = $<i>3;
  415. X              if (!$5)
  416. X                  tmpmonst[nmons]->id = -1;
  417. X              else {
  418. X                  token = get_monster_id($5, (char) $<i>3);  
  419. X                  if (token == ERR) {
  420. X                      yywarning("Illegal monster name!  Making random monster.");
  421. X                      tmpmonst[nmons]->id = -1;
  422. X                  } else
  423. X                      tmpmonst[nmons]->id = token;
  424. X              }
  425. X              nmons++;
  426. X          }
  427. X
  428. Xobject_detail    : OBJECT_ID ':' object_c ',' o_name ',' coordinate
  429. X          {
  430. X              int token;
  431. X
  432. X              tmpobj[nobj] = (object *) alloc(sizeof(object));
  433. X              tmpobj[nobj]->x = current_coord.x;
  434. X              tmpobj[nobj]->y = current_coord.y;
  435. X              tmpobj[nobj]->class = $<i>3;
  436. X              if (!$5)
  437. X                  tmpobj[nobj]->id = -1;
  438. X              else {
  439. X                  token = get_object_id($5, (char) $<i>3);
  440. X                  if (token == ERR) {
  441. X                      yywarning("Illegal object name!  Making random object.");
  442. X                      tmpobj[nobj]->id = -1;
  443. X                  } else
  444. X                      tmpobj[nobj]->id = token;
  445. X              }
  446. X              nobj++;
  447. X          }
  448. X
  449. Xdoor_detail    : DOOR_ID ':' door_state ',' coordinate
  450. X          {
  451. X            tmpdoor[ndoor] = (door *) alloc(sizeof(door));
  452. X            tmpdoor[ndoor]->x = current_coord.x;
  453. X            tmpdoor[ndoor]->y = current_coord.y;
  454. X            tmpdoor[ndoor]->mask = $<i>3;
  455. X            ndoor++;
  456. X          }
  457. X
  458. Xtrap_detail    : TRAP_ID ':' trap_name ',' coordinate
  459. X          {
  460. X            tmptrap[ntrap] = (trap *) alloc(sizeof(trap));
  461. X            tmptrap[ntrap]->x = current_coord.x;
  462. X            tmptrap[ntrap]->y = current_coord.y;
  463. X            tmptrap[ntrap]->type = $<i>3;
  464. X            ntrap++;
  465. X          }
  466. X
  467. Xdrawbridge_detail: DRAWBRIDGE_ID ':' coordinate ',' DIRECTION ',' door_state
  468. X           {
  469. X            tmpdb[ndb] = (drawbridge *) alloc(sizeof(drawbridge));
  470. X            tmpdb[ndb]->x = current_coord.x;
  471. X            tmpdb[ndb]->y = current_coord.y;
  472. X            tmpdb[ndb]->dir = db_dirs[$5];
  473. X            if ( $<i>7 == D_ISOPEN )
  474. X              tmpdb[ndb]->open = 1;
  475. X            else if ( $<i>7 == D_CLOSED )
  476. X              tmpdb[ndb]->open = 0;
  477. X            else
  478. X              yyerror("A drawbridge can only be open or closed!");
  479. X            ndb++;
  480. X           }
  481. X
  482. Xmazewalk_detail    : MAZEWALK_ID ':' coordinate ',' DIRECTION
  483. X          {
  484. X            tmpwalk[nwalk] = (walk *) alloc(sizeof(walk));
  485. X            tmpwalk[nwalk]->x = current_coord.x;
  486. X            tmpwalk[nwalk]->y = current_coord.y;
  487. X            tmpwalk[nwalk]->dir = $5;
  488. X            nwalk++;
  489. X          }
  490. X
  491. Xladder_detail    : LADDER_ID ':' coordinate ',' UP_OR_DOWN
  492. X          {
  493. X            tmplad[nlad] = (lad *) alloc(sizeof(lad));
  494. X            tmplad[nlad]->x = current_coord.x;
  495. X            tmplad[nlad]->y = current_coord.y;
  496. X            tmplad[nlad]->up = $<i>5;
  497. X            nlad++;
  498. X          }
  499. X
  500. Xdiggable_detail    : NON_DIGGABLE_ID ':' region
  501. X          {
  502. X            tmpdig[ndig] = (dig *) alloc(sizeof(dig));
  503. X            tmpdig[ndig]->x1 = current_region.x1;
  504. X            tmpdig[ndig]->y1 = current_region.y1;
  505. X            tmpdig[ndig]->x2 = current_region.x2;
  506. X            tmpdig[ndig]->y2 = current_region.y2;
  507. X            ndig++;
  508. X          }
  509. X
  510. Xregion_detail    : REGION_ID ':' region ',' light_state ',' room_type
  511. X          {
  512. X            tmpreg[nreg] = (region *) alloc(sizeof(region));
  513. X            tmpreg[nreg]->x1 = current_region.x1;
  514. X            tmpreg[nreg]->y1 = current_region.y1;
  515. X            tmpreg[nreg]->x2 = current_region.x2;
  516. X            tmpreg[nreg]->y2 = current_region.y2;
  517. X            tmpreg[nreg]->rlit = $<i>5;
  518. X            tmpreg[nreg]->rtype = $<i>7;
  519. X            nreg++;
  520. X          }
  521. X
  522. Xaltar_detail    : ALTAR_ID ':' coordinate ',' alignment ',' altar_type
  523. X          {
  524. X#ifndef ALTARS
  525. X            yywarning("Altars are not allowed in this version!  Ignoring...");
  526. X#else
  527. X            tmpaltar[naltar] = (altar *) alloc(sizeof(altar));
  528. X            tmpaltar[naltar]->x = current_coord.x;
  529. X            tmpaltar[naltar]->y = current_coord.y;
  530. X            tmpaltar[naltar]->align = $<i>5;
  531. X            tmpaltar[naltar]->shrine = $<i>7;
  532. X            naltar++;
  533. X#endif /* ALTARS */
  534. X          }
  535. X
  536. Xmonster_c    : monster
  537. X        | RANDOM_TYPE
  538. X          {
  539. X              $<i>$ = - MAX_REGISTERS - 1;
  540. X          }
  541. X        | m_register ;
  542. X
  543. Xobject_c    : object
  544. X        | RANDOM_TYPE
  545. X          {
  546. X              $<i>$ = - MAX_REGISTERS - 1;
  547. X          }
  548. X        | o_register;
  549. X
  550. Xm_name        : string
  551. X        | RANDOM_TYPE
  552. X          {
  553. X              $$ = (char *) 0;
  554. X          }
  555. X
  556. Xo_name        : string
  557. X        | RANDOM_TYPE
  558. X          {
  559. X              $$ = (char *) 0;
  560. X          }
  561. X
  562. Xtrap_name    : string
  563. X          {
  564. X              int token = get_trap_type($1);
  565. X            if (token == ERR)
  566. X                yyerror("unknown trap type!");
  567. X            $<i>$ = token;
  568. X          }
  569. X        | RANDOM_TYPE
  570. X
  571. Xroom_type    : string
  572. X          {
  573. X            int token = get_room_type($1);
  574. X            if (token == ERR) {
  575. X                yywarning("Unknown room type!  Making ordinary room...");
  576. X                $<i>$ = OROOM;
  577. X            } else
  578. X                $<i>$ = token;
  579. X          }
  580. X        | RANDOM_TYPE
  581. X
  582. Xcoordinate    : coord
  583. X        | p_register
  584. X        | RANDOM_TYPE
  585. X          {
  586. X              current_coord.x = current_coord.y = -MAX_REGISTERS-1;
  587. X          }
  588. X
  589. Xdoor_state    : DOOR_STATE
  590. X        | RANDOM_TYPE
  591. X
  592. Xlight_state    : LIGHT_STATE
  593. X        | RANDOM_TYPE
  594. X
  595. Xalignment    : ALIGNMENT
  596. X        | a_register
  597. X        | RANDOM_TYPE
  598. X          {
  599. X              $<i>$ = - MAX_REGISTERS - 1;
  600. X          }
  601. X
  602. Xaltar_type    : ALTAR_TYPE
  603. X        | RANDOM_TYPE
  604. X
  605. Xp_register    : P_REGISTER '[' INTEGER ']'
  606. X          {
  607. X            if ( $3 >= MAX_REGISTERS ) {
  608. X                yyerror("Register Index overflow!");
  609. X            } else {
  610. X                current_coord.x = current_coord.y = - $3 - 1;
  611. X            }
  612. X          }
  613. X
  614. Xo_register    : O_REGISTER '[' INTEGER ']' 
  615. X          {
  616. X            if ( $3 >= MAX_REGISTERS ) {
  617. X                yyerror("Register Index overflow!");
  618. X            } else {
  619. X                $<i>$ = - $3 - 1;
  620. X            }
  621. X          }
  622. X
  623. Xm_register    : M_REGISTER '[' INTEGER ']'
  624. X          {
  625. X            if ( $3 >= MAX_REGISTERS ) {
  626. X                yyerror("Register Index overflow!");
  627. X            } else {
  628. X                $<i>$ = - $3 - 1;
  629. X            }
  630. X          }
  631. X
  632. Xa_register    : A_REGISTER '[' INTEGER ']'
  633. X          {
  634. X            if ( $3 >= 3 ) {
  635. X                yyerror("Register Index overflow!");
  636. X            } else {
  637. X                $<i>$ = - $3 - 1;
  638. X            }
  639. X          }
  640. X
  641. Xplace        : coord
  642. X
  643. Xmonster        : CHAR
  644. X          {
  645. X            if (check_monster_char($1))
  646. X                $<i>$ = $1 ;
  647. X            else {
  648. X                yyerror("unknown monster class!");
  649. X                $<i>$ = ERR;
  650. X            }
  651. X          }
  652. X
  653. Xobject        : CHAR
  654. X          {
  655. X            char c;
  656. X
  657. X            c = $1;
  658. X#ifndef SPELLS
  659. X            if ( c == '+') {
  660. X                c = '?';
  661. X                yywarning("Spellbooks are not allowed in this version! (converted into scroll)");
  662. X            }
  663. X#endif
  664. X            if (check_object_char(c))
  665. X                $<i>$ = c;
  666. X            else {
  667. X                yyerror("Unknown char class!");
  668. X                $<i>$ = ERR;
  669. X            }
  670. X          }
  671. Xstring        : STRING
  672. X
  673. Xcoord        : '(' INTEGER ',' INTEGER ')'
  674. X          {
  675. X                if ($2 < 0 || $2 > max_x_map ||
  676. X                $4 < 0 || $4 > max_y_map)
  677. X                yyerror("Coordinates out of map range!");
  678. X            current_coord.x = $2;
  679. X            current_coord.y = $4;
  680. X          }
  681. X
  682. Xregion        : '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'
  683. X          {
  684. X                if ($2 < 0 || $2 > max_x_map ||
  685. X                $4 < 0 || $4 > max_y_map ||
  686. X                $6 < 0 || $6 > max_x_map ||
  687. X                $8 < 0 || $8 > max_y_map)
  688. X                yyerror("Region out of map range!");
  689. X            current_region.x1 = $2;
  690. X            current_region.y1 = $4;
  691. X            current_region.x2 = $6;
  692. X            current_region.y2 = $8;
  693. X          }
  694. X
  695. X
  696. X%%
  697. X
  698. X/* 
  699. X * Find the type of a room in the table, knowing its name.
  700. X */
  701. X
  702. Xint
  703. Xget_room_type(s)
  704. Xchar *s;
  705. X{
  706. X    register int i;
  707. X    
  708. X    for(i=0; i < SHOPBASE -1; i++)
  709. X        if (!strcmp(s, room_types[i].name))
  710. X        return room_types[i].type;
  711. X    return ERR;
  712. X}
  713. X
  714. X/* 
  715. X * Find the type of a trap in the table, knowing its name.
  716. X */
  717. X
  718. Xint
  719. Xget_trap_type(s)
  720. Xchar *s;
  721. X{
  722. X    register int i;
  723. X    
  724. X    for(i=0; i < TRAPNUM - 1; i++)
  725. X        if(!strcmp(s,trap_types[i].name))
  726. X        return(trap_types[i].type);
  727. X    return ERR;
  728. X}
  729. X
  730. X/* 
  731. X * Find the index of a monster in the table, knowing its name.
  732. X */
  733. X
  734. Xint
  735. Xget_monster_id(s, c)
  736. Xchar *s;
  737. Xchar c;
  738. X{
  739. X    register int i;
  740. X    
  741. X    for(i=0; mons[i].mname[0]; i++)
  742. X        if(!strncmp(s, mons[i].mname, strlen(mons[i].mname))
  743. X           && c == mons[i].mlet)
  744. X        return i;
  745. X    return ERR;
  746. X}
  747. X
  748. X/* 
  749. X * Find the index of an object in the table, knowing its name.
  750. X */
  751. X
  752. Xint
  753. Xget_object_id(s, c)
  754. Xchar *s;
  755. Xchar c;
  756. X{
  757. X    register int i;
  758. X    
  759. X    for(i=0; i<=NROFOBJECTS;i++)
  760. X        if(objects[i].oc_name &&
  761. X           !strncmp(s, objects[i].oc_name, strlen(objects[i].oc_name))
  762. X           && c == objects[i].oc_olet)
  763. X        return i;
  764. X    return ERR;
  765. X}
  766. X
  767. X/* 
  768. X * Is the character 'c' a valid monster class ?
  769. X */
  770. X
  771. Xboolean
  772. Xcheck_monster_char(c)
  773. Xchar c;
  774. X{
  775. X    register int i;
  776. X    
  777. X    for(i=0; mons[i].mname[0]; i++)
  778. X        if( c ==  mons[i].mlet)
  779. X        return 1;
  780. X    return(0);
  781. X}
  782. X
  783. X/* 
  784. X * Is the character 'c' a valid object class ?
  785. X */
  786. X
  787. Xboolean
  788. Xcheck_object_char(c)
  789. Xchar c;
  790. X{
  791. X    register int i;
  792. X    
  793. X    for(i=0; i<=NROFOBJECTS;i++)
  794. X        if( c == objects[i].oc_olet)
  795. X        return 1;
  796. X    return 0;
  797. X}
  798. X
  799. X/* 
  800. X * Yep! LEX gives us the map in a raw mode.
  801. X * Just analyze it here.
  802. X */
  803. X
  804. Xvoid scan_map(map)
  805. Xchar *map;
  806. X{
  807. X    register int i, len;
  808. X    register char *s1, *s2;
  809. X    int max_len = 0;
  810. X    int max_hig = 0;
  811. X    
  812. X    /* First : find the max width of the map */
  813. X
  814. X    s1 = map;
  815. X    while (s1 && *s1) {
  816. X        s2 = index(s1, '\n');
  817. X        if (s2) {
  818. X            if (s2-s1 > max_len)
  819. X                max_len = s2-s1;
  820. X            s1 = s2 + 1;
  821. X        } else {
  822. X            if (strlen(s1) > max_len)
  823. X                max_len = strlen(s1);
  824. X            s1 = (char *) 0;
  825. X        }
  826. X    }
  827. X
  828. X    /* Then parse it now */
  829. X
  830. X    while (map && *map) {
  831. X        tmpmap[max_hig] = (char *) alloc(max_len);
  832. X        s1 = index(map, '\n');
  833. X        if (s1) {
  834. X            len = s1 - map;
  835. X            s1++;
  836. X        } else {
  837. X            len = strlen(map);
  838. X            s1 = map + len;
  839. X        }
  840. X        for(i=0; i<len; i++)
  841. X            switch(map[i]) {
  842. X              case '-' : tmpmap[max_hig][i] = HWALL; break;
  843. X              case '|' : tmpmap[max_hig][i] = VWALL; break;
  844. X              case '+' : tmpmap[max_hig][i] = DOOR; break;
  845. X              case 'S' : tmpmap[max_hig][i] = SDOOR; break;
  846. X              case '{' : 
  847. X#ifdef FOUNTAINS
  848. X                  tmpmap[max_hig][i] = FOUNTAIN;
  849. X#else
  850. X                  tmpmap[max_hig][i] = ROOM;
  851. X                  yywarning("Fountains are not allowed in this version!  Ignoring...");
  852. X#endif
  853. X                  break;
  854. X              case '\\' : 
  855. X#ifdef THRONES
  856. X                  tmpmap[max_hig][i] = THRONE;
  857. X#else
  858. X                  tmpmap[max_hig][i] = ROOM;
  859. X                  yywarning("Thrones are not allowed in this version!  Ignoring...");
  860. X#endif
  861. X                  break;
  862. X              case 'K' : 
  863. X#ifdef SINKS
  864. X                  tmpmap[max_hig][i] = SINK;
  865. X#else
  866. X                  tmpmap[max_hig][i] = ROOM;
  867. X                  yywarning("Sinks are not allowed in this version!  Ignoring...");
  868. X#endif
  869. X                  break;
  870. X              case '}' : tmpmap[max_hig][i] = MOAT; break;
  871. X              case '#' : tmpmap[max_hig][i] = CORR; break;
  872. X              default  : tmpmap[max_hig][i] = ROOM; break;
  873. X            }
  874. X        while(i < max_len)
  875. X            tmpmap[max_hig][i++] = ROOM;
  876. X        map = s1;
  877. X        max_hig++;
  878. X    }
  879. X
  880. X    /* Memorize boundaries */
  881. X
  882. X    max_x_map = max_len - 1;
  883. X    max_y_map = max_hig - 1;
  884. X
  885. X    /* Store the map into the mazepart structure */
  886. X
  887. X    tmppart[npart]->xsize = max_len;
  888. X    tmppart[npart]->ysize = max_hig;
  889. X    tmppart[npart]->map = (char **) alloc(max_hig*sizeof(char *));
  890. X    for(i = 0; i< max_hig; i++)
  891. X        tmppart[npart]->map[i] = tmpmap[i];
  892. X}
  893. X
  894. X/* 
  895. X * Here we want to store the maze part we just got.
  896. X */
  897. X
  898. Xvoid
  899. Xstore_part()
  900. X{
  901. X    register int i;
  902. X
  903. X    /* Ok, We got the whole part, now we store it. */
  904. X    
  905. X    /* The Regions */
  906. X
  907. X    if(tmppart[npart]->nreg = nreg) {
  908. X        tmppart[npart]->regions = (region**)alloc(sizeof(region*) * nreg);
  909. X        for(i=0;i<nreg;i++)
  910. X            tmppart[npart]->regions[i] = tmpreg[i];
  911. X    }
  912. X    nreg = 0;
  913. X
  914. X    /* the doors */
  915. X
  916. X    if(tmppart[npart]->ndoor = ndoor) {
  917. X        tmppart[npart]->doors = (door **)alloc(sizeof(door *) * ndoor);
  918. X        for(i=0;i<ndoor;i++)
  919. X            tmppart[npart]->doors[i] = tmpdoor[i];
  920. X    }
  921. X    ndoor = 0;
  922. X
  923. X    /* the traps */
  924. X
  925. X    if(tmppart[npart]->ntraps = ntrap) {
  926. X        tmppart[npart]->traps = (trap **)alloc(sizeof(trap*) * ntrap);
  927. X        for(i=0;i<ntrap;i++)
  928. X            tmppart[npart]->traps[i] = tmptrap[i];
  929. X    }
  930. X    ntrap = 0;
  931. X
  932. X    /* the monsters */
  933. X
  934. X    if(tmppart[npart]->nmonster = nmons) {
  935. X        tmppart[npart]->monsters = (monster**)alloc(sizeof(monster*)*nmons);
  936. X        for(i=0;i<nmons;i++)
  937. X            tmppart[npart]->monsters[i] = tmpmonst[i];
  938. X    }
  939. X    nmons = 0;
  940. X
  941. X    /* the objects */
  942. X
  943. X    if(tmppart[npart]->nobjects = nobj) {
  944. X        tmppart[npart]->objects = (object**)alloc(sizeof(object*)*nobj);
  945. X        for(i=0;i<nobj;i++)
  946. X            tmppart[npart]->objects[i] = tmpobj[i];
  947. X    }
  948. X    nobj = 0;
  949. X
  950. X    /* the drawbridges */
  951. X
  952. X    if(tmppart[npart]->ndrawbridge = ndb) {
  953. X        tmppart[npart]->drawbridges = (drawbridge**)alloc(sizeof(drawbridge*)*ndb);
  954. X        for(i=0;i<ndb;i++)
  955. X            tmppart[npart]->drawbridges[i] = tmpdb[i];
  956. X    }
  957. X    ndb = 0;
  958. X
  959. X    /* The walkmaze directives */
  960. X
  961. X    if(tmppart[npart]->nwalk = nwalk) {
  962. X        tmppart[npart]->walks = (walk**)alloc(sizeof(walk*)*nwalk);
  963. X        for(i=0;i<nwalk;i++)
  964. X            tmppart[npart]->walks[i] = tmpwalk[i];
  965. X    }
  966. X    nwalk = 0;
  967. X
  968. X    /* The non_diggable directives */
  969. X
  970. X    if(tmppart[npart]->ndig = ndig) {
  971. X        tmppart[npart]->digs = (dig **) alloc(sizeof(dig*) * ndig);
  972. X        for(i=0;i<ndig;i++)
  973. X            tmppart[npart]->digs[i] = tmpdig[i];
  974. X    }
  975. X    ndig = 0;
  976. X
  977. X    /* The ladders */
  978. X
  979. X    if(tmppart[npart]->nlad = nlad) {
  980. X        tmppart[npart]->lads = (lad **) alloc(sizeof(lad*) * nlad);
  981. X        for(i=0;i<nlad;i++)
  982. X            tmppart[npart]->lads[i] = tmplad[i];
  983. X    }
  984. X    nlad = 0;
  985. X#ifdef ALTARS
  986. X    /* The altars */
  987. X
  988. X    if(tmppart[npart]->naltar = naltar) {
  989. X        tmppart[npart]->altars = (altar**)alloc(sizeof(altar*) * naltar);
  990. X        for(i=0;i<naltar;i++)
  991. X            tmppart[npart]->altars[i] = tmpaltar[i];
  992. X    }
  993. X    naltar = 0;
  994. X#endif /* ALTARS /**/
  995. X    npart++;
  996. X    n_plist = n_mlist = n_olist = 0;
  997. X}
  998. X
  999. X/* 
  1000. X * Here we write the structure of the maze in the specified file (fd).
  1001. X * Also, we have to free the memory allocated via alloc()
  1002. X */
  1003. X
  1004. Xvoid
  1005. Xwrite_maze(fd, maze)
  1006. Xint fd;
  1007. Xspecialmaze *maze;
  1008. X{
  1009. X    char c;
  1010. X    short i,j;
  1011. X    mazepart *pt;
  1012. X
  1013. X    c = 2;
  1014. X    (void) write(fd, &c, 1);    /* Header for special mazes */
  1015. X    (void) write(fd, &(maze->numpart), 1);    /* Number of parts */
  1016. X    for(i=0;i<maze->numpart;i++) {
  1017. X        pt = maze->parts[i];
  1018. X
  1019. X        /* First, write the map */
  1020. X
  1021. X        (void) write(fd, &(pt->halign), 1);
  1022. X        (void) write(fd, &(pt->valign), 1);
  1023. X        (void) write(fd, &(pt->xsize), 1);
  1024. X        (void) write(fd, &(pt->ysize), 1);
  1025. X        for(j=0;j<pt->ysize;j++) {
  1026. X            (void) write(fd, pt->map[j], pt->xsize);
  1027. X            free(pt->map[j]);
  1028. X        }
  1029. X        free(pt->map);
  1030. X
  1031. X        /* The random registers */
  1032. X        (void) write(fd, &(pt->nrobjects), 1);
  1033. X        if(pt->nrobjects) {
  1034. X            (void) write(fd, pt->robjects, pt->nrobjects);
  1035. X            free(pt->robjects);
  1036. X        }
  1037. X        (void) write(fd, &(pt->nloc), 1);
  1038. X        if(pt->nloc) {
  1039. X        (void) write(fd,pt->rloc_x, pt->nloc);
  1040. X        (void) write(fd,pt->rloc_y, pt->nloc);
  1041. X        free(pt->rloc_x);
  1042. X        free(pt->rloc_y);
  1043. X        }
  1044. X        (void) write(fd,&(pt->nrmonst), 1);
  1045. X        if(pt->nrmonst) {
  1046. X            (void) write(fd, pt->rmonst, pt->nrmonst);
  1047. X            free(pt->rmonst);
  1048. X        }
  1049. X
  1050. X        /* subrooms */
  1051. X        (void) write(fd, &(pt->nreg), 1);
  1052. X        for(j=0;j<pt->nreg;j++) {
  1053. X            (void) write(fd,(genericptr_t) pt->regions[j], sizeof(region));
  1054. X            free(pt->regions[j]);
  1055. X        }
  1056. X        if(pt->nreg > 0)
  1057. X        free(pt->regions);
  1058. X
  1059. X        /* the doors */
  1060. X        (void) write(fd,&(pt->ndoor),1);
  1061. X        for(j=0;j<pt->ndoor;j++) {
  1062. X            (void) write(fd,(genericptr_t) pt->doors[j], sizeof(door));
  1063. X            free(pt->doors[j]);
  1064. X        }
  1065. X        if (pt->ndoor > 0)
  1066. X        free(pt->doors);
  1067. X
  1068. X        /* The traps */
  1069. X        (void) write(fd,&(pt->ntraps), 1);
  1070. X        for(j=0;j<pt->ntraps;j++) {
  1071. X            (void) write(fd,(genericptr_t) pt->traps[j], sizeof(trap));
  1072. X            free(pt->traps[j]);
  1073. X        }
  1074. X        if (pt->ntraps)
  1075. X        free(pt->traps);
  1076. X
  1077. X        /* The monsters */
  1078. X        (void) write(fd, &(pt->nmonster), 1);
  1079. X        for(j=0;j<pt->nmonster;j++) {
  1080. X            (void) write(fd,(genericptr_t) pt->monsters[j], sizeof(monster));
  1081. X            free(pt->monsters[j]);
  1082. X        }
  1083. X        if (pt->nmonster > 0)
  1084. X        free(pt->monsters);
  1085. X
  1086. X        /* The objects */
  1087. X        (void) write(fd, &(pt->nobjects), 1);
  1088. X        for(j=0;j<pt->nobjects;j++) {
  1089. X            (void) write(fd,(genericptr_t) pt->objects[j], sizeof(object));
  1090. X            free(pt->objects[j]);
  1091. X        }
  1092. X        if(pt->nobjects > 0)
  1093. X        free(pt->objects);
  1094. X
  1095. X        /* The drawbridges */
  1096. X        (void) write(fd, &(pt->ndrawbridge),1);
  1097. X        for(j=0;j<pt->ndrawbridge;j++) {
  1098. X            (void) write(fd,(genericptr_t) pt->drawbridges[j], sizeof(drawbridge));
  1099. X            free(pt->drawbridges[j]);
  1100. X        }
  1101. X        if(pt->ndrawbridge > 0)
  1102. X        free(pt->drawbridges);
  1103. X
  1104. X        /* The mazewalk directives */
  1105. X        (void) write(fd, &(pt->nwalk), 1);
  1106. X        for(j=0; j<pt->nwalk; j++) {
  1107. X            (void) write(fd,(genericptr_t) pt->walks[j], sizeof(walk));
  1108. X            free(pt->walks[j]);
  1109. X        }
  1110. X        if (pt->nwalk > 0)
  1111. X        free(pt->walks);
  1112. X
  1113. X        /* The non_diggable directives */
  1114. X        (void) write(fd, &(pt->ndig), 1);
  1115. X        for(j=0;j<pt->ndig;j++) {
  1116. X            (void) write(fd,(genericptr_t) pt->digs[j], sizeof(dig));
  1117. X            free(pt->digs[j]);
  1118. X        }
  1119. X        if (pt->ndig > 0)
  1120. X        free(pt->digs);
  1121. X
  1122. X        /* The ladders */
  1123. X        (void) write(fd, &(pt->nlad), 1);
  1124. X        for(j=0;j<pt->nlad;j++) {
  1125. X            (void) write(fd,(genericptr_t) pt->lads[j], sizeof(lad));
  1126. X            free(pt->lads[j]);
  1127. X        }
  1128. X        if (pt->nlad > 0)
  1129. X        free(pt->lads);
  1130. X#ifdef ALTARS
  1131. X        /* The altars */
  1132. X        (void) write(fd, &(pt->naltar), 1);
  1133. X        for(j=0;j<pt->naltar;j++) {
  1134. X            (void) write(fd,(genericptr_t) pt->altars[j], sizeof(altar));
  1135. X            free(pt->altars[j]);
  1136. X        }
  1137. X        if (pt->naltar > 0)
  1138. X        free(pt->altars);
  1139. X#endif /* ALTARS /**/
  1140. X        free(pt);
  1141. X    }
  1142. X}
  1143. END_OF_FILE
  1144. if test 23359 -ne `wc -c <'src/lev_comp.y'`; then
  1145.     echo shar: \"'src/lev_comp.y'\" unpacked with wrong size!
  1146. fi
  1147. # end of 'src/lev_comp.y'
  1148. fi
  1149. if test -f 'src/mklev.c' -a "${1}" != "-c" ; then 
  1150.   echo shar: Will not clobber existing file \"'src/mklev.c'\"
  1151. else
  1152. echo shar: Extracting \"'src/mklev.c'\" \(27014 characters\)
  1153. sed "s/^X//" >'src/mklev.c' <<'END_OF_FILE'
  1154. X/*    SCCS Id: @(#)mklev.c    3.0    88/11/24
  1155. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1156. X/* NetHack may be freely redistributed.  See license for details. */
  1157. X
  1158. X#include "hack.h"
  1159. X
  1160. X/* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */
  1161. X/* croom->lx etc are schar (width <= int), so % arith ensures that */
  1162. X/* conversion of result to int is reasonable */
  1163. X
  1164. X#ifdef SINKS
  1165. Xstatic void mksink();
  1166. X#endif
  1167. X#ifdef ALTARS
  1168. Xstatic void mkaltar();
  1169. X#endif
  1170. X
  1171. Xint
  1172. Xsomex(croom)
  1173. Xregister struct mkroom *croom;
  1174. X{
  1175. X    return rn2(croom->hx-croom->lx+1) + croom->lx;
  1176. X}
  1177. X
  1178. Xint
  1179. Xsomey(croom)
  1180. Xregister struct mkroom *croom;
  1181. X{
  1182. X    return rn2(croom->hy-croom->ly+1) + croom->ly;
  1183. X}
  1184. X
  1185. X#define    XLIM    4    /* define minimum required space around a room */
  1186. X#define    YLIM    3
  1187. Xboolean secret;        /* TRUE while making a vault: increase [XY]LIM */
  1188. Xstruct rm zerorm;
  1189. Xschar nxcor;
  1190. Xboolean goldseen;
  1191. X
  1192. X/* Definitions used by makerooms() and addrs() */
  1193. X#define    MAXRS    50    /* max lth of temp rectangle table - arbitrary */
  1194. Xstruct rectangle {
  1195. X    xchar rlx,rly,rhx,rhy;
  1196. X} rs[MAXRS+1];
  1197. Xint rscnt,rsmax;    /* 0..rscnt-1: currently under consideration */
  1198. X            /* rscnt..rsmax: discarded */
  1199. X
  1200. Xstatic void
  1201. Xaddrsx(lx,ly,hx,hy,discarded)
  1202. Xregister int lx,ly,hx,hy;
  1203. Xboolean discarded;        /* piece of a discarded area */
  1204. X{
  1205. X    register struct rectangle *rsp;
  1206. X
  1207. X    /* check inclusions */
  1208. X    for(rsp = rs; rsp < &rs[rsmax]; rsp++) {
  1209. X        if(lx >= rsp->rlx && hx <= rsp->rhx &&
  1210. X           ly >= rsp->rly && hy <= rsp->rhy)
  1211. X            return;
  1212. X    }
  1213. X
  1214. X    /* make a new entry */
  1215. X    if(rsmax >= MAXRS) {
  1216. X#ifdef WIZARD
  1217. X        if(wizard) pline("MAXRS may be too small.");
  1218. X#endif
  1219. X        return;
  1220. X    }
  1221. X    rsmax++;
  1222. X    if(!discarded) {
  1223. X        *rsp = rs[rscnt];
  1224. X        rsp = &rs[rscnt];
  1225. X        rscnt++;
  1226. X    }
  1227. X    rsp->rlx = lx;
  1228. X    rsp->rly = ly;
  1229. X    rsp->rhx = hx;
  1230. X    rsp->rhy = hy;
  1231. X}
  1232. X
  1233. Xstatic void
  1234. Xaddrs(lowx,lowy,hix,hiy)
  1235. Xregister int lowx,lowy,hix,hiy;
  1236. X{
  1237. X    register struct rectangle *rsp;
  1238. X    register int lx,ly,hx,hy,xlim,ylim;
  1239. X    boolean discarded;
  1240. X
  1241. X    xlim = XLIM + secret;
  1242. X    ylim = YLIM + secret;
  1243. X
  1244. X    /* walk down since rscnt and rsmax change */
  1245. X    for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {
  1246. X
  1247. X        if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
  1248. X           (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
  1249. X            continue;
  1250. X        if((discarded = (rsp >= &rs[rscnt]))) {
  1251. X            *rsp = rs[--rsmax];
  1252. X        } else {
  1253. X            rsmax--;
  1254. X            rscnt--;
  1255. X            *rsp = rs[rscnt];
  1256. X            if(rscnt != rsmax)
  1257. X                rs[rscnt] = rs[rsmax];
  1258. X        }
  1259. X        if(lowy - ly > 2*ylim + 4)
  1260. X            addrsx(lx,ly,hx,lowy-2,discarded);
  1261. X        if(lowx - lx > 2*xlim + 4)
  1262. X            addrsx(lx,ly,lowx-2,hy,discarded);
  1263. X        if(hy - hiy > 2*ylim + 4)
  1264. X            addrsx(lx,hiy+2,hx,hy,discarded);
  1265. X        if(hx - hix > 2*xlim + 4)
  1266. X            addrsx(hix+2,ly,hx,hy,discarded);
  1267. X    }
  1268. X}
  1269. X
  1270. Xstatic int
  1271. Xcomp(x,y)
  1272. Xregister struct mkroom *x,*y;
  1273. X{
  1274. X    if(x->lx < y->lx) return(-1);
  1275. X    return(x->lx > y->lx);
  1276. X}
  1277. X
  1278. Xstatic void
  1279. Xfinddpos(cc, xl,yl,xh,yh)
  1280. Xcoord    *cc;
  1281. Xxchar    xl,yl,xh,yh;
  1282. X{
  1283. X    register xchar x, y;
  1284. X
  1285. X    x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
  1286. X    y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
  1287. X    if(okdoor(x, y))
  1288. X        goto gotit;
  1289. X
  1290. X    for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
  1291. X        if(okdoor(x, y))
  1292. X            goto gotit;
  1293. X
  1294. X    for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
  1295. X        if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR)
  1296. X            goto gotit;
  1297. X    /* cannot find something reasonable -- strange */
  1298. X    x = xl;
  1299. X    y = yh;
  1300. Xgotit:
  1301. X    cc->x = x;
  1302. X    cc->y = y;
  1303. X    return;
  1304. X}
  1305. X
  1306. X/* Only called from makerooms() and makebigroom() */
  1307. Xstatic int
  1308. Xmaker(lowx,ddx,lowy,ddy,lit)
  1309. Xschar lowx,ddx,lowy,ddy;
  1310. Xboolean lit;
  1311. X{
  1312. X    register struct mkroom *croom;
  1313. X    register int x, y, hix = lowx+ddx, hiy = lowy+ddy;
  1314. X    register int xlim = XLIM + secret, ylim = YLIM + secret;
  1315. X
  1316. X    if(nroom >= MAXNROFROOMS) return(0);
  1317. X    if(lowx < XLIM) lowx = XLIM;
  1318. X    if(lowy < YLIM) lowy = YLIM;
  1319. X    if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1;
  1320. X    if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1;
  1321. Xchk:
  1322. X    if(hix <= lowx || hiy <= lowy) return(0);
  1323. X
  1324. X    /* check area around room (and make room smaller if necessary) */
  1325. X    for(x = lowx - xlim; x <= hix + xlim; x++) {
  1326. X        for(y = lowy - ylim; y <= hiy + ylim; y++) {
  1327. X            if(levl[x][y].typ) {
  1328. X#ifdef WIZARD
  1329. X                if(wizard && !secret)
  1330. X                pline("Strange area [%d,%d] in maker().",x,y);
  1331. X#endif
  1332. X                if(!rn2(3)) return(0);
  1333. X                if(x < lowx)
  1334. X                    lowx = x+xlim+1;
  1335. X                else
  1336. X                    hix = x-xlim-1;
  1337. X                if(y < lowy)
  1338. X                    lowy = y+ylim+1;
  1339. X                else
  1340. X                    hiy = y-ylim-1;
  1341. X                goto chk;
  1342. X            }
  1343. X        }
  1344. X    }
  1345. X
  1346. X    croom = &rooms[nroom];
  1347. X
  1348. X    /* on low levels the room is lit (usually) */
  1349. X    /* secret vaults are always lit */
  1350. X    /* some other rooms may require lighting */
  1351. X    if((rnd(dlevel) < 10 && rn2(77)) || secret || lit) {
  1352. X        for(x = lowx-1; x <= hix+1; x++)
  1353. X            for(y = lowy-1; y <= hiy+1; y++)
  1354. X                levl[x][y].lit = 1;
  1355. X        croom->rlit = 1;
  1356. X    } else
  1357. X        croom->rlit = 0;
  1358. X    croom->lx = lowx;
  1359. X    croom->hx = hix;
  1360. X    croom->ly = lowy;
  1361. X    croom->hy = hiy;
  1362. X    croom->rtype = OROOM;
  1363. X    croom->doorct = 0;
  1364. X    /* if we're not making a vault, doorindex will still be 0
  1365. X     * if we are, we'll have problems adding niches to the previous room
  1366. X     * unless fdoor is at least doorindex
  1367. X     */
  1368. X    croom->fdoor = doorindex;
  1369. X
  1370. X    for(x = lowx-1; x <= hix+1; x++)
  1371. X        for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
  1372. X        levl[x][y].typ = HWALL;
  1373. X        levl[x][y].scrsym = HWALL_SYM;
  1374. X        }
  1375. X    for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
  1376. X        for(y = lowy; y <= hiy; y++) {
  1377. X        levl[x][y].typ = VWALL;
  1378. X        levl[x][y].scrsym = VWALL_SYM;
  1379. X        }
  1380. X    for(x = lowx; x <= hix; x++)
  1381. X        for(y = lowy; y <= hiy; y++) {
  1382. X        levl[x][y].typ = ROOM;
  1383. X        levl[x][y].scrsym = ROOM_SYM;
  1384. X        }
  1385. X    levl[lowx-1][lowy-1].typ = TLCORNER;
  1386. X    levl[hix+1][lowy-1].typ = TRCORNER;
  1387. X    levl[lowx-1][hiy+1].typ = BLCORNER;
  1388. X    levl[hix+1][hiy+1].typ = BRCORNER;
  1389. X    levl[lowx-1][lowy-1].scrsym = TLCORN_SYM;
  1390. X    levl[hix+1][lowy-1].scrsym = TRCORN_SYM;
  1391. X    levl[lowx-1][hiy+1].scrsym = BLCORN_SYM;
  1392. X    levl[hix+1][hiy+1].scrsym = BRCORN_SYM;
  1393. X
  1394. X    smeq[nroom] = nroom;
  1395. X    croom++;
  1396. X    croom->hx = -1;
  1397. X    nroom++;
  1398. X    return(1);
  1399. X}
  1400. X
  1401. Xstatic int
  1402. Xmakerooms() {
  1403. Xregister struct rectangle *rsp;
  1404. Xregister int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
  1405. Xint tryct = 0, xlim, ylim;
  1406. X
  1407. X    /* init */
  1408. X    xlim = XLIM + secret;
  1409. X    ylim = YLIM + secret;
  1410. X    if(nroom == 0) {
  1411. X        rsp = rs;
  1412. X        rsp->rlx = rsp->rly = 0;
  1413. X        rsp->rhx = COLNO-1;
  1414. X        rsp->rhy = ROWNO-1;
  1415. X        rsmax = 1;
  1416. X    }
  1417. X    rscnt = rsmax;
  1418. X
  1419. X    /* make rooms until satisfied */
  1420. X    while(rscnt > 0 && nroom < MAXNROFROOMS-1) {
  1421. X        if(!secret && nroom > (MAXNROFROOMS/4) &&
  1422. X           !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom)))
  1423. X            return 0;
  1424. X
  1425. X        /* pick a rectangle */
  1426. X        rsp = &rs[rn2(rscnt)];
  1427. X        hx = rsp->rhx;
  1428. X        hy = rsp->rhy;
  1429. X        lx = rsp->rlx;
  1430. X        ly = rsp->rly;
  1431. X
  1432. X        /* find size of room */
  1433. X        if(secret)
  1434. X            dx = dy = 1;
  1435. X        else {
  1436. X            dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);
  1437. X            dy = 2 + rn2(4);
  1438. X            if(dx*dy > 50)
  1439. X                dy = 50/dx;
  1440. X        }
  1441. X
  1442. X        /* look whether our room will fit */
  1443. X        if(hx-lx < dx + (dx>>1) + 2*xlim ||
  1444. X           hy-ly < dy + dy/3 + 2*ylim) {
  1445. X                    /* no, too small */
  1446. X                    /* maybe we throw this area out */
  1447. X            if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) {
  1448. X                rscnt--;
  1449. X                rs[rsmax] = *rsp;
  1450. X                *rsp = rs[rscnt];
  1451. X                rs[rscnt] = rs[rsmax];
  1452. X                tryct = 0;
  1453. X            } else
  1454. X                tryct++;
  1455. X            continue;
  1456. X        }
  1457. X
  1458. X        lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);
  1459. X        lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);
  1460. X        hix = lowx + dx;
  1461. X        hiy = lowy + dy;
  1462. X
  1463. X        if(maker(lowx, dx, lowy, dy, FALSE)) {
  1464. X            if(secret) return(1);
  1465. X            addrs(lowx-1, lowy-1, hix+1, hiy+1);
  1466. X            tryct = 0;
  1467. X        } else
  1468. X            if(tryct++ > 100)
  1469. X                break;
  1470. X    }
  1471. X    return(0);    /* failed to make vault - very strange */
  1472. X}
  1473. X
  1474. Xstatic void
  1475. Xjoin(a,b)
  1476. Xregister int a, b;
  1477. X{
  1478. X    coord cc,tt;
  1479. X    register int tx, ty, xx, yy;
  1480. X    register struct rm *crm;
  1481. X    register struct mkroom *croom, *troom;
  1482. X    register int dx, dy, dix, diy, cct;
  1483. X
  1484. X    croom = &rooms[a];
  1485. X    troom = &rooms[b];
  1486. X
  1487. X    /* find positions cc and tt for doors in croom and troom
  1488. X       and direction for a corridor between them */
  1489. X
  1490. X    if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
  1491. X    if(troom->lx > croom->hx) {
  1492. X        dx = 1;
  1493. X        dy = 0;
  1494. X        xx = croom->hx+1;
  1495. X        tx = troom->lx-1;
  1496. X        finddpos(&cc, xx, croom->ly, xx, croom->hy);
  1497. X        finddpos(&tt, tx, troom->ly, tx, troom->hy);
  1498. X    } else if(troom->hy < croom->ly) {
  1499. X        dy = -1;
  1500. X        dx = 0;
  1501. X        yy = croom->ly-1;
  1502. X        finddpos(&cc, croom->lx, yy, croom->hx, yy);
  1503. X        ty = troom->hy+1;
  1504. X        finddpos(&tt, troom->lx, ty, troom->hx, ty);
  1505. X    } else if(troom->hx < croom->lx) {
  1506. X        dx = -1;
  1507. X        dy = 0;
  1508. X        xx = croom->lx-1;
  1509. X        tx = troom->hx+1;
  1510. X        finddpos(&cc, xx, croom->ly, xx, croom->hy);
  1511. X        finddpos(&tt, tx, troom->ly, tx, troom->hy);
  1512. X    } else {
  1513. X        dy = 1;
  1514. X        dx = 0;
  1515. X        yy = croom->hy+1;
  1516. X        ty = troom->ly-1;
  1517. X        finddpos(&cc, croom->lx, yy, croom->hx, yy);
  1518. X        finddpos(&tt, troom->lx, ty, troom->hx, ty);
  1519. X    }
  1520. X    xx = cc.x;
  1521. X    yy = cc.y;
  1522. X    tx = tt.x - dx;
  1523. X    ty = tt.y - dy;
  1524. X    if(nxcor && levl[xx+dx][yy+dy].typ)
  1525. X        return;
  1526. X    dodoor(xx,yy,croom);
  1527. X
  1528. X    cct = 0;
  1529. X    while(xx != tx || yy != ty) {
  1530. X        xx += dx;
  1531. X        yy += dy;
  1532. X
  1533. X        /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
  1534. X        if(cct++ > 500 || (nxcor && !rn2(35)))
  1535. X        return;
  1536. X
  1537. X        if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
  1538. X        return;        /* impossible */
  1539. X
  1540. X        crm = &levl[xx][yy];
  1541. X        if(!(crm->typ)) {
  1542. X        if(rn2(100)) {
  1543. X            crm->typ = CORR;
  1544. X            crm->scrsym = CORR_SYM;
  1545. X            if(nxcor && !rn2(50))
  1546. X                (void) mksobj_at(BOULDER, xx, yy);
  1547. X        } else {
  1548. X            crm->typ = SCORR;
  1549. X            crm->scrsym = STONE_SYM;
  1550. X        }
  1551. X        } else
  1552. X        if(crm->typ != CORR && crm->typ != SCORR) {
  1553. X        /* strange ... */
  1554. X        return;
  1555. X        }
  1556. X
  1557. X        /* find next corridor position */
  1558. X        dix = abs(xx-tx);
  1559. X        diy = abs(yy-ty);
  1560. X
  1561. X        /* do we have to change direction ? */
  1562. X        if(dy && dix > diy) {
  1563. X        register int ddx = (xx > tx) ? -1 : 1;
  1564. X
  1565. X        crm = &levl[xx+ddx][yy];
  1566. X        if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
  1567. X            dx = ddx;
  1568. X            dy = 0;
  1569. X            continue;
  1570. X        }
  1571. X        } else if(dx && diy > dix) {
  1572. X        register int ddy = (yy > ty) ? -1 : 1;
  1573. X
  1574. X        crm = &levl[xx][yy+ddy];
  1575. X        if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
  1576. X            dy = ddy;
  1577. X            dx = 0;
  1578. X            continue;
  1579. X        }
  1580. X        }
  1581. X
  1582. X        /* continue straight on? */
  1583. X        crm = &levl[xx+dx][yy+dy];
  1584. X        if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
  1585. X        continue;
  1586. X
  1587. X        /* no, what must we do now?? */
  1588. X        if(dx) {
  1589. X        dx = 0;
  1590. X        dy = (ty < yy) ? -1 : 1;
  1591. X        crm = &levl[xx+dx][yy+dy];
  1592. X        if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
  1593. X            continue;
  1594. X        dy = -dy;
  1595. X        continue;
  1596. X        } else {
  1597. X        dy = 0;
  1598. X        dx = (tx < xx) ? -1 : 1;
  1599. X        crm = &levl[xx+dx][yy+dy];
  1600. X        if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
  1601. X            continue;
  1602. X        dx = -dx;
  1603. X        continue;
  1604. X        }
  1605. X    }
  1606. X
  1607. X    /* we succeeded in digging the corridor */
  1608. X    dodoor(tt.x, tt.y, troom);
  1609. X
  1610. X    if(smeq[a] < smeq[b])
  1611. X        smeq[b] = smeq[a];
  1612. X    else
  1613. X        smeq[a] = smeq[b];
  1614. X}
  1615. X
  1616. Xstatic void
  1617. Xmakecorridors() {
  1618. X    register int a, b;
  1619. X
  1620. X    nxcor = 0;
  1621. X    for(a = 0; a < nroom-1; a++)
  1622. X        join(a, a+1);
  1623. X    for(a = 0; a < nroom-2; a++)
  1624. X        if(smeq[a] != smeq[a+2])
  1625. X        join(a, a+2);
  1626. X    for(a = 0; a < nroom; a++)
  1627. X        for(b = 0; b < nroom; b++)
  1628. X        if(smeq[a] != smeq[b])
  1629. X            join(a, b);
  1630. X    if(nroom > 2)
  1631. X        for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
  1632. X        a = rn2(nroom);
  1633. X        b = rn2(nroom-2);
  1634. X        if(b >= a) b += 2;
  1635. X        join(a, b);
  1636. X        }
  1637. X}
  1638. X
  1639. Xstatic void
  1640. Xdosdoor(x,y,aroom,type)
  1641. Xregister int x, y;
  1642. Xregister struct mkroom *aroom;
  1643. Xregister int type;
  1644. X{
  1645. X    register struct mkroom *broom;
  1646. X    register int tmp;
  1647. X    boolean shdoor = in_shop(x, y);
  1648. X
  1649. X    if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with DOOR_SYM as scrsym */
  1650. X        type = DOOR;
  1651. X    levl[x][y].typ = type;
  1652. X    if(type == DOOR) {
  1653. X        levl[x][y].scrsym = DOOR_SYM;
  1654. X        if(!rn2(3)) {      /* is it a locked door, closed, or a doorway? */
  1655. X        if(!rn2(5))
  1656. X            levl[x][y].doormask = D_ISOPEN;
  1657. X        else if(!rn2(4))
  1658. X            levl[x][y].doormask = D_LOCKED;
  1659. X        else
  1660. X            levl[x][y].doormask = D_CLOSED;
  1661. X
  1662. X        if (levl[x][y].doormask != D_ISOPEN && !shdoor && !rn2(25))
  1663. X            levl[x][y].doormask |= D_TRAPPED;
  1664. X        } else {
  1665. X        if(shdoor)    levl[x][y].doormask = D_ISOPEN;
  1666. X        else        levl[x][y].doormask = D_NODOOR;
  1667. X        }
  1668. X    } else { /* SDOOR */
  1669. X        if(shdoor || !rn2(5))    levl[x][y].doormask = D_LOCKED;
  1670. X        else            levl[x][y].doormask = D_CLOSED;
  1671. X
  1672. X        if(!shdoor && !rn2(20)) levl[x][y].doormask |= D_TRAPPED;
  1673. X    }
  1674. X    aroom->doorct++;
  1675. X    broom = aroom+1;
  1676. X    if(broom->hx < 0) tmp = doorindex; else
  1677. X    for(tmp = doorindex; tmp > broom->fdoor; tmp--)
  1678. X        doors[tmp] = doors[tmp-1];
  1679. X    doorindex++;
  1680. X    doors[tmp].x = x;
  1681. X    doors[tmp].y = y;
  1682. X    for( ; broom->hx >= 0; broom++) broom->fdoor++;
  1683. X}
  1684. X
  1685. Xstatic boolean
  1686. Xplace_niche(aroom,dy,xx,yy)
  1687. Xregister struct mkroom *aroom;
  1688. Xint *dy, *xx, *yy;
  1689. X{
  1690. X    coord dd;
  1691. X
  1692. X    if(rn2(2)) {
  1693. X        *dy = 1;
  1694. X        finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1);
  1695. X    } else {
  1696. X        *dy = -1;
  1697. X        finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1);
  1698. X    }
  1699. X    *xx = dd.x;
  1700. X    *yy = dd.y;
  1701. X    return(levl[*xx][(*yy)+(*dy)].typ == STONE);
  1702. X}
  1703. X
  1704. X#ifdef ORACLE
  1705. Xboolean
  1706. Xplace_oracle(aroom,dy,xx,yy)
  1707. Xregister struct mkroom *aroom;
  1708. Xint *dy, *xx, *yy;
  1709. X{
  1710. X    if(!place_niche(aroom,dy,xx,yy)) return FALSE;
  1711. X
  1712. X    dosdoor(*xx,*yy,aroom,DOOR);
  1713. X    levl[*xx][*yy].doormask = D_NODOOR;
  1714. X    return TRUE;
  1715. X}
  1716. X#endif
  1717. X
  1718. X/* there should be one of these per trap */
  1719. Xconst char *engravings[] = {    "", "", "", "", "", "",
  1720. X                "?la? ?as ?er?", "ad ae?ar um",
  1721. X                "", "", "", "" ,""
  1722. X                , "", "ad ae?ar um"
  1723. X#ifdef SPELLS
  1724. X                ,""
  1725. X#endif
  1726. X                ,""
  1727. X#ifdef POLYSELF
  1728. X                ,""
  1729. X#endif
  1730. X                ,""
  1731. X                };
  1732. X
  1733. Xstatic void
  1734. Xmakeniche(trap_type)
  1735. Xint trap_type;
  1736. X{
  1737. X    register struct mkroom *aroom;
  1738. X    register struct rm *rm;
  1739. X    register int vct = 8;
  1740. X    int dy, xx, yy;
  1741. X    register struct trap *ttmp;
  1742. X
  1743. X    if(doorindex < DOORMAX)
  1744. X      while(vct--) {
  1745. X        aroom = &rooms[rn2(nroom)];
  1746. X        if(aroom->rtype != OROOM) continue;    /* not an ordinary room */
  1747. X        if(aroom->doorct == 1 && rn2(5)) continue;
  1748. X        if(!place_niche(aroom,&dy,&xx,&yy)) continue;
  1749. X
  1750. X        rm = &levl[xx][yy+dy];
  1751. X        if(trap_type || !rn2(4)) {
  1752. X
  1753. X        rm->typ = SCORR;
  1754. X        rm->scrsym = STONE_SYM;
  1755. X        if(trap_type) {
  1756. X            ttmp = maketrap(xx, yy+dy, trap_type);
  1757. X            ttmp->once = 1;
  1758. X            if (strlen(engravings[trap_type]) > 0)
  1759. X            make_engr_at(xx, yy-dy, engravings[trap_type]);
  1760. X        }
  1761. X        dosdoor(xx, yy, aroom, SDOOR);
  1762. X        } else {
  1763. X        rm->typ = CORR;
  1764. X        rm->scrsym = CORR_SYM;
  1765. X        if(rn2(7))
  1766. X            dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
  1767. X        else {
  1768. X            (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy);
  1769. X            if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy);
  1770. X        }
  1771. X        }
  1772. X        return;
  1773. X    }
  1774. X}
  1775. X
  1776. Xstatic void
  1777. Xmake_niches()
  1778. X{
  1779. X    register int ct = rnd((nroom>>1) + 1);
  1780. X    boolean    ltptr = TRUE,
  1781. X        vamp = TRUE;
  1782. X
  1783. X    while(ct--) {
  1784. X
  1785. X        if(dlevel > 15 && !rn2(6) && ltptr) {
  1786. X
  1787. X            ltptr = FALSE;
  1788. X            makeniche(LEVEL_TELEP);
  1789. X        } else if (dlevel > 5 && dlevel < 25
  1790. X               && !rn2(6) && vamp) {
  1791. X
  1792. X            vamp = FALSE;
  1793. X            makeniche(TRAPDOOR);
  1794. X        } else    makeniche(NO_TRAP);
  1795. X    }
  1796. X}
  1797. X
  1798. Xstatic void
  1799. Xmakebigroom()
  1800. X{
  1801. X    register int x,y,n;
  1802. X    register struct mkroom *croom;
  1803. X    register struct monst *tmonst;
  1804. X
  1805. X    /* make biggest possible room; make sure it's lit */
  1806. X    (void) maker(XLIM, COLNO - 2*XLIM - 1, YLIM, ROWNO - 2*YLIM - 1, TRUE);
  1807. X    croom = &rooms[0];
  1808. X
  1809. X    /* add extra monsters and goodies */
  1810. X    n = 10 + rn2(15);
  1811. X    while (n--) {
  1812. X        x = somex(croom);
  1813. X        y = somey(croom);
  1814. X        tmonst = makemon((struct permonst *) 0,x,y);
  1815. X        if (tmonst && tmonst->data==&mons[PM_GIANT_SPIDER])
  1816. X            (void) maketrap(x,y,WEB);
  1817. X        if (tmonst && rn2(2))
  1818. X            tmonst->msleep = 1;
  1819. X    }
  1820. X    n = 6 + rn2(10);
  1821. X    while (n--)
  1822. X        (void) mkobj_at(0,somex(croom),somey(croom));
  1823. X}
  1824. X
  1825. Xstatic void
  1826. Xmakevtele()
  1827. X{
  1828. X    makeniche(TELEP_TRAP);
  1829. X}
  1830. X
  1831. X#define rntwixt(L1,L2)    rn1((L2)-(L1),L1)
  1832. X
  1833. Xstatic void
  1834. Xinit_levels()
  1835. X{
  1836. X#if defined(STRONGHOLD) && defined(MUSIC)
  1837. X    register int x;
  1838. X#endif
  1839. X
  1840. X#ifdef LINT    /* handle constant in conditional context */
  1841. X    medusa_level = 0;
  1842. X#else
  1843. X    medusa_level = rn1(3, HELLLEVEL - 5);
  1844. X#endif /* LINT */
  1845. X#ifdef STRONGHOLD
  1846. X    stronghold_level = rn1(5, medusa_level)+1;
  1847. X# ifdef MUSIC
  1848. X    for (x=0; x<5; x++)
  1849. X        tune[x] = 'A' + rn2(7);
  1850. X    tune[5] = 0;
  1851. X# endif
  1852. X    /* The tower will be on 3 levels */
  1853. X    tower_level = rntwixt(stronghold_level, MAXLEVEL-2)+1;
  1854. X    /* We don't want the wizard in Vlad's tower */
  1855. X    do
  1856. X        wiz_level = rntwixt(stronghold_level, MAXLEVEL)+1;
  1857. X    while (wiz_level >= tower_level && wiz_level <= tower_level + 2);
  1858. X#else
  1859. X    wiz_level     = rntwixt(medusa_level, MAXLEVEL)+1;
  1860. X#endif /* STRONGHOLD /**/
  1861. X#ifdef WIZARD
  1862. X    if (!rn2(15) || wizard)
  1863. X#else
  1864. X    if (!rn2(15))
  1865. X#endif
  1866. X        /* between the middle of the dungeon and the medusa level */
  1867. X        bigroom_level = rntwixt(HELLLEVEL>>1, medusa_level);
  1868. X#ifdef REINCARNATION
  1869. X# ifdef WIZARD
  1870. X    if (!rn2(3) || wizard)
  1871. X# else
  1872. X    if (!rn2(3))
  1873. X# endif
  1874. X        rogue_level = rn1(5,10);
  1875. X#endif
  1876. X#ifdef ORACLE
  1877. X    oracle_level = rn1(4,5);
  1878. X#endif
  1879. X}
  1880. X
  1881. X#undef rntwixt
  1882. X
  1883. Xstatic void
  1884. Xmakelevel() {
  1885. X    register struct mkroom *croom, *troom;
  1886. X    register unsigned int tryct;
  1887. X    register int x,y;
  1888. X    struct monst *tmonst;    /* always put a web with a spider */
  1889. X
  1890. X    nroom = 0;
  1891. X    doorindex = 0;
  1892. X    rooms[0].hx = -1;    /* in case we are in a maze */
  1893. X
  1894. X    for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
  1895. X        levl[x][y] = zerorm;
  1896. X
  1897. X    oinit();    /* assign level dependent obj probabilities */
  1898. X    fountsound = 0;
  1899. X    sinksound = 0;
  1900. X
  1901. X    if (wiz_level == 0)
  1902. X        init_levels();
  1903. X    if (
  1904. X#ifndef STRONGHOLD
  1905. X        Inhell
  1906. X#else
  1907. X        dlevel >= stronghold_level || dlevel < 0
  1908. X#endif
  1909. X        || (dlevel > medusa_level && rn2(5))
  1910. X       ) {
  1911. X        makemaz();
  1912. X        return;
  1913. X    }
  1914. X
  1915. X    /* construct the rooms */
  1916. X    nroom = 0;
  1917. X    secret = FALSE;
  1918. X
  1919. X#ifdef REINCARNATION
  1920. X    if (dlevel == rogue_level) {
  1921. X        makeroguerooms();
  1922. X        makerogueghost();
  1923. X    } else
  1924. X#endif
  1925. X    if (dlevel == bigroom_level)
  1926. X        makebigroom();
  1927. X    else
  1928. X        (void) makerooms();
  1929. X
  1930. X    /* construct stairs (up and down in different rooms if possible) */
  1931. X    croom = &rooms[rn2(nroom)];
  1932. X    xdnstair = somex(croom);
  1933. X    ydnstair = somey(croom);
  1934. X    levl[xdnstair][ydnstair].scrsym = DN_SYM;
  1935. X    levl[xdnstair][ydnstair].typ = STAIRS;
  1936. X#ifdef MEDUSA
  1937. X    if (dlevel == medusa_level) {
  1938. X        struct monst *mtmp;
  1939. X
  1940. X        if (mtmp = makemon(&mons[PM_MEDUSA], xdnstair, ydnstair))
  1941. X            mtmp->msleep = 1;
  1942. X        for (tryct = rn1(1,3); tryct; tryct--) {
  1943. X            x = somex(croom); y = somey(croom);
  1944. X            if (goodpos(x,y))
  1945. X                (void) mk_tt_statue(x, y);
  1946. X        }
  1947. X    }
  1948. X#endif
  1949. X    if(nroom > 1) {
  1950. X        troom = croom;
  1951. X        croom = &rooms[rn2(nroom-1)];
  1952. X        if(croom >= troom) croom++;
  1953. X    }
  1954. X    xupstair = somex(croom);    /* %% < and > might be in the same place */
  1955. X    yupstair = somey(croom);
  1956. X    levl[xupstair][yupstair].scrsym = UP_SYM;
  1957. X    levl[xupstair][yupstair].typ = STAIRS;
  1958. X#ifdef STRONGHOLD
  1959. X    xdnladder = ydnladder = xupladder = yupladder = 0;
  1960. X#endif
  1961. X    is_maze_lev = FALSE;
  1962. X
  1963. X#ifdef SYSV
  1964. X    qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), comp);
  1965. X#else
  1966. X    qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), comp);
  1967. X#endif
  1968. X#ifdef REINCARNATION
  1969. X    if (dlevel == rogue_level) {
  1970. X       You("feel as though you were here in a previous lifetime.");
  1971. X       return;
  1972. X    }
  1973. X#endif
  1974. X    makecorridors();
  1975. X    make_niches();
  1976. X
  1977. X    /* make a secret treasure vault, not connected to the rest */
  1978. X    if(nroom <= (MAXNROFROOMS/2)) if(rn2(3)) {
  1979. X
  1980. X        troom = &rooms[nroom];
  1981. X        secret = TRUE;
  1982. X        if(makerooms()) {
  1983. X            troom->rtype = VAULT;        /* treasure vault */
  1984. X            for(x = troom->lx; x <= troom->hx; x++)
  1985. X            for(y = troom->ly; y <= troom->hy; y++)
  1986. X                mkgold((long)(rnd(dlevel*100) + 50), x, y);
  1987. X            if(!rn2(3))
  1988. X                makevtele();
  1989. X        }
  1990. X    }
  1991. X
  1992. X#ifdef WIZARD
  1993. X    if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else
  1994. X#endif
  1995. X#ifdef ORACLE
  1996. X    if(dlevel == oracle_level) mkroom(DELPHI);
  1997. X    /*  It is possible that we find no good place to set up Delphi.
  1998. X     *  It is also possible to get more than one Delphi using bones levels.
  1999. X     *  The first is not a problem; the second is a minor nuisance.
  2000. X     */
  2001. X    else
  2002. X#endif
  2003. X    if(dlevel > 1 && dlevel < medusa_level && rn2(dlevel) < 3) mkroom(SHOPBASE);
  2004. X    else
  2005. X#ifdef THRONES
  2006. X    if(dlevel > 4 && !rn2(6)) mkroom(COURT);
  2007. X    else
  2008. X#endif
  2009. X    if(dlevel > 6 && !rn2(7)) mkroom(ZOO);
  2010. X    else
  2011. X#ifdef ALTARS
  2012. X    if(dlevel > 8 && !rn2(5)) mkroom(TEMPLE);
  2013. X    else
  2014. X#endif
  2015. X    if(dlevel > 9 && !rn2(5) && !(mons[PM_KILLER_BEE].geno & G_GENOD))
  2016. X        mkroom(BEEHIVE);
  2017. X    else
  2018. X    if(dlevel > 11 && !rn2(6)) mkroom(MORGUE);
  2019. X    else
  2020. X#ifdef ARMY
  2021. X    if(dlevel > 14 && !rn2(4) && !(mons[PM_SOLDIER].geno & G_GENOD))
  2022. X        mkroom(BARRACKS);
  2023. X    else
  2024. X#endif
  2025. X    if(dlevel > 18 && !rn2(6)) mkroom(SWAMP);
  2026. X
  2027. X
  2028. X    /* for each room: put things inside */
  2029. X    for(croom = rooms; croom->hx > 0; croom++) {
  2030. X        register boolean boxinlev = FALSE;
  2031. X
  2032. X        if(croom->rtype != OROOM) continue;
  2033. X
  2034. X        /* put a sleeping monster inside */
  2035. X        /* Note: monster may be on the stairs. This cannot be
  2036. X           avoided: maybe the player fell through a trapdoor
  2037. X           while a monster was on the stairs. Conclusion:
  2038. X           we have to check for monsters on the stairs anyway. */
  2039. X
  2040. X        if(u.uhave_amulet || !rn2(3)) {
  2041. X            x = somex(croom); y = somey(croom);
  2042. X#ifdef REINCARNATION
  2043. X            if (dlevel == rogue_level)
  2044. X            tmonst = makemon(roguemon(), x, y);
  2045. X            else
  2046. X#endif
  2047. X            tmonst = makemon((struct permonst *) 0, x,y);
  2048. X            if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER])
  2049. X            (void) maketrap (x,y,WEB);
  2050. X        }
  2051. X        /* put traps and mimics inside */
  2052. X        goldseen = FALSE;
  2053. X        while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
  2054. X        if(!goldseen && !rn2(3)) mkgold(0L, somex(croom), somey(croom));
  2055. X#ifdef REINCARNATION
  2056. X        if (dlevel == rogue_level) goto skip_nonrogue;
  2057. X#endif
  2058. X#ifdef FOUNTAINS
  2059. X        if(!rn2(10)) mkfount(0,croom);
  2060. X#endif
  2061. X#ifdef SINKS
  2062. X        if(!rn2(60)) mksink(croom);
  2063. X#endif
  2064. X#ifdef ALTARS
  2065. X        if(!rn2(60)) mkaltar(croom);
  2066. X#endif
  2067. X        /* put statues inside */
  2068. X#ifdef MEDUSA
  2069. X        if(!rn2(dlevel == medusa_level ? 1 : 20)) {
  2070. X            if (!rn2(dlevel == medusa_level ? 2 : 50))
  2071. X                (void) mk_tt_statue(somex(croom), somey(croom));
  2072. X            else {
  2073. X                struct obj *otmp =
  2074. X                    mkstatue((struct permonst *)0,
  2075. X                        somex(croom), somey(croom));
  2076. X                if (dlevel == medusa_level && otmp) 
  2077. X                    otmp->spe = 0;
  2078. X                /* Medusa statues don't contain books */
  2079. X            }
  2080. X        }
  2081. X#else
  2082. X        if(!rn2(20))
  2083. X                (void) mkstatue((struct permonst *)0,
  2084. X                        somex(croom), somey(croom));
  2085. X#endif
  2086. X
  2087. X        /* put box/chest inside */
  2088. X        if(!rn2(20) && !boxinlev) {
  2089. X
  2090. X            boxinlev = TRUE;
  2091. X            (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
  2092. X                     somex(croom), somey(croom));
  2093. X        }
  2094. X
  2095. X#ifdef REINCARNATION
  2096. X    skip_nonrogue:
  2097. X#endif
  2098. X        if(!rn2(3)) {
  2099. X            (void) mkobj_at(0, somex(croom), somey(croom));
  2100. X            tryct = 0;
  2101. X            while(!rn2(5)) {
  2102. X                if(++tryct > 100){
  2103. X                    Printf("tryct overflow4\n");
  2104. X                    break;
  2105. X                }
  2106. X                (void) mkobj_at(0, somex(croom), somey(croom));
  2107. X            }
  2108. X        }
  2109. X    }
  2110. X}
  2111. X
  2112. Xvoid
  2113. Xmklev()
  2114. X{
  2115. X    if(getbones()) return;
  2116. X
  2117. X    in_mklev = TRUE;
  2118. X    makelevel();
  2119. X    bound_digging();
  2120. X    in_mklev = FALSE;
  2121. X}
  2122. X
  2123. Xstatic boolean
  2124. Xbydoor(x, y)
  2125. Xregister xchar x, y;
  2126. X{
  2127. X    register boolean tmp1, tmp2;
  2128. X
  2129. X    /* break up large expression to help some compilers */
  2130. X    tmp1 = (IS_DOOR(levl[x+1][y].typ) || levl[x+1][y].typ == SDOOR ||
  2131. X        IS_DOOR(levl[x-1][y].typ) || levl[x-1][y].typ == SDOOR);
  2132. X    tmp2 = (IS_DOOR(levl[x][y+1].typ) || levl[x][y+1].typ == SDOOR ||
  2133. X        IS_DOOR(levl[x][y-1].typ) || levl[x][y-1].typ == SDOOR);
  2134. X    return(tmp1 || tmp2);
  2135. X}
  2136. X
  2137. X/* see whether it is allowable to create a door at [x,y] */
  2138. Xint
  2139. Xokdoor(x,y)
  2140. Xregister xchar x, y;
  2141. X{
  2142. X    register boolean near_door = bydoor(x, y);
  2143. X
  2144. X    return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&
  2145. X               doorindex < DOORMAX && !near_door);
  2146. X}
  2147. X
  2148. Xvoid
  2149. Xdodoor(x,y,aroom)
  2150. Xregister int x, y;
  2151. Xregister struct mkroom *aroom;
  2152. X{
  2153. X    if(doorindex >= DOORMAX) {
  2154. X        impossible("DOORMAX exceeded?");
  2155. X        return;
  2156. X    }
  2157. X    if(!okdoor(x,y) && nxcor)
  2158. X        return;
  2159. X    dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
  2160. X}
  2161. X
  2162. Xstatic boolean
  2163. Xoccupied(x, y)
  2164. Xregister xchar x, y;
  2165. X{
  2166. X    return(t_at(x, y) || levl[x][y].typ == STAIRS
  2167. X#ifdef FOUNTAINS
  2168. X        || IS_FOUNTAIN(levl[x][y].typ)
  2169. X#endif
  2170. X#ifdef THRONES
  2171. X        || IS_THRONE(levl[x][y].typ)
  2172. X#endif
  2173. X#ifdef SINKS
  2174. X        || IS_SINK(levl[x][y].typ)
  2175. X#endif
  2176. X#ifdef ALTARS
  2177. X        || levl[x][y].typ == ALTAR
  2178. X#endif
  2179. X        );
  2180. X}
  2181. X
  2182. X/* make a trap somewhere (in croom if mazeflag = 0) */
  2183. Xvoid
  2184. Xmktrap(num, mazeflag, croom)
  2185. Xregister int num, mazeflag;
  2186. Xregister struct mkroom *croom;
  2187. X{
  2188. X    register struct trap *ttmp;
  2189. X    register int kind,nomonst,nomimic,nospider,
  2190. X#ifdef POLYSELF
  2191. X            nopoly,
  2192. X#endif
  2193. X            nospikes, nolevltp,
  2194. X            nolandmine,
  2195. X            tryct = 0;
  2196. X
  2197. X    xchar mx,my;
  2198. X
  2199. X    if(!num || num >= TRAPNUM) {
  2200. X        nomonst = (dlevel < 4) ? 1 : 0;
  2201. X        nolevltp = (dlevel < 5) ? 1 : 0;
  2202. X        nospikes = (dlevel < 6) ? 1 : 0;
  2203. X        nospider = (dlevel < 7) ? 1 : 0;
  2204. X#ifdef POLYSELF
  2205. X        nopoly = (dlevel < 6) ? 1 : 0;
  2206. X#endif
  2207. X        nolandmine = (dlevel < 5) ? 1 : 0;
  2208. X        nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
  2209. X        if((mons[PM_SMALL_MIMIC].geno & G_GENOD) &&
  2210. X           (mons[PM_LARGE_MIMIC].geno & G_GENOD) &&
  2211. X           (mons[PM_GIANT_MIMIC].geno & G_GENOD))
  2212. X            nomimic = 1;
  2213. X        if(mons[PM_GIANT_SPIDER].geno & G_GENOD)
  2214. X            nospider = 1;
  2215. X
  2216. X        do {
  2217. X#ifdef REINCARNATION
  2218. X            if (dlevel==rogue_level) {
  2219. X            switch(rn2(7)) {
  2220. X                 case 0: kind = BEAR_TRAP; break;
  2221. X                 case 1: kind = ARROW_TRAP; break;
  2222. X                 case 2: kind = DART_TRAP; break;
  2223. X                 case 3: kind = TRAPDOOR; break;
  2224. X                 case 4: kind = PIT; break;
  2225. X                 case 5: kind = SLP_GAS_TRAP; break;
  2226. X                 case 6: kind = RUST_TRAP; break;
  2227. X            }
  2228. X            } else
  2229. X#endif
  2230. X                kind = rnd(TRAPNUM-1);
  2231. X            if((kind == MONST_TRAP && (nomonst && nomimic))
  2232. X            || ((kind == WEB) && nospider)
  2233. X            || (kind == SPIKED_PIT && nospikes)
  2234. X            || (kind == LEVEL_TELEP && nolevltp)
  2235. X#ifdef POLYSELF
  2236. X            || (kind == POLY_TRAP && nopoly)
  2237. X#endif
  2238. X            || (kind == LANDMINE && nolandmine)
  2239. X            )  kind = NO_TRAP;
  2240. X        } while(kind == NO_TRAP);
  2241. X    } else kind = num;
  2242. X
  2243. X    if(kind == MONST_TRAP && !nomimic && !rn2(4) && !mazeflag) {
  2244. X        register struct monst *mtmp;
  2245. X
  2246. X        do {
  2247. X            if(++tryct > 200) return;
  2248. X            /* note: fakedoor maybe on actual door */
  2249. X            if(rn2(2)){
  2250. X                if(rn2(2))    mx = croom->hx+1;
  2251. X                else    mx = croom->lx-1;
  2252. X                my = somey(croom);
  2253. X            } else {
  2254. X                if(rn2(2))    my = croom->hy+1;
  2255. X                else    my = croom->ly-1;
  2256. X                mx = somex(croom);
  2257. X            }
  2258. X        } while(levl[mx][my].mmask);
  2259. X
  2260. X        if((mtmp = makemon(mkclass(S_MIMIC), mx, my))) {
  2261. X            mtmp->mimic = 1;
  2262. X            mtmp->mappearance = DOOR_SYM;
  2263. X        }
  2264. X        return;
  2265. X    }
  2266. X
  2267. X    do {
  2268. X        if(++tryct > 200)
  2269. X            return;
  2270. X        if(mazeflag){
  2271. X            coord mm;
  2272. X            mazexy(&mm);
  2273. X            mx = mm.x;
  2274. X            my = mm.y;
  2275. X        } else {
  2276. X            mx = somex(croom);
  2277. X            my = somey(croom);
  2278. X        }
  2279. X    } while(occupied(mx, my));
  2280. X
  2281. X    ttmp = maketrap(mx, my, kind);
  2282. X    if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], mx, my);
  2283. X    if(mazeflag && !rn2(10) && ttmp->ttyp < MONST_TRAP)
  2284. X        ttmp->tseen = 1;
  2285. X}
  2286. X
  2287. X#ifdef FOUNTAINS
  2288. Xvoid
  2289. Xmkfount(mazeflag,croom)
  2290. Xregister struct mkroom *croom;
  2291. Xregister int mazeflag;
  2292. X{
  2293. X    register xchar mx,my;
  2294. X    register int tryct = 0;
  2295. X
  2296. X    do {
  2297. X        if(++tryct > 200) return;
  2298. X        if(mazeflag) {
  2299. X         coord mm;
  2300. X         mazexy(&mm);
  2301. X         mx = mm.x;
  2302. X         my = mm.y;
  2303. X        } else {
  2304. X         mx = somex(croom);
  2305. X         my = somey(croom);
  2306. X        }
  2307. X    } while(occupied(mx, my) || bydoor(mx, my));
  2308. X
  2309. X    /* Put a fountain at mx, my */
  2310. X    levl[mx][my].typ = FOUNTAIN;
  2311. X    levl[mx][my].scrsym = FOUNTAIN_SYM;
  2312. X
  2313. X    fountsound++;
  2314. X}
  2315. X#endif /* FOUNTAINS /**/
  2316. X
  2317. X#ifdef SINKS
  2318. Xstatic void
  2319. Xmksink(croom)
  2320. Xregister struct mkroom *croom;
  2321. X{
  2322. X    register xchar mx,my;
  2323. X    register int tryct = 0;
  2324. X
  2325. X    do {
  2326. X        if(++tryct > 200) return;
  2327. X        mx = somex(croom);
  2328. X        my = somey(croom);
  2329. X    } while(occupied(mx, my) || bydoor(mx, my));
  2330. X
  2331. X    /* Put a sink at mx, my */
  2332. X    levl[mx][my].typ = SINK;
  2333. X    levl[mx][my].scrsym = SINK_SYM;
  2334. X
  2335. X    sinksound++;
  2336. X}
  2337. X#endif /* SINKS /**/
  2338. X
  2339. X
  2340. X#ifdef ALTARS
  2341. Xstatic void
  2342. Xmkaltar(croom)
  2343. Xregister struct mkroom *croom;
  2344. X{
  2345. X    register xchar mx,my;
  2346. X    register int tryct = 0;
  2347. X
  2348. X    if(croom->rtype != OROOM) return;
  2349. X
  2350. X    do {
  2351. X        if(++tryct > 200) return;
  2352. X        mx = somex(croom);
  2353. X        my = somey(croom);
  2354. X    } while(occupied(mx, my) || bydoor(mx, my));
  2355. X
  2356. X    /* Put an altar at mx, my */
  2357. X    levl[mx][my].typ = ALTAR;
  2358. X    levl[mx][my].scrsym = ALTAR_SYM;
  2359. X    /* 0 - A_CHAOS, 1 - A_NEUTRAL, 2 - A_LAW */
  2360. X    levl[mx][my].altarmask = rn2((int)A_LAW+1);
  2361. X}
  2362. X#endif /* ALTARS /**/
  2363. END_OF_FILE
  2364. if test 27014 -ne `wc -c <'src/mklev.c'`; then
  2365.     echo shar: \"'src/mklev.c'\" unpacked with wrong size!
  2366. fi
  2367. # end of 'src/mklev.c'
  2368. fi
  2369. echo shar: End of archive 20 \(of 38\).
  2370. cp /dev/null ark20isdone
  2371. MISSING=""
  2372. 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 ; do
  2373.     if test ! -f ark${I}isdone ; then
  2374.     MISSING="${MISSING} ${I}"
  2375.     fi
  2376. done
  2377. if test "${MISSING}" = "" ; then
  2378.     echo You have unpacked all 38 archives.
  2379.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2380. else
  2381.     echo You still need to unpack the following archives:
  2382.     echo "        " ${MISSING}
  2383. fi
  2384. ##  End of shell archive.
  2385. exit 0
  2386.