home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / part64 < prev    next >
Encoding:
Internet Message Format  |  1993-02-03  |  57.2 KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i072:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part64/108
  5. Message-ID: <4375@master.CNA.TEK.COM>
  6. Date: 1 Feb 93 19:50:22 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2388
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1622
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 72
  14. Archive-name: nethack31/Part64
  15. Supersedes: nethack3p9: Volume 10, Issue 46-102
  16. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 64 (of 108)."
  27. # Contents:  src/dbridge.c util/lev_main.c
  28. # Wrapped by billr@saab on Wed Jan 27 16:09:12 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'src/dbridge.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'src/dbridge.c'\"
  32. else
  33. echo shar: Extracting \"'src/dbridge.c'\" \(22283 characters\)
  34. sed "s/^X//" >'src/dbridge.c' <<'END_OF_FILE'
  35. X/*    SCCS Id: @(#)dbridge.c    3.1    92/10/24    */
  36. X/*    Copyright (c) 1989 by Jean-Christophe Collet */
  37. X/* NetHack may be freely redistributed.  See license for details. */
  38. X
  39. X/*
  40. X * This file contains the drawbridge manipulation (create, open, close,
  41. X * destroy).
  42. X *
  43. X * Added comprehensive monster-handling, and the "entity" structure to 
  44. X * deal with players as well. - 11/89
  45. X */
  46. X
  47. X#include "hack.h"
  48. X
  49. X#ifdef OVLB
  50. Xstatic void FDECL(get_wall_for_db, (int *, int *));
  51. Xstatic struct entity *FDECL(e_at, (int, int));
  52. Xstatic void FDECL(m_to_e, (struct monst *, XCHAR_P, XCHAR_P, struct entity *));
  53. Xstatic void FDECL(u_to_e, (struct entity *));
  54. Xstatic void FDECL(set_entity, (int, int, struct entity *));
  55. Xstatic char *FDECL(e_nam, (struct entity *));
  56. X#ifdef D_DEBUG
  57. Xstatic char *FDECL(Enam, (struct entity *)); /* unused */
  58. X#endif
  59. Xstatic char *FDECL(E_phrase, (struct entity *, const char *));
  60. Xstatic boolean FDECL(e_survives_at, (struct entity *, int, int));
  61. Xstatic void FDECL(e_died, (struct entity *, int, int));
  62. Xstatic boolean FDECL(automiss, (struct entity *));
  63. Xstatic boolean FDECL(e_missed, (struct entity *, BOOLEAN_P));
  64. Xstatic boolean FDECL(e_jumps, (struct entity *));
  65. Xstatic void FDECL(do_entity, (struct entity *));
  66. X#endif /* OVLB */
  67. X
  68. X#ifdef OVL0
  69. X
  70. Xboolean
  71. Xis_pool(x,y)
  72. Xint x,y;
  73. X{
  74. X       register schar ltyp = levl[x][y].typ;
  75. X       if(ltyp == POOL || ltyp == MOAT || ltyp == WATER) return TRUE;
  76. X       if(ltyp == DRAWBRIDGE_UP &&
  77. X               (levl[x][y].drawbridgemask & DB_UNDER) == DB_MOAT) return TRUE;
  78. X       return FALSE;
  79. X}
  80. X
  81. Xboolean
  82. Xis_lava(x,y)
  83. Xint x,y;
  84. X{
  85. X       register schar ltyp = levl[x][y].typ;
  86. X       if(ltyp == LAVAPOOL ||
  87. X      (ltyp == DRAWBRIDGE_UP &&
  88. X       (levl[x][y].drawbridgemask & DB_UNDER) == DB_LAVA)) return TRUE;
  89. X       return FALSE;
  90. X}
  91. X
  92. Xboolean
  93. Xis_ice(x,y)
  94. Xint x,y;
  95. X{
  96. X    register schar ltyp = levl[x][y].typ;
  97. X    if (ltyp == ICE ||
  98. X        (ltyp == DRAWBRIDGE_UP &&
  99. X        (levl[x][y].drawbridgemask & DB_UNDER) == DB_ICE)) return TRUE;
  100. X    return FALSE;
  101. X}
  102. X
  103. X#endif /* OVL0 */
  104. X
  105. X#ifdef OVL1
  106. X
  107. X/* 
  108. X * We want to know whether a wall (or a door) is the portcullis (passageway)
  109. X * of an eventual drawbridge.
  110. X *
  111. X * Return value:  the direction of the drawbridge.
  112. X */
  113. X
  114. Xint
  115. Xis_drawbridge_wall(x,y)
  116. Xint x,y;
  117. X{
  118. X    struct rm *lev;
  119. X
  120. X    lev = &levl[x][y];
  121. X    if (lev->typ != DOOR && lev->typ != DBWALL)
  122. X        return (-1);
  123. X
  124. X    if (IS_DRAWBRIDGE(levl[x+1][y].typ) &&
  125. X        (levl[x+1][y].drawbridgemask & DB_DIR) == DB_WEST)
  126. X        return (DB_WEST);
  127. X    if (IS_DRAWBRIDGE(levl[x-1][y].typ) && 
  128. X        (levl[x-1][y].drawbridgemask & DB_DIR) == DB_EAST)
  129. X        return (DB_EAST);
  130. X    if (IS_DRAWBRIDGE(levl[x][y-1].typ) && 
  131. X        (levl[x][y-1].drawbridgemask & DB_DIR) == DB_SOUTH)
  132. X        return (DB_SOUTH);
  133. X    if (IS_DRAWBRIDGE(levl[x][y+1].typ) && 
  134. X        (levl[x][y+1].drawbridgemask & DB_DIR) == DB_NORTH)
  135. X        return (DB_NORTH);
  136. X
  137. X    return (-1);
  138. X}
  139. X
  140. X/*
  141. X * Use is_db_wall where you want to verify that a
  142. X * drawbridge "wall" is UP in the location x, y
  143. X * (instead of UP or DOWN, as with is_drawbridge_wall). 
  144. X */ 
  145. Xboolean
  146. Xis_db_wall(x,y)
  147. Xint x,y;
  148. X{
  149. X    return( levl[x][y].typ == DBWALL );
  150. X}
  151. X
  152. X
  153. X/*
  154. X * Return true with x,y pointing to the drawbridge if x,y initially indicate
  155. X * a drawbridge or drawbridge wall.
  156. X */
  157. Xboolean
  158. Xfind_drawbridge(x,y)
  159. Xint *x,*y;
  160. X{
  161. X    int dir;
  162. X
  163. X    if (IS_DRAWBRIDGE(levl[*x][*y].typ))
  164. X        return TRUE;
  165. X    dir = is_drawbridge_wall(*x,*y);
  166. X    if (dir >= 0) {
  167. X        switch(dir) {
  168. X            case DB_NORTH: (*y)++; break;
  169. X            case DB_SOUTH: (*y)--; break;
  170. X            case DB_EAST:  (*x)--; break;
  171. X            case DB_WEST:  (*x)++; break;
  172. X        }
  173. X        return TRUE;
  174. X    }
  175. X    return FALSE;
  176. X}
  177. X
  178. X#endif /* OVL1 */
  179. X#ifdef OVLB
  180. X
  181. X/* 
  182. X * Find the drawbridge wall associated with a drawbridge.
  183. X */
  184. Xstatic void
  185. Xget_wall_for_db(x,y)
  186. Xint *x,*y;
  187. X{
  188. X    switch (levl[*x][*y].drawbridgemask & DB_DIR) {
  189. X        case DB_NORTH: (*y)--; break;
  190. X        case DB_SOUTH: (*y)++; break;
  191. X        case DB_EAST:  (*x)++; break;
  192. X        case DB_WEST:  (*x)--; break;
  193. X    }
  194. X}
  195. X
  196. X/*
  197. X * Creation of a drawbridge at pos x,y.
  198. X *     dir is the direction.
  199. X *     flag must be put to TRUE if we want the drawbridge to be opened.
  200. X */
  201. X
  202. Xboolean
  203. Xcreate_drawbridge(x,y,dir,flag)
  204. Xint x,y,dir;
  205. Xboolean flag;
  206. X{
  207. X    int x2,y2;
  208. X    boolean horiz;
  209. X    boolean lava = levl[x][y].typ == LAVAPOOL; /* assume initialized map */
  210. X
  211. X    x2 = x; y2 = y;
  212. X    switch(dir) {
  213. X        case DB_NORTH:
  214. X            horiz = TRUE;
  215. X            y2--;
  216. X            break;
  217. X        case DB_SOUTH:
  218. X            horiz = TRUE;
  219. X            y2++;
  220. X            break;
  221. X        case DB_EAST:
  222. X            horiz = FALSE;
  223. X            x2++;
  224. X            break;
  225. X        default:
  226. X            impossible("bad direction in create_drawbridge");
  227. X            /* fall through */
  228. X        case DB_WEST:
  229. X            horiz = FALSE;
  230. X            x2--;
  231. X            break;
  232. X    }
  233. X    if (!IS_WALL(levl[x2][y2].typ))
  234. X        return(FALSE);
  235. X    if (flag) {             /* We want the bridge open */
  236. X        levl[x][y].typ = DRAWBRIDGE_DOWN;
  237. X        levl[x2][y2].typ = DOOR;
  238. X        levl[x2][y2].doormask = D_NODOOR;
  239. X    } else {
  240. X        levl[x][y].typ = DRAWBRIDGE_UP;
  241. X        levl[x2][y2].typ = DBWALL;
  242. X        /* Drawbridges are non-diggable. */
  243. X        levl[x2][y2].diggable = W_NONDIGGABLE;
  244. X    }
  245. X    levl[x][y].horizontal = !horiz;
  246. X    levl[x2][y2].horizontal = horiz;
  247. X    levl[x][y].drawbridgemask = dir;
  248. X    if(lava) levl[x][y].drawbridgemask |= DB_LAVA;
  249. X    return(TRUE);           
  250. X}
  251. X
  252. Xstruct entity {
  253. X    struct monst *emon;      /* youmonst for the player */
  254. X    struct permonst *edata;   /* must be non-zero for record to be valid */
  255. X    int ex, ey;
  256. X};
  257. X
  258. X#define ENTITIES 2
  259. X
  260. Xstatic struct entity NEARDATA occupants[ENTITIES];
  261. X
  262. Xstatic
  263. Xstruct entity *
  264. Xe_at(x, y)
  265. Xint x, y;
  266. X{
  267. X    int entitycnt;
  268. X    
  269. X    for (entitycnt = 0; entitycnt < ENTITIES; entitycnt++)
  270. X        if ((occupants[entitycnt].edata) && 
  271. X            (occupants[entitycnt].ex == x) &&
  272. X            (occupants[entitycnt].ey == y))
  273. X            break;
  274. X#ifdef D_DEBUG
  275. X    pline("entitycnt = %d", entitycnt);
  276. X    wait_synch();
  277. X#endif
  278. X    return((entitycnt == ENTITIES)? 
  279. X           (struct entity *)0 : &(occupants[entitycnt]));
  280. X}
  281. X
  282. Xstatic void
  283. Xm_to_e(mtmp, x, y, etmp)
  284. Xstruct monst *mtmp;
  285. Xxchar x, y;
  286. Xstruct entity *etmp;
  287. X{
  288. X    etmp->emon = mtmp;
  289. X    if (mtmp) {
  290. X        etmp->ex = x;
  291. X        etmp->ey = y;
  292. X        if (mtmp->wormno && (x != mtmp->mx || y != mtmp->my))
  293. X            etmp->edata = &mons[PM_LONG_WORM_TAIL];
  294. X        else
  295. X            etmp->edata = mtmp->data;
  296. X    } else
  297. X        etmp->edata = (struct permonst *)0;
  298. X}
  299. X
  300. Xstatic void
  301. Xu_to_e(etmp)
  302. Xstruct entity *etmp;
  303. X{
  304. X    etmp->emon = &youmonst;
  305. X    etmp->ex = u.ux;
  306. X    etmp->ey = u.uy;
  307. X    etmp->edata = uasmon;
  308. X}
  309. X
  310. Xstatic void
  311. Xset_entity(x, y, etmp)
  312. Xint x, y;
  313. Xstruct entity *etmp;
  314. X{
  315. X    if ((x == u.ux) && (y == u.uy))
  316. X        u_to_e(etmp);
  317. X    else
  318. X        if (MON_AT(x, y))
  319. X            m_to_e(m_at(x, y), x, y, etmp);
  320. X        else
  321. X            etmp->edata = (struct permonst *)0;
  322. X}
  323. X
  324. X#define is_u(etmp) (etmp->emon == &youmonst)
  325. X#define e_canseemon(etmp) (is_u(etmp) ? (boolean)TRUE : canseemon(etmp->emon)) 
  326. X
  327. X/*
  328. X * e_strg is a utility routine which is not actually in use anywhere, since 
  329. X * the specialized routines below suffice for all current purposes. 
  330. X */
  331. X
  332. X/* #define e_strg(etmp, func) (is_u(etmp)? (char *)0 : func(etmp->emon)) */
  333. X
  334. Xstatic char *
  335. Xe_nam(etmp)
  336. Xstruct entity *etmp;
  337. X{
  338. X    return(is_u(etmp)? "you" : mon_nam(etmp->emon));
  339. X}
  340. X
  341. X#ifdef D_DEBUG
  342. X/*
  343. X * Enam is another unused utility routine:  E_phrase is preferable.
  344. X */
  345. X
  346. Xstatic char *
  347. XEnam(etmp)
  348. Xstruct entity *etmp;
  349. X{
  350. X    return(is_u(etmp)? "You" : Monnam(etmp->emon));
  351. X}
  352. X#endif /* D_DEBUG */
  353. X
  354. X/*
  355. X * Generates capitalized entity name, makes 2nd -> 3rd person conversion on 
  356. X * verb, where necessary.
  357. X */
  358. X
  359. Xstatic char *
  360. XE_phrase(etmp, verb)
  361. Xstruct entity *etmp;
  362. Xconst char *verb;
  363. X{
  364. X    static char wholebuf[80];
  365. X    char verbbuf[30];
  366. X
  367. X    if (is_u(etmp)) 
  368. X        Strcpy(wholebuf, "You");
  369. X    else
  370. X        Strcpy(wholebuf, Monnam(etmp->emon));
  371. X    if (!*verb)
  372. X        return(wholebuf);
  373. X    Strcat(wholebuf, " ");
  374. X    verbbuf[0] = '\0';
  375. X    if (is_u(etmp)) 
  376. X        Strcpy(verbbuf, verb);
  377. X    else {
  378. X        if (!strcmp(verb, "are"))
  379. X            Strcpy(verbbuf, "is");
  380. X        if (!strcmp(verb, "have"))
  381. X            Strcpy(verbbuf, "has");
  382. X        if (!verbbuf[0]) {
  383. X            Strcpy(verbbuf, verb);
  384. X            switch (verbbuf[strlen(verbbuf) - 1]) {
  385. X                case 'y':
  386. X                    verbbuf[strlen(verbbuf) - 1] = '\0';
  387. X                    Strcat(verbbuf, "ies");
  388. X                    break;
  389. X                case 'h':
  390. X                case 'o':
  391. X                case 's':
  392. X                    Strcat(verbbuf, "es");
  393. X                    break;
  394. X                default:
  395. X                    Strcat(verbbuf, "s");
  396. X                    break;
  397. X            }
  398. X        }
  399. X    }
  400. X    Strcat(wholebuf, verbbuf);
  401. X    return(wholebuf);
  402. X}
  403. X
  404. X/*
  405. X * Simple-minded "can it be here?" routine
  406. X */
  407. X
  408. Xstatic boolean
  409. Xe_survives_at(etmp, x, y)
  410. Xstruct entity *etmp;
  411. Xint x, y;
  412. X{
  413. X    if (noncorporeal(etmp->edata))
  414. X        return(TRUE);
  415. X    if (is_pool(x, y))
  416. X        return((is_u(etmp) && (Wwalking || Magical_breathing || Levitation)) ||
  417. X               is_swimmer(etmp->edata) || is_flyer(etmp->edata) ||
  418. X               is_floater(etmp->edata));
  419. X    /* must force call to lava_effects in e_died if is_u */
  420. X    if (is_lava(x, y))
  421. X        return(is_u(etmp) ? !!Levitation : resists_fire(etmp->edata));
  422. X    if (is_db_wall(x, y))
  423. X        return(passes_walls(etmp->edata));
  424. X    return(TRUE);
  425. X}
  426. X
  427. Xstatic void
  428. Xe_died(etmp, dest, how)
  429. Xstruct entity *etmp;
  430. Xint dest, how;
  431. X{
  432. X    if (is_u(etmp)) {
  433. X        if (how == DROWNING)
  434. X            (void) drown();
  435. X        if (how == BURNING)
  436. X            (void) lava_effects();
  437. X        else {
  438. X            coord xy;
  439. X
  440. X            killer_format = KILLED_BY_AN;
  441. X            killer = "falling drawbridge";
  442. X            done(how);
  443. X            /* So, you didn't die */
  444. X            if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
  445. X                if (enexto(&xy, etmp->ex, etmp->ey,
  446. X                                etmp->edata)) {
  447. X                pline("A %s force teleports you away...",
  448. X                      Hallucination ? "normal" : "strange");
  449. X                teleds(xy.x, xy.y);
  450. X                }
  451. X                /* otherwise on top of the drawbridge is the
  452. X                 * only viable spot in the dungeon, so stay there
  453. X                 */
  454. X            }
  455. X        }
  456. X    } else {
  457. X        xkilled(etmp->emon, dest);
  458. X        etmp->edata = (struct permonst *)0;    
  459. X    }
  460. X}
  461. X
  462. X
  463. X/*
  464. X * These are never directly affected by a bridge or portcullis.
  465. X */
  466. X
  467. Xstatic boolean
  468. Xautomiss(etmp)
  469. Xstruct entity *etmp;
  470. X{
  471. X    return(passes_walls(etmp->edata) || noncorporeal(etmp->edata));
  472. X}
  473. X
  474. X/*
  475. X * Does falling drawbridge or portcullis miss etmp?
  476. X */
  477. X
  478. Xstatic boolean
  479. Xe_missed(etmp, chunks)
  480. Xstruct entity *etmp;
  481. Xboolean chunks;
  482. X{
  483. X    int misses;
  484. X
  485. X#ifdef D_DEBUG
  486. X    if (chunks)
  487. X        pline("Do chunks miss?");
  488. X#endif
  489. X    if (automiss(etmp))
  490. X        return(TRUE);    
  491. X
  492. X    if (is_flyer(etmp->edata) && 
  493. X        (is_u(etmp)? !Sleeping : 
  494. X         (etmp->emon->mcanmove && !etmp->emon->msleep)))
  495. X                         /* flying requires mobility */
  496. X        misses = 5;    /* out of 8 */    
  497. X    else
  498. X        if (is_floater(etmp->edata) ||
  499. X            (is_u(etmp) && Levitation))     /* doesn't require mobility */
  500. X            misses = 3;
  501. X        else
  502. X            if (chunks && is_pool(etmp->ex, etmp->ey))
  503. X                misses = 2;             /* sitting ducks */
  504. X            else
  505. X                misses = 0;      
  506. X
  507. X    if (is_db_wall(etmp->ex, etmp->ey))
  508. X        misses -= 3;                    /* less airspace */
  509. X
  510. X#ifdef D_DEBUG
  511. X    pline("Miss chance = %d (out of 8)", misses);
  512. X#endif
  513. X
  514. X    return((misses >= rnd(8))? TRUE : FALSE);
  515. X}
  516. X
  517. X/*
  518. X * Can etmp jump from death?
  519. X */ 
  520. X
  521. Xstatic boolean
  522. Xe_jumps(etmp)
  523. Xstruct entity *etmp;
  524. X{
  525. X    int tmp = 4;         /* out of 10 */
  526. X
  527. X    if (is_u(etmp)? (Sleeping || Fumbling) : 
  528. X                (!etmp->emon->mcanmove || etmp->emon->msleep || 
  529. X             !etmp->edata->mmove   || etmp->emon->wormno))
  530. X        return(FALSE);
  531. X
  532. X    if (is_u(etmp)? Confusion : etmp->emon->mconf)
  533. X        tmp -= 2;
  534. X
  535. X    if (is_u(etmp)? Stunned : etmp->emon->mstun)
  536. X        tmp -= 3;
  537. X
  538. X    if (is_db_wall(etmp->ex, etmp->ey))
  539. X        tmp -= 2;                /* less room to maneuver */
  540. X    
  541. X#ifdef D_DEBUG
  542. X    pline("%s to jump (%d chances in 10)", E_phrase(etmp, "try"), tmp);
  543. X#endif
  544. X    return((tmp >= rnd(10))? TRUE : FALSE);
  545. X}
  546. X
  547. Xstatic void
  548. Xdo_entity(etmp)
  549. Xstruct entity *etmp;
  550. X{
  551. X    int newx, newy, at_portcullis, oldx, oldy;
  552. X    boolean must_jump = FALSE, relocates = FALSE, e_inview;
  553. X    struct rm *crm;
  554. X
  555. X    if (!etmp->edata)
  556. X        return;
  557. X
  558. X    e_inview = e_canseemon(etmp);
  559. X
  560. X    oldx = etmp->ex;
  561. X    oldy = etmp->ey;
  562. X
  563. X    at_portcullis = is_db_wall(oldx, oldy);
  564. X
  565. X    crm = &levl[oldx][oldy];
  566. X
  567. X    if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) {
  568. X        char edifice[20];
  569. X
  570. X        if (e_inview) {
  571. X            *edifice = '\0';
  572. X            if ((crm->typ == DRAWBRIDGE_DOWN) ||
  573. X                    (crm->typ == DRAWBRIDGE_UP))
  574. X                Strcpy(edifice, "drawbridge");
  575. X            else
  576. X                     if (at_portcullis) 
  577. X                    Strcpy(edifice, "portcullis");
  578. X            if (*edifice)
  579. X                pline("The %s passes through %s!", edifice, 
  580. X                            e_nam(etmp));            
  581. X        }
  582. X        return;
  583. X    }
  584. X    if (e_missed(etmp, FALSE)) { 
  585. X        if (at_portcullis)
  586. X            pline("The portcullis misses %s!",
  587. X                  e_nam(etmp));
  588. X#ifdef D_DEBUG
  589. X        else
  590. X            pline("The drawbridge misses %s!", 
  591. X                  e_nam(etmp));
  592. X#endif
  593. X        if (e_survives_at(etmp, oldx, oldy)) 
  594. X            return;
  595. X        else {
  596. X#ifdef D_DEBUG
  597. X            pline("Mon can't survive here");
  598. X#endif
  599. X            if (at_portcullis)
  600. X                must_jump = TRUE;
  601. X            else
  602. X                relocates = TRUE; /* just ride drawbridge in */
  603. X        }
  604. X    } else {
  605. X        if (crm->typ == DRAWBRIDGE_DOWN) {
  606. X            pline("%s crushed underneath the drawbridge.",
  607. X                        E_phrase(etmp, "are"));             /* no jump */
  608. X            e_died(etmp, e_inview? 3 : 2, CRUSHING);/* no corpse */
  609. X            return;   /* Note: Beyond this point, we know we're  */
  610. X        }                 /* not at an opened drawbridge, since all  */
  611. X        must_jump = TRUE; /* *missable* creatures survive on the     */
  612. X    }              /* square, and all the unmissed ones die.  */
  613. X    if (must_jump) {
  614. X        if (at_portcullis) {
  615. X        if (e_jumps(etmp)) {
  616. X            relocates = TRUE;
  617. X#ifdef D_DEBUG
  618. X            pline("Jump succeeds!");
  619. X#endif
  620. X        } else {
  621. X            if (e_inview)
  622. X            pline("%s crushed by the falling portcullis!",
  623. X                  E_phrase(etmp, "are"));
  624. X            else if (flags.soundok)
  625. X            You("hear a crushing sound.");
  626. X            e_died(etmp, e_inview? 3 : 2, CRUSHING);
  627. X            /* no corpse */
  628. X            return;
  629. X        }
  630. X        } else { /* tries to jump off bridge to original square */
  631. X        relocates = !e_jumps(etmp); 
  632. X#ifdef D_DEBUG
  633. X        pline("Jump %s!", (relocates)? "fails" : "succeeds");
  634. X#endif
  635. X        }
  636. X    }
  637. X
  638. X/*
  639. X * Here's where we try to do relocation.  Assumes that etmp is not arriving
  640. X * at the portcullis square while the drawbridge is falling, since this square
  641. X * would be inaccessible (i.e. etmp started on drawbridge square) or 
  642. X * unnecessary (i.e. etmp started here) in such a situation.
  643. X */
  644. X#ifdef D_DEBUG
  645. X    pline("Doing relocation.");
  646. X#endif
  647. X    newx = oldx;
  648. X    newy = oldy;
  649. X    (void)find_drawbridge(&newx, &newy);
  650. X    if ((newx == oldx) && (newy == oldy))
  651. X        get_wall_for_db(&newx, &newy);
  652. X#ifdef D_DEBUG
  653. X    pline("Checking new square for occupancy.");
  654. X#endif
  655. X    if (relocates && (e_at(newx, newy))) { 
  656. X
  657. X/* 
  658. X * Standoff problem:  one or both entities must die, and/or both switch 
  659. X * places.  Avoid infinite recursion by checking first whether the other 
  660. X * entity is staying put.  Clean up if we happen to move/die in recursion.
  661. X */
  662. X        struct entity *other;
  663. X
  664. X        other = e_at(newx, newy);
  665. X#ifdef D_DEBUG
  666. X        pline("New square is occupied by %s", e_nam(other));
  667. X#endif
  668. X        if (e_survives_at(other, newx, newy) && automiss(other)) {
  669. X            relocates = FALSE;               /* "other" won't budge */
  670. X#ifdef D_DEBUG
  671. X            pline("%s suicide.", E_phrase(etmp, "commit"));
  672. X#endif
  673. X        } else {
  674. X
  675. X#ifdef D_DEBUG
  676. X            pline("Handling %s", e_nam(other));
  677. X#endif
  678. X            while ((e_at(newx, newy)) && 
  679. X                   (e_at(newx, newy) != etmp))
  680. X                       do_entity(other);
  681. X#ifdef D_DEBUG
  682. X            pline("Checking existence of %s", e_nam(etmp));
  683. X            wait_synch();
  684. X#endif
  685. X            if (e_at(oldx, oldy) != etmp) {
  686. X#ifdef D_DEBUG
  687. X                pline("%s moved or died in recursion somewhere",
  688. X                  E_phrase(etmp, "have"));
  689. X                wait_synch();
  690. X#endif
  691. X                return;
  692. X            }
  693. X        }
  694. X    }
  695. X    if (relocates && !e_at(newx, newy)) {/* if e_at() entity = worm tail */
  696. X#ifdef D_DEBUG
  697. X        pline("Moving %s", e_nam(etmp));
  698. X#endif
  699. X        if (!is_u(etmp)) {
  700. X            remove_monster(etmp->ex, etmp->ey);
  701. X            place_monster(etmp->emon, newx, newy);
  702. X        } else {
  703. X            u.ux = newx;
  704. X            u.uy = newy;
  705. X        }
  706. X        etmp->ex = newx;
  707. X        etmp->ey = newy;
  708. X        e_inview = e_canseemon(etmp);
  709. X    }
  710. X#ifdef D_DEBUG
  711. X    pline("Final disposition of %s", e_nam(etmp));
  712. X    wait_synch();
  713. X#endif
  714. X    if (is_db_wall(etmp->ex, etmp->ey)) {
  715. X#ifdef D_DEBUG
  716. X        pline("%s in portcullis chamber", E_phrase(etmp, "are"));
  717. X        wait_synch();
  718. X#endif
  719. X        if (e_inview) {
  720. X            if (is_u(etmp)) {
  721. X                You("tumble towards the closed portcullis!"); 
  722. X                if (automiss(etmp))
  723. X                    You("pass through it!");
  724. X                else
  725. X                    pline("The drawbridge closes in...");
  726. X            } else
  727. X                pline("%s behind the drawbridge.",
  728. X                                  E_phrase(etmp, "disappear"));
  729. X        }
  730. X        if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
  731. X            killer_format = KILLED_BY_AN;
  732. X            killer = "closing drawbridge";
  733. X            e_died(etmp, 0, CRUSHING);            /* no message */
  734. X            return;
  735. X        }
  736. X#ifdef D_DEBUG
  737. X        pline("%s in here", E_phrase(etmp, "survive"));
  738. X#endif
  739. X    } else {
  740. X#ifdef D_DEBUG
  741. X        pline("%s on drawbridge square", E_phrase(etmp, "are"));
  742. X#endif
  743. X        if (is_pool(etmp->ex, etmp->ey) && !e_inview)
  744. X            if (flags.soundok)
  745. X                You("hear a splash.");
  746. X        if (e_survives_at(etmp, etmp->ex, etmp->ey)) {
  747. X            if (e_inview && !is_flyer(etmp->edata) &&
  748. X                !is_floater(etmp->edata))
  749. X                pline("%s from the bridge.",
  750. X                                  E_phrase(etmp, "fall"));    
  751. X            return;    
  752. X        }
  753. X#ifdef D_DEBUG
  754. X        pline("%s cannot survive on the drawbridge square",Enam(etmp));
  755. X#endif
  756. X        if (is_pool(etmp->ex, etmp->ey) || is_lava(etmp->ex, etmp->ey))
  757. X            if (e_inview && !is_u(etmp)) {
  758. X            /* drown() will supply msgs if nec. */
  759. X            boolean lava = is_lava(etmp->ex, etmp->ey);
  760. X
  761. X            if (Hallucination)
  762. X                pline("%s the %s and disappears.",
  763. X                  E_phrase(etmp, "drink"),
  764. X                  lava ? "lava" : "moat");
  765. X            else
  766. X                pline("%s into the %s.",
  767. X                  E_phrase(etmp, "fall"),
  768. X                  lava ? "lava" : "moat");
  769. X            }
  770. X        killer_format = NO_KILLER_PREFIX;
  771. X        killer = "fell from a drawbridge";
  772. X        e_died(etmp, e_inview ? 3 : 2,      /* CRUSHING is arbitrary */
  773. X               (is_pool(etmp->ex, etmp->ey)) ? DROWNING :
  774. X               (is_lava(etmp->ex, etmp->ey)) ? BURNING :
  775. X                               CRUSHING); /*no corpse*/
  776. X        return;
  777. X    }
  778. X}
  779. X
  780. X/*
  781. X * Close the drawbridge located at x,y
  782. X */
  783. X
  784. Xvoid
  785. Xclose_drawbridge(x,y)
  786. Xint x,y;
  787. X{
  788. X    register struct rm *lev1, *lev2;
  789. X    int x2, y2;
  790. X
  791. X    lev1 = &levl[x][y];
  792. X    if (lev1->typ != DRAWBRIDGE_DOWN) return;
  793. X    x2 = x; y2 = y;
  794. X    get_wall_for_db(&x2,&y2);
  795. X    if (cansee(x,y))  /* change msgs if you are a w-walker at portcullis */
  796. X        You("see a drawbridge %s up!", 
  797. X            ((u.ux == x2) && (u.uy == y2))? "coming" : "going");
  798. X    lev1->typ = DRAWBRIDGE_UP;
  799. X    lev2 = &levl[x2][y2];
  800. X    lev2->typ = DBWALL;
  801. X    switch (lev1->drawbridgemask & DB_DIR) {
  802. X        case DB_NORTH:
  803. X        case DB_SOUTH:
  804. X            lev2->horizontal = TRUE;
  805. X            break;
  806. X        case DB_WEST:
  807. X        case DB_EAST:
  808. X            lev2->horizontal = FALSE;
  809. X            break;
  810. X    }
  811. X    lev2->diggable = W_NONDIGGABLE;
  812. X    set_entity(x, y, &(occupants[0]));
  813. X    set_entity(x2, y2, &(occupants[1]));
  814. X    do_entity(&(occupants[0]));        /* Do set_entity after first */
  815. X    set_entity(x2, y2, &(occupants[1]));    /* do_entity for worm tail */
  816. X    do_entity(&(occupants[1]));
  817. X    if(OBJ_AT(x,y) && flags.soundok)
  818. X        You("hear smashing and crushing.");
  819. X    (void) revive_nasty(x,y,NULL);
  820. X    (void) revive_nasty(x2,y2,NULL);
  821. X    delallobj(x, y);
  822. X    newsym(x, y);
  823. X    delallobj(x2, y2);
  824. X    newsym(x2, y2);
  825. X    block_point(x2,y2);    /* vision */
  826. X}
  827. X
  828. X/* 
  829. X * Open the drawbridge located at x,y
  830. X */
  831. X
  832. Xvoid
  833. Xopen_drawbridge(x,y)
  834. Xint x,y;
  835. X{
  836. X    register struct rm *lev1, *lev2;
  837. X    int x2, y2;
  838. X
  839. X    lev1 = &levl[x][y];
  840. X    if (lev1->typ != DRAWBRIDGE_UP) return;
  841. X    x2 = x; y2 = y;
  842. X    get_wall_for_db(&x2,&y2);
  843. X    if (cansee(x,y))  /* change msgs if you are a w-walker at portcullis */
  844. X        You("see a drawbridge %s down!",
  845. X            ((x2 == u.ux) && (y2 == u.uy))? "going" : "coming");
  846. X    lev1->typ = DRAWBRIDGE_DOWN;
  847. X    lev2 = &levl[x2][y2];
  848. X    lev2->typ = DOOR;
  849. X    lev2->doormask = D_NODOOR;
  850. X    set_entity(x, y, &(occupants[0]));
  851. X    set_entity(x2, y2, &(occupants[1]));
  852. X    do_entity(&(occupants[0]));        /* do set_entity after first */
  853. X    set_entity(x2, y2, &(occupants[1]));    /* do_entity for worm tails */
  854. X    do_entity(&(occupants[1]));
  855. X    spoteffects();  /* if underwater, hero is now on solid ground */
  856. X    (void) revive_nasty(x,y,NULL);
  857. X    delallobj(x, y);
  858. X    newsym(x, y);
  859. X    newsym(x2, y2);
  860. X    unblock_point(x2,y2);    /* vision */
  861. X    if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE;
  862. X}
  863. X
  864. X/*
  865. X * Let's destroy the drawbridge located at x,y
  866. X */
  867. X
  868. Xvoid
  869. Xdestroy_drawbridge(x,y)
  870. Xint x,y;
  871. X{
  872. X    register struct rm *lev1, *lev2;
  873. X    int x2, y2;
  874. X    boolean e_inview;
  875. X    struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]);
  876. X
  877. X    lev1 = &levl[x][y];
  878. X    if (!IS_DRAWBRIDGE(lev1->typ))
  879. X        return;
  880. X    x2 = x; y2 = y;
  881. X    get_wall_for_db(&x2,&y2);
  882. X    lev2 = &levl[x2][y2];
  883. X    if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT ||
  884. X        (lev1->drawbridgemask & DB_UNDER) == DB_LAVA) {
  885. X        struct obj *otmp;
  886. X        boolean lava = (lev1->drawbridgemask & DB_UNDER) == DB_LAVA;
  887. X        if (lev1->typ == DRAWBRIDGE_UP) {
  888. X            if (cansee(x2,y2))
  889. X                pline("The portcullis of the drawbridge falls into the %s!",
  890. X                  lava ? "lava" : "moat");
  891. X            else if (flags.soundok)
  892. X                You("hear a loud *SPLASH*!");
  893. X        } else {
  894. X            if (cansee(x,y))
  895. X                pline("The drawbridge collapses into the %s!",
  896. X                  lava ? "lava" : "moat");
  897. X            else if (flags.soundok)
  898. X                You("hear a loud *SPLASH*!");
  899. X        }
  900. X        lev1->typ = lava ? LAVAPOOL : MOAT;
  901. X        lev1->drawbridgemask = 0;
  902. X        if(otmp = sobj_at(BOULDER,x,y)) {
  903. X            freeobj(otmp);
  904. X            (void) flooreffects(otmp,x,y,"fall");
  905. X        }
  906. X    } else {
  907. X        if (cansee(x,y))
  908. X            pline("The drawbridge disintegrates!");
  909. X        else
  910. X            You("hear a loud *CRASH*!");
  911. X        lev1->typ =
  912. X            ((lev1->drawbridgemask & DB_ICE) ? ICE : ROOM);
  913. X        lev1->icedpool =
  914. X            ((lev1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0);
  915. X    }
  916. X    wake_nearby();
  917. X    lev2->typ = DOOR;
  918. X    lev2->doormask = D_NODOOR;
  919. X    newsym(x,y);
  920. X    newsym(x2,y2);
  921. X    if (!does_block(x2,y2,lev2)) unblock_point(x2,y2);    /* vision */
  922. X    if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE;
  923. X
  924. X    set_entity(x2, y2, etmp2); /* currently only automissers can be here */
  925. X    if (etmp2->edata) {
  926. X        e_inview = e_canseemon(etmp2);
  927. X        if (!automiss(etmp2)) {
  928. X            if (e_inview)
  929. X                pline("%s blown apart by flying debris.",
  930. X                            E_phrase(etmp2, "are"));
  931. X            killer_format = KILLED_BY_AN;
  932. X            killer = "exploding drawbridge";
  933. X            e_died(etmp2, e_inview? 3 : 2, CRUSHING); /*no corpse*/
  934. X        }         /* nothing which is vulnerable can survive this */
  935. X    }
  936. X    set_entity(x, y, etmp1);
  937. X    if (etmp1->edata) {
  938. X        e_inview = e_canseemon(etmp1);
  939. X        if (e_missed(etmp1, TRUE)) {
  940. X#ifdef D_DEBUG
  941. X            pline("%s spared!", E_phrase(etmp1, "are"));
  942. X#endif
  943. X        } else {
  944. X            if (e_inview) {
  945. X                if (!is_u(etmp1) && Hallucination)
  946. X                pline("%s into some heavy metal",
  947. X                      E_phrase(etmp1, "get"));
  948. X                else
  949. X                pline("%s hit by a huge chunk of metal!",
  950. X                      E_phrase(etmp1, "are"));
  951. X            } else {
  952. X                if (flags.soundok && !is_u(etmp1) && !is_pool(x,y))
  953. X                You("hear a crushing sound");
  954. X#ifdef D_DEBUG
  955. X                else
  956. X                pline("%s from shrapnel", 
  957. X                      E_phrase(etmp1, "die"));
  958. X#endif
  959. X            }
  960. X            killer_format = KILLED_BY_AN;
  961. X            killer = "collapsing drawbridge";
  962. X            e_died(etmp1, e_inview? 3 : 2, CRUSHING); /*no corpse*/
  963. X            if(lev1->typ == MOAT) do_entity(etmp1);
  964. X        }
  965. X    }
  966. X}
  967. X
  968. X
  969. X#endif /* OVLB */
  970. X
  971. X/*dbridge.c*/
  972. END_OF_FILE
  973. if test 22283 -ne `wc -c <'src/dbridge.c'`; then
  974.     echo shar: \"'src/dbridge.c'\" unpacked with wrong size!
  975. fi
  976. # end of 'src/dbridge.c'
  977. fi
  978. if test -f 'util/lev_main.c' -a "${1}" != "-c" ; then 
  979.   echo shar: Will not clobber existing file \"'util/lev_main.c'\"
  980. else
  981. echo shar: Extracting \"'util/lev_main.c'\" \(31210 characters\)
  982. sed "s/^X//" >'util/lev_main.c' <<'END_OF_FILE'
  983. X/*    SCCS Id: @(#)lev_main.c    3.1    92/12/11    */
  984. X/*    Copyright (c) 1989 by Jean-Christophe Collet */
  985. X/* NetHack may be freely redistributed.  See license for details. */
  986. X
  987. X/*
  988. X * This file contains the main function for the parser
  989. X * and some useful functions needed by yacc
  990. X */
  991. X
  992. X#include "hack.h"
  993. X#include "sp_lev.h"
  994. X#ifdef STRICT_REF_DEF
  995. X#include "termcap.h"
  996. X#endif
  997. X
  998. X#ifdef MAC
  999. X# ifdef applec
  1000. X#  define MPWTOOL
  1001. X#  include <CursorCtl.h>
  1002. X# endif
  1003. X#endif
  1004. X
  1005. X#ifndef MPWTOOL
  1006. X# define SpinCursor(x)
  1007. X#endif
  1008. X
  1009. X#ifndef O_WRONLY
  1010. X# include <fcntl.h>
  1011. X#endif
  1012. X#ifndef O_CREAT    /* some older BSD systems do not define O_CREAT in <fcntl.h> */
  1013. X# include <sys/file.h>
  1014. X#endif
  1015. X#ifndef O_BINARY    /* used for micros, no-op for others */
  1016. X# define O_BINARY 0
  1017. X#endif
  1018. X
  1019. X#define NEWLINE    10    /* under Mac MPW C '\n' is 13 so don't use it. */
  1020. X
  1021. X#define ERR        (-1)
  1022. X
  1023. X#define NewTab(type, size)    (type **) alloc(sizeof(type *) * size)
  1024. X#define Free(ptr)        if(ptr) free((genericptr_t) (ptr))
  1025. X#define Write(fd, item, size)    (void) write(fd, (genericptr_t)(item), size)
  1026. X
  1027. X#ifdef MICRO
  1028. X# undef exit
  1029. X# ifndef AMIGA
  1030. Xextern void FDECL(exit, (int));
  1031. X# endif
  1032. X#endif
  1033. X
  1034. X#define MAX_ERRORS    25
  1035. X
  1036. Xextern int  NDECL (yyparse);
  1037. Xextern void FDECL (init_yyin, (FILE *));
  1038. Xextern void FDECL (init_yyout, (FILE *));
  1039. X
  1040. Xint  FDECL (main, (int, char **));
  1041. Xvoid FDECL (yyerror, (char *));
  1042. Xvoid FDECL (yywarning, (char *));
  1043. Xint  NDECL (yywrap);
  1044. Xchar *FDECL(dup_string,(const char *));
  1045. Xint FDECL(get_floor_type, (CHAR_P));
  1046. Xint FDECL(get_room_type, (char *));
  1047. Xint FDECL(get_trap_type, (char *));
  1048. Xint FDECL(get_monster_id, (char *, CHAR_P));
  1049. Xint FDECL(get_object_id, (char *));
  1050. Xboolean FDECL(check_monster_char, (CHAR_P));
  1051. Xboolean FDECL(check_object_char, (CHAR_P));
  1052. Xchar FDECL(what_map_char, (CHAR_P));
  1053. Xvoid FDECL(scan_map, (char *));
  1054. Xvoid NDECL(wallify_map);
  1055. Xboolean NDECL(check_subrooms);
  1056. Xvoid FDECL(check_coord, (int, int, char *));
  1057. Xvoid NDECL(store_part);
  1058. Xvoid NDECL(store_room);
  1059. Xstatic void FDECL(write_common_data, (int,int,lev_init *,long));
  1060. Xvoid FDECL(write_maze, (int, specialmaze *));
  1061. Xvoid FDECL(write_lev, (int, splev *));
  1062. Xvoid FDECL(free_rooms, (room **, int));
  1063. X
  1064. Xstatic struct {
  1065. X    const char *name;
  1066. X    short type;
  1067. X} trap_types[TRAPNUM] = {
  1068. X    { "arrow",    ARROW_TRAP },
  1069. X    { "dart",    DART_TRAP },
  1070. X    { "falling rock", ROCKTRAP },
  1071. X    { "board",    SQKY_BOARD },
  1072. X    { "bear",    BEAR_TRAP },
  1073. X    { "land mine",    LANDMINE },
  1074. X    { "sleep gas",    SLP_GAS_TRAP },
  1075. X    { "rust",    RUST_TRAP },
  1076. X    { "fire",    FIRE_TRAP },
  1077. X    { "pit",    PIT },
  1078. X    { "spiked pit",    SPIKED_PIT },
  1079. X    { "trapdoor",    TRAPDOOR },
  1080. X    { "teleport",    TELEP_TRAP },
  1081. X    { "level teleport", LEVEL_TELEP },
  1082. X    { "magic portal",   MAGIC_PORTAL },
  1083. X    { "web",    WEB },
  1084. X    { "statue",    STATUE_TRAP },
  1085. X    { "magic",    MAGIC_TRAP },
  1086. X    { "anti magic",    ANTI_MAGIC },
  1087. X#ifdef POLYSELF
  1088. X    { "polymorph",    POLY_TRAP },
  1089. X#endif
  1090. X    { 0, 0 }
  1091. X};
  1092. X
  1093. Xstatic struct {
  1094. X    char *name;
  1095. X    int type;
  1096. X} room_types[] = {
  1097. X    /* for historical reasons, room types are not contiguous numbers */
  1098. X    /* (type 1 is skipped) */
  1099. X    { "ordinary",     OROOM },
  1100. X    { "throne",     COURT },
  1101. X    { "swamp",     SWAMP },
  1102. X    { "vault",     VAULT },
  1103. X    { "beehive",     BEEHIVE },
  1104. X    { "morgue",     MORGUE },
  1105. X#ifdef ARMY
  1106. X    { "barracks",     BARRACKS },
  1107. X#endif
  1108. X    { "zoo",     ZOO },
  1109. X    { "delphi",     DELPHI },
  1110. X    { "temple",     TEMPLE },
  1111. X    { "shop",     SHOPBASE },
  1112. X    { "armor shop",     ARMORSHOP },
  1113. X    { "scroll shop", SCROLLSHOP },
  1114. X    { "potion shop", POTIONSHOP },
  1115. X    { "weapon shop", WEAPONSHOP },
  1116. X    { "food shop",     FOODSHOP },
  1117. X    { "ring shop",     RINGSHOP },
  1118. X    { "wand shop",     WANDSHOP },
  1119. X    { "tool shop",     TOOLSHOP },
  1120. X    { "book shop",     BOOKSHOP },
  1121. X    { "candle shop", CANDLESHOP },
  1122. X    { 0, 0 }
  1123. X};
  1124. X
  1125. Xchar *fname = "(stdin)";
  1126. Xint fatal_error = 0;
  1127. Xint want_warnings = 0;
  1128. X
  1129. X/* Flex 2.3 bug work around */
  1130. Xint yy_more_len = 0;
  1131. X
  1132. Xextern char tmpmessage[];
  1133. Xextern altar *tmpaltar[];
  1134. Xextern lad *tmplad[];
  1135. Xextern stair *tmpstair[];
  1136. Xextern digpos *tmpdig[];
  1137. Xextern char *tmpmap[];
  1138. Xextern region *tmpreg[];
  1139. Xextern lev_region *tmplreg[];
  1140. Xextern door *tmpdoor[];
  1141. Xextern room_door *tmprdoor[];
  1142. Xextern trap *tmptrap[];
  1143. Xextern monster *tmpmonst[];
  1144. Xextern object *tmpobj[];
  1145. Xextern drawbridge *tmpdb[];
  1146. Xextern walk *tmpwalk[];
  1147. Xextern gold *tmpgold[];
  1148. Xextern fountain *tmpfountain[];
  1149. Xextern sink *tmpsink[];
  1150. Xextern pool *tmppool[];
  1151. Xextern engraving *tmpengraving[];
  1152. Xextern mazepart *tmppart[];
  1153. Xextern room *tmproom[];
  1154. Xextern corridor *tmpcor[];
  1155. X
  1156. Xextern int n_olist, n_mlist, n_plist;
  1157. X
  1158. Xextern unsigned int nlreg, nreg, ndoor, ntrap, nmons, nobj;
  1159. Xextern unsigned int ndb, nwalk, npart, ndig, nlad, nstair;
  1160. Xextern unsigned int naltar, ncorridor, nrooms, ngold, nengraving;
  1161. Xextern unsigned int nfountain, npool, nsink;
  1162. X
  1163. Xextern unsigned int max_x_map, max_y_map;
  1164. X
  1165. Xextern int line_number, colon_line_number;
  1166. X
  1167. Xint
  1168. Xmain(argc, argv)
  1169. Xint argc;
  1170. Xchar **argv;
  1171. X{
  1172. X    FILE *fin;
  1173. X    int i;
  1174. X#ifdef MAC_THINKC5
  1175. X    static char *mac_argv[] = {    "lev_comp",    /* dummy argv[0] */
  1176. X                ":dat:Arch.des",
  1177. X                ":dat:Barb.des",
  1178. X                ":dat:Caveman.des",
  1179. X                ":dat:Elf.des",
  1180. X                ":dat:Healer.des",
  1181. X                ":dat:Knight.des",
  1182. X                ":dat:Priest.des",
  1183. X                ":dat:Rogue.des",
  1184. X                ":dat:Samurai.des",
  1185. X                ":dat:Tourist.des",
  1186. X                ":dat:Valkyrie.des",
  1187. X                ":dat:Wizard.des",
  1188. X                ":dat:bigroom.des",
  1189. X                ":dat:castle.des",
  1190. X                ":dat:endgame.des",
  1191. X                ":dat:gehennom.des",
  1192. X                ":dat:knox.des",
  1193. X                ":dat:medusa.des",
  1194. X                ":dat:mines.des",
  1195. X                ":dat:oracle.des",
  1196. X                ":dat:tower.des",
  1197. X                ":dat:yendor.des"
  1198. X                };
  1199. X
  1200. X    argc = SIZE(mac_argv);
  1201. X    argv = mac_argv;
  1202. X#endif
  1203. X    /* Note:  these initializers don't do anything except guarantee that
  1204. X        we're linked properly.
  1205. X    */
  1206. X    monst_init();
  1207. X    objects_init();
  1208. X    decl_init();
  1209. X
  1210. X    init_yyout(stdout);
  1211. X    if (argc == 1) {        /* Read standard input */
  1212. X        init_yyin(stdin);
  1213. X        yyparse();
  1214. X    } else {            /* Otherwise every argument is a filename */
  1215. X        for(i=1; i<argc; i++) {
  1216. X            fname = argv[i];
  1217. X            if(!strcmp(fname, "-w")) {
  1218. X            want_warnings++;
  1219. X            continue;
  1220. X            }
  1221. X            fin = freopen(fname, "r", stdin);
  1222. X            if (!fin) {
  1223. X            (void) fprintf(stderr,"Can't open \"%s\" for input.\n",
  1224. X                        fname);
  1225. X            perror(fname);
  1226. X            } else {
  1227. X            init_yyin(fin);
  1228. X            yyparse();
  1229. X            }
  1230. X            line_number = 1;
  1231. X            fatal_error = 0;
  1232. X        }
  1233. X    }
  1234. X#ifndef VMS
  1235. X    return 0;
  1236. X#else
  1237. X    return 1;       /* vms success */
  1238. X#endif /*VMS*/
  1239. X}
  1240. X
  1241. X/*
  1242. X * Each time the parser detects an error, it uses this function.
  1243. X * Here we take count of the errors. To continue farther than
  1244. X * MAX_ERRORS wouldn't be reasonable.
  1245. X * Assume that explicit calls from lev_comp.y have the 1st letter
  1246. X * capitalized, to allow printing of the line containing the start of
  1247. X * the current declaration, instead of the beginning of the next declaration.
  1248. X */
  1249. X
  1250. Xvoid
  1251. Xyyerror(s)
  1252. Xchar *s;
  1253. X{
  1254. X    (void) fprintf(stderr, "%s: line %d : %s\n", fname,
  1255. X        (*s >= 'A' && *s <= 'Z') ? colon_line_number : line_number, s);
  1256. X    if (++fatal_error > MAX_ERRORS) {
  1257. X        (void) fprintf(stderr,"Too many errors, good bye!\n");
  1258. X        exit(1);
  1259. X    }
  1260. X}
  1261. X
  1262. X/*
  1263. X * Just display a warning (that is : a non fatal error)
  1264. X */
  1265. X
  1266. Xvoid
  1267. Xyywarning(s)
  1268. Xchar *s;
  1269. X{
  1270. X    (void) fprintf(stderr, "%s: line %d : WARNING : %s\n",
  1271. X                fname, colon_line_number, s);
  1272. X}
  1273. X
  1274. Xint
  1275. Xyywrap()
  1276. X{
  1277. X    return 1;
  1278. X}
  1279. X
  1280. X/*
  1281. X * Duplicate a string.
  1282. X */
  1283. X
  1284. Xchar *
  1285. Xdup_string(s)
  1286. Xconst char *s;
  1287. X{
  1288. X    char *news;
  1289. X
  1290. X    if (!s)
  1291. X        return (char *) 0;
  1292. X    news = (char *) alloc(strlen(s)+1);
  1293. X    Strcpy(news, s);
  1294. X    return news;
  1295. X}
  1296. X
  1297. X/*
  1298. X * Find the type of floor, knowing its char representation.
  1299. X */
  1300. X
  1301. Xint
  1302. Xget_floor_type(c)
  1303. Xchar c;
  1304. X{
  1305. X    int val;
  1306. X
  1307. X    SpinCursor(3);
  1308. X    val = what_map_char(c);
  1309. X    if(val == INVALID_TYPE) {
  1310. X        val = ERR;
  1311. X        yywarning("Invalid fill character in MAZE declaration");
  1312. X    }
  1313. X    return val;
  1314. X}
  1315. X
  1316. X/*
  1317. X * Find the type of a room in the table, knowing its name.
  1318. X */
  1319. X
  1320. Xint
  1321. Xget_room_type(s)
  1322. Xchar *s;
  1323. X{
  1324. X    register int i;
  1325. X
  1326. X    SpinCursor(3);
  1327. X    for(i=0; room_types[i].name; i++)
  1328. X        if (!strcmp(s, room_types[i].name))
  1329. X        return ((int) room_types[i].type);
  1330. X    return ERR;
  1331. X}
  1332. X
  1333. X/*
  1334. X * Find the type of a trap in the table, knowing its name.
  1335. X */
  1336. X
  1337. Xint
  1338. Xget_trap_type(s)
  1339. Xchar *s;
  1340. X{
  1341. X    register int i;
  1342. X
  1343. X    SpinCursor(3);
  1344. X    for(i=0; i < TRAPNUM - 1; i++)
  1345. X        if(!strcmp(s,trap_types[i].name))
  1346. X        return((int)trap_types[i].type);
  1347. X    return ERR;
  1348. X}
  1349. X
  1350. X/*
  1351. X * Find the index of a monster in the table, knowing its name.
  1352. X */
  1353. Xint
  1354. Xget_monster_id(s, c)
  1355. Xchar *s;
  1356. Xchar c;
  1357. X{
  1358. X    register int i, class;
  1359. X
  1360. X    SpinCursor(3);
  1361. X    class = def_char_to_monclass(c);
  1362. X    if (c && class == MAXMCLASSES) return ERR;
  1363. X
  1364. X    for(i = 0; i < NUMMONS; i++)
  1365. X        if(!strncmp(s, mons[i].mname, strlen(mons[i].mname))
  1366. X           && (!c || class == mons[i].mlet))
  1367. X        return i;
  1368. X    return ERR;
  1369. X}
  1370. X
  1371. X/*
  1372. X * Find the index of an object in the table, knowing its name.
  1373. X */
  1374. Xint
  1375. Xget_object_id(s)
  1376. Xchar *s;
  1377. X{
  1378. X    register int i;
  1379. X    register const char *objname;
  1380. X
  1381. X    SpinCursor(3);
  1382. X    for (i=0; i<=NROFOBJECTS; i++)
  1383. X        if ((objname = obj_descr[i].oc_name)
  1384. X           && !strncmp(s, objname, strlen(objname)))
  1385. X        return i;
  1386. X    return ERR;
  1387. X}
  1388. X
  1389. X/*
  1390. X * Is the character 'c' a valid monster class ?
  1391. X */
  1392. Xboolean
  1393. Xcheck_monster_char(c)
  1394. Xchar c;
  1395. X{
  1396. X    return (def_char_to_monclass(c) != MAXMCLASSES);
  1397. X}
  1398. X
  1399. X/*
  1400. X * Is the character 'c' a valid object class ?
  1401. X */
  1402. Xboolean
  1403. Xcheck_object_char(c)
  1404. Xchar c;
  1405. X{
  1406. X    return (def_char_to_objclass(c) != MAXOCLASSES);
  1407. X}
  1408. X
  1409. Xchar
  1410. Xwhat_map_char(c)
  1411. X
  1412. X     char    c;
  1413. X{
  1414. X    SpinCursor(3);
  1415. X    switch(c) {
  1416. X          case ' '  : return(STONE);
  1417. X          case '#'  : return(CORR);
  1418. X          case '.'  : return(ROOM);
  1419. X          case '-'  : return(HWALL);
  1420. X          case '|'  : return(VWALL);
  1421. X          case '+'  : return(DOOR);
  1422. X          case 'A'  : return(AIR);
  1423. X          case 'B'  : return(CROSSWALL); /* hack: boundary location */
  1424. X          case 'C'  : return(CLOUD);
  1425. X          case 'S'  : return(SDOOR);
  1426. X          case '{'  : return(FOUNTAIN);
  1427. X          case '\\' : return(THRONE);
  1428. X          case 'K'  :
  1429. X#ifdef SINKS
  1430. X              return(SINK);
  1431. X#else
  1432. X              yywarning("Sinks are not allowed in this version!  Ignoring...");
  1433. X              return(ROOM);
  1434. X#endif
  1435. X          case '}'  : return(MOAT);
  1436. X          case 'P'  : return(POOL);
  1437. X          case 'L'  : return(LAVAPOOL);
  1438. X          case 'I'  : return(ICE);
  1439. X          case 'W'  : return(WATER);
  1440. X        }
  1441. X    return(INVALID_TYPE);
  1442. X}
  1443. X
  1444. X/*
  1445. X * Yep! LEX gives us the map in a raw mode.
  1446. X * Just analyze it here.
  1447. X */
  1448. X
  1449. Xvoid
  1450. Xscan_map(map)
  1451. Xchar *map;
  1452. X{
  1453. X    register int i, len;
  1454. X    register char *s1, *s2;
  1455. X    int max_len = 0;
  1456. X    int max_hig = 0;
  1457. X    char msg[256];
  1458. X
  1459. X    /* First : find the max width of the map */
  1460. X
  1461. X    s1 = map;
  1462. X    while (s1 && *s1) {
  1463. X        s2 = index(s1, NEWLINE);
  1464. X        if (s2) {
  1465. X            if (s2-s1 > max_len)
  1466. X                max_len = s2-s1;
  1467. X            s1 = s2 + 1;
  1468. X        } else {
  1469. X            if (strlen(s1) > max_len)
  1470. X                max_len = strlen(s1);
  1471. X            s1 = (char *) 0;
  1472. X        }
  1473. X    }
  1474. X
  1475. X    /* Then parse it now */
  1476. X
  1477. X    while (map && *map) {
  1478. X        tmpmap[max_hig] = (char *) alloc(max_len);
  1479. X        s1 = index(map, NEWLINE);
  1480. X        if (s1) {
  1481. X            len = s1 - map;
  1482. X            s1++;
  1483. X        } else {
  1484. X            len = strlen(map);
  1485. X            s1 = map + len;
  1486. X        }
  1487. X        for(i=0; i<len; i++)
  1488. X          if((tmpmap[max_hig][i] = what_map_char(map[i])) == INVALID_TYPE) {
  1489. X              Sprintf(msg,
  1490. X             "Invalid character @ (%d, %d) - replacing with stone",
  1491. X                  max_hig, i);
  1492. X              yywarning(msg);
  1493. X              tmpmap[max_hig][i] = STONE;
  1494. X            }
  1495. X        while(i < max_len)
  1496. X            tmpmap[max_hig][i++] = STONE;
  1497. X        map = s1;
  1498. X        max_hig++;
  1499. X    }
  1500. X
  1501. X    /* Memorize boundaries */
  1502. X
  1503. X    max_x_map = max_len - 1;
  1504. X    max_y_map = max_hig - 1;
  1505. X
  1506. X    /* Store the map into the mazepart structure */
  1507. X
  1508. X    if(max_len > MAP_X_LIM || max_hig > MAP_Y_LIM) {
  1509. X        Sprintf(msg, "Map too large! (max %d x %d)", MAP_X_LIM, MAP_Y_LIM);
  1510. X        yyerror(msg);
  1511. X    }
  1512. X
  1513. X    tmppart[npart]->xsize = max_len;
  1514. X    tmppart[npart]->ysize = max_hig;
  1515. X    tmppart[npart]->map = (char **) alloc(max_hig*sizeof(char *));
  1516. X    for(i = 0; i< max_hig; i++)
  1517. X        tmppart[npart]->map[i] = tmpmap[i];
  1518. X}
  1519. X
  1520. X/*
  1521. X *    If we have drawn a map without walls, this allows us to
  1522. X *    auto-magically wallify it.
  1523. X */
  1524. X#define Map_point(x,y) *(tmppart[npart]->map[y] + x)
  1525. X#define Valid_point(x,y) ((x >= 0 && x <= max_x_map) && \
  1526. X              (y >= 0 && y <= max_y_map))
  1527. Xvoid
  1528. Xwallify_map()
  1529. X{
  1530. X
  1531. X    int x, y, xx, yy;
  1532. X
  1533. X    for(y = 0; y <= max_y_map; y++) {
  1534. X      SpinCursor(3);
  1535. X      for(x = 0; x <= max_x_map; x++)
  1536. X
  1537. X        if(Map_point(x,y) == STONE) {
  1538. X
  1539. X          for(yy = y - 1; yy <= y+1 && Map_point(x,y) == STONE; yy++)
  1540. X        for(xx = x - 1; xx <= x+1 && Map_point(x,y) == STONE; xx++)
  1541. X
  1542. X          if(Valid_point(xx,yy) &&
  1543. X             (IS_ROOM(Map_point(xx,yy)) ||
  1544. X              Map_point(xx,yy) == CROSSWALL)) {
  1545. X
  1546. X            if(yy != y)    Map_point(x,y) = HWALL;
  1547. X            else    Map_point(x,y) = VWALL;
  1548. X          }
  1549. X        }
  1550. X    }
  1551. X}
  1552. X
  1553. X/*
  1554. X * We need to check the subrooms apartenance to an existing room.
  1555. X */
  1556. X
  1557. Xboolean
  1558. Xcheck_subrooms()
  1559. X{
  1560. X    short i,j;
  1561. X    boolean found, ok = TRUE;
  1562. X    char msg[256];
  1563. X
  1564. X    for (i = 0; i < nrooms; i++)
  1565. X        if (tmproom[i]->parent) {
  1566. X            found = FALSE;
  1567. X            for(j = 0; j < nrooms; j++)
  1568. X            if (tmproom[j]->name && !strcmp(tmproom[i]->parent,
  1569. X                            tmproom[j]->name)) {
  1570. X                found = TRUE;
  1571. X                break;
  1572. X            }
  1573. X            if (!found) {
  1574. X                Sprintf(msg,"Subroom error : parent room '%s' not found!", tmproom[i]->parent);
  1575. X                yyerror(msg);
  1576. X                ok = FALSE;
  1577. X            }
  1578. X        }
  1579. X    return ok;
  1580. X}
  1581. X
  1582. X/*
  1583. X * Check that coordinates (x,y) are roomlike locations.
  1584. X * Print warning "str" if they aren't.
  1585. X */
  1586. X
  1587. Xvoid
  1588. Xcheck_coord(x, y, str)
  1589. Xint x, y;
  1590. Xchar *str;
  1591. X{
  1592. X    char ebuf[60];
  1593. X
  1594. X    if (x >= 0 && y >= 0 && x <= max_x_map && y <= max_y_map &&
  1595. X    (IS_ROCK(tmpmap[y][x]) || IS_DOOR(tmpmap[y][x]))) {
  1596. X    Sprintf(ebuf, "%s placed in wall at (%02d,%02d)?!", str, x, y);
  1597. X    yywarning(ebuf);
  1598. X    }
  1599. X}
  1600. X
  1601. X/*
  1602. X * Here we want to store the maze part we just got.
  1603. X */
  1604. X
  1605. Xvoid
  1606. Xstore_part()
  1607. X{
  1608. X    register int i;
  1609. X
  1610. X    /* Ok, We got the whole part, now we store it. */
  1611. X
  1612. X    /* The Regions */
  1613. X
  1614. X    if ((tmppart[npart]->nreg = nreg) != 0) {
  1615. X        tmppart[npart]->regions = NewTab(region, nreg);
  1616. X        for(i=0;i<nreg;i++)
  1617. X            tmppart[npart]->regions[i] = tmpreg[i];
  1618. X    }
  1619. X    nreg = 0;
  1620. X
  1621. X    /* The Level Regions */
  1622. X
  1623. X    if ((tmppart[npart]->nlreg = nlreg) != 0) {
  1624. X        tmppart[npart]->lregions = NewTab(lev_region, nlreg);
  1625. X        for(i=0;i<nlreg;i++)
  1626. X            tmppart[npart]->lregions[i] = tmplreg[i];
  1627. X    }
  1628. X    nlreg = 0;
  1629. X
  1630. X    /* the doors */
  1631. X
  1632. X    if ((tmppart[npart]->ndoor = ndoor) != 0) {
  1633. X        tmppart[npart]->doors = NewTab(door, ndoor);
  1634. X        for(i=0;i<ndoor;i++)
  1635. X            tmppart[npart]->doors[i] = tmpdoor[i];
  1636. X    }
  1637. X    ndoor = 0;
  1638. X
  1639. X    /* the traps */
  1640. X
  1641. X    if ((tmppart[npart]->ntrap = ntrap) != 0) {
  1642. X        tmppart[npart]->traps = NewTab(trap, ntrap);
  1643. X        for(i=0;i<ntrap;i++)
  1644. X            tmppart[npart]->traps[i] = tmptrap[i];
  1645. X    }
  1646. X    ntrap = 0;
  1647. X
  1648. X    /* the monsters */
  1649. X
  1650. X    if ((tmppart[npart]->nmonster = nmons) != 0) {
  1651. X        tmppart[npart]->monsters = NewTab(monster, nmons);
  1652. X        for(i=0;i<nmons;i++)
  1653. X            tmppart[npart]->monsters[i] = tmpmonst[i];
  1654. X    }
  1655. X    nmons = 0;
  1656. X
  1657. X    /* the objects */
  1658. X
  1659. X    if ((tmppart[npart]->nobject = nobj) != 0) {
  1660. X        tmppart[npart]->objects = NewTab(object, nobj);
  1661. X        for(i=0;i<nobj;i++)
  1662. X            tmppart[npart]->objects[i] = tmpobj[i];
  1663. X    }
  1664. X    nobj = 0;
  1665. X
  1666. X    /* the drawbridges */
  1667. X
  1668. X    if ((tmppart[npart]->ndrawbridge = ndb) != 0) {
  1669. X        tmppart[npart]->drawbridges = NewTab(drawbridge, ndb);
  1670. X        for(i=0;i<ndb;i++)
  1671. X            tmppart[npart]->drawbridges[i] = tmpdb[i];
  1672. X    }
  1673. X    ndb = 0;
  1674. X
  1675. X    /* The walkmaze directives */
  1676. X
  1677. X    if ((tmppart[npart]->nwalk = nwalk) != 0) {
  1678. X        tmppart[npart]->walks = NewTab(walk, nwalk);
  1679. X        for(i=0;i<nwalk;i++)
  1680. X            tmppart[npart]->walks[i] = tmpwalk[i];
  1681. X    }
  1682. X    nwalk = 0;
  1683. X
  1684. X    /* The non_diggable directives */
  1685. X
  1686. X    if ((tmppart[npart]->ndig = ndig) != 0) {
  1687. X        tmppart[npart]->digs = NewTab(digpos, ndig);
  1688. X        for(i=0;i<ndig;i++)
  1689. X            tmppart[npart]->digs[i] = tmpdig[i];
  1690. X    }
  1691. X    ndig = 0;
  1692. X
  1693. X    /* The ladders */
  1694. X
  1695. X    if ((tmppart[npart]->nlad = nlad) != 0) {
  1696. X        tmppart[npart]->lads = NewTab(lad, nlad);
  1697. X        for(i=0;i<nlad;i++)
  1698. X            tmppart[npart]->lads[i] = tmplad[i];
  1699. X    }
  1700. X    nlad = 0;
  1701. X
  1702. X    /* The stairs */
  1703. X
  1704. X    if ((tmppart[npart]->nstair = nstair) != 0) {
  1705. X        tmppart[npart]->stairs = NewTab(stair, nstair);
  1706. X        for(i=0;i<nstair;i++)
  1707. X            tmppart[npart]->stairs[i] = tmpstair[i];
  1708. X    }
  1709. X    nstair = 0;
  1710. X
  1711. X    /* The altars */
  1712. X    if ((tmppart[npart]->naltar = naltar) != 0) {
  1713. X        tmppart[npart]->altars = NewTab(altar, naltar);
  1714. X        for(i=0;i<naltar;i++)
  1715. X            tmppart[npart]->altars[i] = tmpaltar[i];
  1716. X    }
  1717. X    naltar = 0;
  1718. X
  1719. X    /* The gold piles */
  1720. X
  1721. X    if ((tmppart[npart]->ngold = ngold) != 0) {
  1722. X        tmppart[npart]->golds = NewTab(gold, ngold);
  1723. X        for(i=0;i<ngold;i++)
  1724. X            tmppart[npart]->golds[i] = tmpgold[i];
  1725. X    }
  1726. X    ngold = 0;
  1727. X
  1728. X    /* The engravings */
  1729. X
  1730. X    if ((tmppart[npart]->nengraving = nengraving) != 0) {
  1731. X        tmppart[npart]->engravings = NewTab(engraving, nengraving);
  1732. X        for(i=0;i<nengraving;i++)
  1733. X            tmppart[npart]->engravings[i] = tmpengraving[i];
  1734. X    }
  1735. X    nengraving = 0;
  1736. X
  1737. X    /* The fountains */
  1738. X
  1739. X    if ((tmppart[npart]->nfountain = nfountain) != 0) {
  1740. X        tmppart[npart]->fountains = NewTab(fountain, nfountain);
  1741. X        for(i=0;i<nfountain;i++)
  1742. X            tmppart[npart]->fountains[i] = tmpfountain[i];
  1743. X    }
  1744. X    nfountain = 0;
  1745. X
  1746. X    npart++;
  1747. X    n_plist = n_mlist = n_olist = 0;
  1748. X}
  1749. X
  1750. X/*
  1751. X * Here we want to store the room part we just got.
  1752. X */
  1753. X
  1754. Xvoid
  1755. Xstore_room()
  1756. X{
  1757. X    register int i;
  1758. X
  1759. X    /* Ok, We got the whole room, now we store it. */
  1760. X
  1761. X    /* the doors */
  1762. X
  1763. X    if ((tmproom[nrooms]->ndoor = ndoor) != 0) {
  1764. X        tmproom[nrooms]->doors = NewTab(room_door, ndoor);
  1765. X        for(i=0;i<ndoor;i++)
  1766. X            tmproom[nrooms]->doors[i] = tmprdoor[i];
  1767. X    }
  1768. X    ndoor = 0;
  1769. X
  1770. X    /* the traps */
  1771. X
  1772. X    if ((tmproom[nrooms]->ntrap = ntrap) != 0) {
  1773. X        tmproom[nrooms]->traps = NewTab(trap, ntrap);
  1774. X        for(i=0;i<ntrap;i++)
  1775. X            tmproom[nrooms]->traps[i] = tmptrap[i];
  1776. X    }
  1777. X    ntrap = 0;
  1778. X
  1779. X    /* the monsters */
  1780. X
  1781. X    if ((tmproom[nrooms]->nmonster = nmons) != 0) {
  1782. X        tmproom[nrooms]->monsters = NewTab(monster, nmons);
  1783. X        for(i=0;i<nmons;i++)
  1784. X            tmproom[nrooms]->monsters[i] = tmpmonst[i];
  1785. X    }
  1786. X    nmons = 0;
  1787. X
  1788. X    /* the objects */
  1789. X
  1790. X    if ((tmproom[nrooms]->nobject = nobj) != 0) {
  1791. X        tmproom[nrooms]->objects = NewTab(object, nobj);
  1792. X        for(i=0;i<nobj;i++)
  1793. X            tmproom[nrooms]->objects[i] = tmpobj[i];
  1794. X    }
  1795. X    nobj = 0;
  1796. X
  1797. X    /* The stairs */
  1798. X
  1799. X    if ((tmproom[nrooms]->nstair = nstair) != 0) {
  1800. X        tmproom[nrooms]->stairs = NewTab(stair, nstair);
  1801. X        for(i=0;i<nstair;i++)
  1802. X            tmproom[nrooms]->stairs[i] = tmpstair[i];
  1803. X    }
  1804. X    nstair = 0;
  1805. X
  1806. X    /* The altars */
  1807. X    if ((tmproom[nrooms]->naltar = naltar) != 0) {
  1808. X        tmproom[nrooms]->altars = NewTab(altar, naltar);
  1809. X        for(i=0;i<naltar;i++)
  1810. X            tmproom[nrooms]->altars[i] = tmpaltar[i];
  1811. X    }
  1812. X    naltar = 0;
  1813. X
  1814. X    /* The gold piles */
  1815. X
  1816. X    if ((tmproom[nrooms]->ngold = ngold) != 0) {
  1817. X        tmproom[nrooms]->golds = NewTab(gold, ngold);
  1818. X        for(i=0;i<ngold;i++)
  1819. X            tmproom[nrooms]->golds[i] = tmpgold[i];
  1820. X    }
  1821. X    ngold = 0;
  1822. X
  1823. X    /* The engravings */
  1824. X
  1825. X    if ((tmproom[nrooms]->nengraving = nengraving) != 0) {
  1826. X        tmproom[nrooms]->engravings = NewTab(engraving, nengraving);
  1827. X        for(i=0;i<nengraving;i++)
  1828. X            tmproom[nrooms]->engravings[i] = tmpengraving[i];
  1829. X    }
  1830. X    nengraving = 0;
  1831. X
  1832. X    /* The fountains */
  1833. X
  1834. X    if ((tmproom[nrooms]->nfountain = nfountain) != 0) {
  1835. X        tmproom[nrooms]->fountains = NewTab(fountain, nfountain);
  1836. X        for(i=0;i<nfountain;i++)
  1837. X            tmproom[nrooms]->fountains[i] = tmpfountain[i];
  1838. X    }
  1839. X    nfountain = 0;
  1840. X
  1841. X    /* The sinks */
  1842. X
  1843. X    if ((tmproom[nrooms]->nsink = nsink) != 0) {
  1844. X        tmproom[nrooms]->sinks = NewTab(sink, nsink);
  1845. X        for(i=0;i<nsink;i++)
  1846. X            tmproom[nrooms]->sinks[i] = tmpsink[i];
  1847. X    }
  1848. X    nsink = 0;
  1849. X
  1850. X    /* The pools */
  1851. X
  1852. X    if ((tmproom[nrooms]->npool = npool) != 0) {
  1853. X        tmproom[nrooms]->pools = NewTab(pool, npool);
  1854. X        for(i=0;i<npool;i++)
  1855. X            tmproom[nrooms]->pools[i] = tmppool[i];
  1856. X    }
  1857. X    npool = 0;
  1858. X
  1859. X    nrooms++;
  1860. X}
  1861. X
  1862. X/* some info common to all special levels */
  1863. Xstatic void
  1864. Xwrite_common_data(fd, typ, init, flgs)
  1865. Xint fd, typ;
  1866. Xlev_init *init;
  1867. Xlong flgs;
  1868. X{
  1869. X    char c;
  1870. X    uchar len;
  1871. X
  1872. X    c = typ;
  1873. X    Write(fd, &c, sizeof(c));    /* 1 byte header */
  1874. X    Write(fd, init, sizeof(lev_init));
  1875. X    Write(fd, &flgs, sizeof flgs);
  1876. X
  1877. X    len = strlen(tmpmessage);
  1878. X    Write(fd, &len, sizeof len);
  1879. X    if (len) Write(fd, tmpmessage, (int) len);
  1880. X    tmpmessage[0] = '\0';
  1881. X}
  1882. X
  1883. X/*
  1884. X * Here we write the structure of the maze in the specified file (fd).
  1885. X * Also, we have to free the memory allocated via alloc()
  1886. X */
  1887. X
  1888. Xvoid
  1889. Xwrite_maze(fd, maze)
  1890. Xint fd;
  1891. Xspecialmaze *maze;
  1892. X{
  1893. X    short i,j;
  1894. X    mazepart *pt;
  1895. X
  1896. X    write_common_data(fd, SP_LEV_MAZE, &(maze->init_lev), maze->flags);
  1897. X
  1898. X    Write(fd, &(maze->filling), sizeof(maze->filling));
  1899. X    Write(fd, &(maze->numpart), sizeof(maze->numpart));
  1900. X                     /* Number of parts */
  1901. X    for(i=0;i<maze->numpart;i++) {
  1902. X        pt = maze->parts[i];
  1903. X
  1904. X        /* First, write the map */
  1905. X
  1906. X        Write(fd, &(pt->halign), sizeof(pt->halign));
  1907. X        Write(fd, &(pt->valign), sizeof(pt->valign));
  1908. X        Write(fd, &(pt->xsize), sizeof(pt->xsize));
  1909. X        Write(fd, &(pt->ysize), sizeof(pt->ysize));
  1910. X        for(j=0;j<pt->ysize;j++) {
  1911. X        if(!maze->init_lev.init_present ||
  1912. X           pt->xsize > 1 || pt->ysize > 1)
  1913. X            Write(fd, pt->map[j], sizeof(*(pt->map[j])) * pt->xsize);
  1914. X        Free(pt->map[j]);
  1915. X        }
  1916. X        Free(pt->map);
  1917. X
  1918. X        /* level region stuff */
  1919. X        Write(fd, &(pt->nlreg), sizeof(pt->nlreg));
  1920. X        for(j=0;j<pt->nlreg;j++) {
  1921. X            Write(fd, pt->lregions[j], sizeof(lev_region));
  1922. X            if(pt->lregions[j]->rname) {
  1923. X                char c = strlen(pt->lregions[j]->rname);
  1924. X                Write(fd, &c, sizeof(c));
  1925. X                Write(fd, pt->lregions[j]->rname, (int)c);
  1926. X            }
  1927. X            Free(pt->lregions[j]);
  1928. X        }
  1929. X        if(pt->nlreg > 0)
  1930. X            Free(pt->lregions);
  1931. X
  1932. X        /* The random registers */
  1933. X        Write(fd, &(pt->nrobjects), sizeof(pt->nrobjects));
  1934. X        if(pt->nrobjects) {
  1935. X            Write(fd, pt->robjects, pt->nrobjects);
  1936. X            Free(pt->robjects);
  1937. X        }
  1938. X        Write(fd, &(pt->nloc), sizeof(pt->nloc));
  1939. X        if(pt->nloc) {
  1940. X            Write(fd, pt->rloc_x, pt->nloc);
  1941. X            Write(fd, pt->rloc_y, pt->nloc);
  1942. X            Free(pt->rloc_x);
  1943. X            Free(pt->rloc_y);
  1944. X        }
  1945. X        Write(fd, &(pt->nrmonst), sizeof(pt->nrmonst));
  1946. X        if(pt->nrmonst) {
  1947. X            Write(fd, pt->rmonst, pt->nrmonst);
  1948. X            Free(pt->rmonst);
  1949. X        }
  1950. X
  1951. X        /* subrooms */
  1952. X        Write(fd, &(pt->nreg), sizeof(pt->nreg));
  1953. X        for(j=0;j<pt->nreg;j++) {
  1954. X            Write(fd, pt->regions[j], sizeof(region));
  1955. X            Free(pt->regions[j]);
  1956. X        }
  1957. X        if(pt->nreg > 0)
  1958. X            Free(pt->regions);
  1959. X
  1960. X        /* the doors */
  1961. X        Write(fd, &(pt->ndoor), sizeof(pt->ndoor));
  1962. X        for(j=0;j<pt->ndoor;j++) {
  1963. X            Write(fd, pt->doors[j], sizeof(door));
  1964. X            Free(pt->doors[j]);
  1965. X        }
  1966. X        if (pt->ndoor > 0)
  1967. X            Free(pt->doors);
  1968. X
  1969. X        /* The traps */
  1970. X        Write(fd, &(pt->ntrap), sizeof(pt->ntrap));
  1971. X        for(j=0;j<pt->ntrap;j++) {
  1972. X            Write(fd, pt->traps[j], sizeof(trap));
  1973. X            Free(pt->traps[j]);
  1974. X        }
  1975. X        if (pt->ntrap)
  1976. X            Free(pt->traps);
  1977. X
  1978. X        /* The monsters */
  1979. X        Write(fd, &(pt->nmonster), sizeof(pt->nmonster));
  1980. X        for(j=0;j<pt->nmonster;j++) {
  1981. X            short size;
  1982. X            monster *m = pt->monsters[j];
  1983. X            Write(fd, m, sizeof(monster));
  1984. X            size = m->name ? strlen(m->name) : 0;
  1985. X            Write(fd, &size, sizeof(size));
  1986. X            if (size) {
  1987. X                Write(fd, m->name, size);
  1988. X                Free(m->name);
  1989. X            }
  1990. X            size = m->appear_as ? strlen(m->appear_as) : 0;
  1991. X            Write(fd, &size, sizeof(size));
  1992. X            if (size) {
  1993. X                Write(fd, m->appear_as, size);
  1994. X                Free(m->appear_as);
  1995. X            }
  1996. X            Free(pt->monsters[j]);
  1997. X        }
  1998. X        if (pt->nmonster > 0)
  1999. X            Free(pt->monsters);
  2000. X
  2001. X        /* The objects */
  2002. X        Write(fd, &(pt->nobject), sizeof(pt->nobject));
  2003. X        for(j=0;j<pt->nobject;j++) {
  2004. X            short size;
  2005. X            object *o = pt->objects[j];
  2006. X            Write(fd, o, sizeof(object));
  2007. X            size = o->name ? strlen(o->name) : 0;
  2008. X            Write(fd, &size, sizeof(size));
  2009. X            if (size) {
  2010. X                Write(fd, o->name, size);
  2011. X                Free(o->name);
  2012. X            }
  2013. X            Free(pt->objects[j]);
  2014. X        }
  2015. X        if(pt->nobject > 0)
  2016. X            Free(pt->objects);
  2017. X
  2018. X        /* The drawbridges */
  2019. X        Write(fd, &(pt->ndrawbridge), sizeof(pt->ndrawbridge));
  2020. X        for(j=0;j<pt->ndrawbridge;j++) {
  2021. X            Write(fd, pt->drawbridges[j], sizeof(drawbridge));
  2022. X            Free(pt->drawbridges[j]);
  2023. X        }
  2024. X        if(pt->ndrawbridge > 0)
  2025. X            Free(pt->drawbridges);
  2026. X
  2027. X        /* The mazewalk directives */
  2028. X        Write(fd, &(pt->nwalk), sizeof(pt->nwalk));
  2029. X        for(j=0; j<pt->nwalk; j++) {
  2030. X            Write(fd, pt->walks[j], sizeof(walk));
  2031. X            Free(pt->walks[j]);
  2032. X        }
  2033. X        if (pt->nwalk > 0)
  2034. X            Free(pt->walks);
  2035. X
  2036. X        /* The non_diggable directives */
  2037. X        Write(fd, &(pt->ndig), sizeof(pt->ndig));
  2038. X        for(j=0;j<pt->ndig;j++) {
  2039. X            Write(fd, pt->digs[j], sizeof(digpos));
  2040. X            Free(pt->digs[j]);
  2041. X        }
  2042. X        if (pt->ndig > 0)
  2043. X            Free(pt->digs);
  2044. X
  2045. X        /* The ladders */
  2046. X        Write(fd, &(pt->nlad), sizeof(pt->nlad));
  2047. X        for(j=0;j<pt->nlad;j++) {
  2048. X            Write(fd, pt->lads[j], sizeof(lad));
  2049. X            Free(pt->lads[j]);
  2050. X        }
  2051. X        if (pt->nlad > 0)
  2052. X            Free(pt->lads);
  2053. X
  2054. X        /* The stairs */
  2055. X        Write(fd, &(pt->nstair), sizeof(pt->nstair));
  2056. X        for(j=0;j<pt->nstair;j++) {
  2057. X            Write(fd, pt->stairs[j], sizeof(stair));
  2058. X            Free(pt->stairs[j]);
  2059. X        }
  2060. X        if (pt->nstair > 0)
  2061. X            Free(pt->stairs);
  2062. X
  2063. X        /* The altars */
  2064. X        Write(fd, &(pt->naltar), sizeof(pt->naltar));
  2065. X        for(j=0;j<pt->naltar;j++) {
  2066. X            Write(fd, pt->altars[j], sizeof(altar));
  2067. X            Free(pt->altars[j]);
  2068. X        }
  2069. X        if (pt->naltar > 0)
  2070. X            Free(pt->altars);
  2071. X
  2072. X        /* The gold piles */
  2073. X        Write(fd, &(pt->ngold), sizeof(pt->naltar));
  2074. X        for(j=0;j<pt->ngold;j++) {
  2075. X            Write(fd, pt->golds[j], sizeof(gold));
  2076. X            Free(pt->golds[j]);
  2077. X        }
  2078. X        if (pt->ngold > 0)
  2079. X            Free(pt->golds);
  2080. X
  2081. X        /* The engravings */
  2082. X        Write(fd, &(pt->nengraving), sizeof(pt->nengraving));
  2083. X        for(j=0;j<pt->nengraving;j++) {
  2084. X            char *txt;
  2085. X            int size;
  2086. X            txt = pt->engravings[j]->e.text;
  2087. X            size = pt->engravings[j]->e.length = strlen(txt);
  2088. X            Write(fd, pt->engravings[j], sizeof *pt->engravings[j]);
  2089. X            Write(fd, txt, size);
  2090. X            Free(txt);
  2091. X            Free(pt->engravings[j]);
  2092. X        }
  2093. X        if (pt->nengraving > 0)
  2094. X            Free(pt->engravings);
  2095. X
  2096. X        /* The fountains */
  2097. X        Write(fd, &(pt->nfountain), sizeof(pt->nfountain));
  2098. X        for(j=0;j<pt->nfountain;j++) {
  2099. X        Write(fd, pt->fountains[j], sizeof(fountain));
  2100. X        Free(pt->fountains[j]);
  2101. X        }
  2102. X        if (pt->nfountain > 0)
  2103. X            Free(pt->fountains);
  2104. X
  2105. X        Free(pt);
  2106. X    }
  2107. X}
  2108. X
  2109. X/*
  2110. X * Here we write the structure of the room level in the specified file (fd).
  2111. X */
  2112. X
  2113. Xvoid
  2114. Xwrite_lev(fd, lev)
  2115. Xint fd;
  2116. Xsplev *lev;
  2117. X{
  2118. X    short i,j, size;
  2119. X    room *pt;
  2120. X
  2121. X    write_common_data(fd, SP_LEV_ROOMS, &(lev->init_lev), lev->flags);
  2122. X
  2123. X    /* Random registers */
  2124. X
  2125. X    Write(fd, &lev->nrobjects, sizeof(lev->nrobjects));
  2126. X    if (lev->nrobjects) {
  2127. X        Write(fd, lev->robjects, lev->nrobjects);
  2128. X        Free (lev->robjects);
  2129. X    }
  2130. X    Write(fd, &lev->nrmonst, sizeof(lev->nrmonst));
  2131. X    if (lev->nrmonst) {
  2132. X        Write(fd, lev->rmonst, lev->nrmonst);
  2133. X        Free (lev->rmonst);
  2134. X    }
  2135. X
  2136. X    Write(fd, &(lev->nroom), sizeof(lev->nroom));
  2137. X                            /* Number of rooms */
  2138. X    for(i=0;i<lev->nroom;i++) {
  2139. X        pt = lev->rooms[i];
  2140. X
  2141. X        /* Room characteristics */
  2142. X
  2143. X        if (pt->name)
  2144. X            size = strlen(pt->name);
  2145. X        else
  2146. X            size = 0;
  2147. X        Write(fd, &size, sizeof(size));
  2148. X        if (size)
  2149. X            Write(fd, pt->name, size);
  2150. X
  2151. X        if (pt->parent)
  2152. X            size = strlen(pt->parent);
  2153. X        else
  2154. X            size = 0;
  2155. X        Write(fd, &size, sizeof(size));
  2156. X        if (size)
  2157. X            Write(fd, pt->parent, size);
  2158. X
  2159. X        Write(fd, &(pt->x), sizeof(pt->x));
  2160. X        Write(fd, &(pt->y), sizeof(pt->y));
  2161. X        Write(fd, &(pt->w), sizeof(pt->w));
  2162. X        Write(fd, &(pt->h), sizeof(pt->h));
  2163. X        Write(fd, &(pt->xalign), sizeof(pt->xalign));
  2164. X        Write(fd, &(pt->yalign), sizeof(pt->yalign));
  2165. X        Write(fd, &(pt->rtype), sizeof(pt->rtype));
  2166. X        Write(fd, &(pt->chance), sizeof(pt->chance));
  2167. X        Write(fd, &(pt->rlit), sizeof(pt->rlit));
  2168. X        Write(fd, &(pt->filled), sizeof(pt->filled));
  2169. X
  2170. X        /* the doors */
  2171. X        Write(fd, &(pt->ndoor), sizeof(pt->ndoor));
  2172. X        for(j=0;j<pt->ndoor;j++)
  2173. X            Write(fd, pt->doors[j], sizeof(room_door));
  2174. X        /* The traps */
  2175. X        Write(fd, &(pt->ntrap), sizeof(pt->ntrap));
  2176. X        for(j=0;j<pt->ntrap;j++)
  2177. X            Write(fd, pt->traps[j], sizeof(trap));
  2178. X
  2179. X        /* The monsters */
  2180. X        Write(fd, &(pt->nmonster), sizeof(pt->nmonster));
  2181. X        for(j=0;j<pt->nmonster;j++) {
  2182. X            monster *m = pt->monsters[j];
  2183. X            Write(fd, m, sizeof(monster));
  2184. X            size = m->name ? strlen(m->name) : 0;
  2185. X            Write(fd, &size, sizeof(size));
  2186. X            if (size)
  2187. X                Write(fd, m->name, size);
  2188. X            size = m->appear_as ? strlen(m->appear_as) : 0;
  2189. X            Write(fd, &size, sizeof(size));
  2190. X            if (size)
  2191. X                Write(fd, m->appear_as, size);
  2192. X        }
  2193. X
  2194. X        /* The objects */
  2195. X        Write(fd, &(pt->nobject), sizeof(pt->nobject));
  2196. X        for(j=0;j<pt->nobject;j++) {
  2197. X            object *o = pt->objects[j];
  2198. X            Write(fd, o, sizeof(object));
  2199. X            size = o->name ? strlen(o->name) : 0;
  2200. X            Write(fd, &size, sizeof(size));
  2201. X            if (size)
  2202. X                Write(fd,  o->name, size);
  2203. X        }
  2204. X
  2205. X        /* The stairs */
  2206. X        Write(fd, &(pt->nstair), sizeof(pt->nstair));
  2207. X        for(j=0;j<pt->nstair;j++)
  2208. X            Write(fd, pt->stairs[j], sizeof(stair));
  2209. X
  2210. X        /* The altars */
  2211. X        Write(fd, &(pt->naltar), sizeof(pt->naltar));
  2212. X        for(j=0;j<pt->naltar;j++)
  2213. X            Write(fd, pt->altars[j], sizeof(altar));
  2214. X
  2215. X        /* The gold piles */
  2216. X        Write(fd, &(pt->ngold), sizeof(pt->ngold));
  2217. X        for(j=0;j<pt->ngold;j++)
  2218. X            Write(fd, pt->golds[j], sizeof(gold));
  2219. X
  2220. X        /* The engravings */
  2221. X        Write(fd, &(pt->nengraving), sizeof(pt->nengraving));
  2222. X        for(j=0;j<pt->nengraving;j++) {
  2223. X            char *txt;
  2224. X            txt = pt->engravings[j]->e.text;
  2225. X            size = pt->engravings[j]->e.length = strlen(txt);
  2226. X            Write(fd, pt->engravings[j],
  2227. X                  sizeof *pt->engravings[j]);
  2228. X            Write(fd, txt, size);
  2229. X        }
  2230. X
  2231. X        /* The fountains */
  2232. X        Write(fd, &(pt->nfountain), sizeof(pt->nfountain));
  2233. X        for(j=0;j<pt->nfountain;j++)
  2234. X            Write(fd, pt->fountains[j], sizeof(fountain));
  2235. X
  2236. X        /* The sinks */
  2237. X        Write(fd, &(pt->nsink), sizeof(pt->nsink));
  2238. X        for(j=0;j<pt->nsink;j++)
  2239. X            Write(fd, pt->sinks[j], sizeof(sink));
  2240. X
  2241. X        /* The pools */
  2242. X        Write(fd, &(pt->npool), sizeof(pt->npool));
  2243. X        for(j=0;j<pt->npool;j++)
  2244. X            Write(fd, pt->pools[j], sizeof(pool));
  2245. X    }
  2246. X
  2247. X    /* The corridors */
  2248. X    Write(fd, &ncorridor, sizeof(ncorridor));
  2249. X    for (i=0; i<ncorridor; i++) {
  2250. X        Write(fd, tmpcor[i], sizeof(corridor));
  2251. X        Free(tmpcor[i]);
  2252. X    }
  2253. X    ncorridor = 0;
  2254. X}
  2255. X
  2256. Xvoid
  2257. Xfree_rooms(ro, n)
  2258. Xroom **ro;
  2259. Xint n;
  2260. X{
  2261. X    short j;
  2262. X    room *r;
  2263. X
  2264. X    while(n--) {
  2265. X        r = ro[n];
  2266. X        Free(r->name);
  2267. X        Free(r->parent);
  2268. X        if ((j = r->ndoor) != 0) {
  2269. X            while(j--)
  2270. X                Free(r->doors[j]);
  2271. X            Free(r->doors);
  2272. X        }
  2273. X        if ((j = r->ntrap) != 0) {
  2274. X            while (j--)
  2275. X                Free(r->traps[j]);
  2276. X            Free(r->traps);
  2277. X        }
  2278. X        if ((j = r->nmonster) != 0) {
  2279. X            while (j--) {
  2280. X                Free(r->monsters[j]->name);
  2281. X                Free(r->monsters[j]->appear_as);
  2282. X                Free(r->monsters[j]);
  2283. X            }
  2284. X            Free(r->monsters);
  2285. X        }
  2286. X        if ((j = r->nobject) != 0) {
  2287. X            while(j--) {
  2288. X                Free(r->objects[j]->name);
  2289. X                Free(r->objects[j]);
  2290. X            }
  2291. X            Free(r->objects);
  2292. X        }
  2293. X        if ((j = r->nstair) != 0) {
  2294. X            while(j--)
  2295. X                Free(r->stairs[j]);
  2296. X            Free(r->stairs);
  2297. X        }
  2298. X        if ((j = r->naltar) != 0) {
  2299. X            while (j--)
  2300. X                Free(r->altars[j]);
  2301. X            Free(r->altars);
  2302. X        }
  2303. X        if ((j = r->ngold) != 0) {
  2304. X            while(j--)
  2305. X                Free(r->golds[j]);
  2306. X            Free(r->golds);
  2307. X        }
  2308. X        if ((j = r->nengraving) != 0) {
  2309. X            while(j--) {
  2310. X                Free(r->engravings[j]->e.text);
  2311. X                Free(r->engravings[j]);
  2312. X            }
  2313. X            Free(r->engravings);
  2314. X        }
  2315. X        if ((j = r->nfountain) != 0) {
  2316. X            while(j--)
  2317. X                Free(r->fountains[j]);
  2318. X            Free(r->fountains);
  2319. X        }
  2320. X        if ((j = r->nsink) != 0) {
  2321. X            while(j--)
  2322. X                Free(r->sinks[j]);
  2323. X            Free(r->sinks);
  2324. X        }
  2325. X        if ((j = r->npool) != 0) {
  2326. X            while(j--)
  2327. X                Free(r->pools[j]);
  2328. X            Free(r->pools);
  2329. X        }
  2330. X        Free(r);
  2331. X    }
  2332. X}
  2333. X
  2334. X#ifdef STRICT_REF_DEF
  2335. X/*
  2336. X * Any globals declared in hack.h and descendents which aren't defined
  2337. X * in the modules linked into lev_comp should be defined here.  These
  2338. X * definitions can be dummies:  their sizes shouldn't matter as long as
  2339. X * as their types are correct; actual values are irrelevant.
  2340. X */
  2341. X#define ARBITRARY_SIZE 1
  2342. X/* attrib.c */
  2343. Xstruct attribs attrmax, attrmin;
  2344. X/* files.c */
  2345. Xconst char *configfile;
  2346. Xchar lock[ARBITRARY_SIZE];
  2347. Xchar SAVEF[ARBITRARY_SIZE];
  2348. X# ifdef MICRO
  2349. Xchar SAVEP[ARBITRARY_SIZE];
  2350. X# endif
  2351. X/* termcap.c */
  2352. Xstruct tc_lcl_data tc_lcl_data;
  2353. X# ifdef TEXTCOLOR
  2354. X#  ifdef TOS
  2355. Xconst char *hilites[MAXCOLORS];
  2356. X#  else
  2357. Xchar NEARDATA *hilites[MAXCOLORS];
  2358. X#  endif
  2359. X# endif
  2360. X/* trap.c */
  2361. Xconst char *traps[TRAPNUM];
  2362. X/* window.c */
  2363. Xstruct window_procs windowprocs;
  2364. X/* xxxtty.c */
  2365. X# ifdef DEFINE_OSPEED
  2366. Xshort ospeed;
  2367. X# endif
  2368. X#endif    /* STRICT_REF_DEF */
  2369. X
  2370. X/*lev_main.c*/
  2371. END_OF_FILE
  2372. if test 31210 -ne `wc -c <'util/lev_main.c'`; then
  2373.     echo shar: \"'util/lev_main.c'\" unpacked with wrong size!
  2374. fi
  2375. # end of 'util/lev_main.c'
  2376. fi
  2377. echo shar: End of archive 64 \(of 108\).
  2378. cp /dev/null ark64isdone
  2379. MISSING=""
  2380. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2381. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2382. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2383. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2384. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2385. 101 102 103 104 105 106 107 108 ; do
  2386.     if test ! -f ark${I}isdone ; then
  2387.     MISSING="${MISSING} ${I}"
  2388.     fi
  2389. done
  2390. if test "${MISSING}" = "" ; then
  2391.     echo You have unpacked all 108 archives.
  2392.     echo "Now execute 'rebuild.sh'"
  2393.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2394. else
  2395.     echo You still need to unpack the following archives:
  2396.     echo "        " ${MISSING}
  2397. fi
  2398. ##  End of shell archive.
  2399. exit 0
  2400.