home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / sources / games / 325 < prev    next >
Encoding:
Internet Message Format  |  1993-01-28  |  57.0 KB

  1. Path: sparky!uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i017:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part17/108
  5. Message-ID: <4300@master.CNA.TEK.COM>
  6. Date: 28 Jan 93 19:14:08 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2329
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  12. Posting-number: Volume 16, Issue 17
  13. Archive-name: nethack31/Part17
  14. Supersedes: nethack3p9: Volume 10, Issue 46-102
  15. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  16.  
  17.  
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 17 (of 108)."
  26. # Contents:  src/steal.c util/makedefs.c
  27. # Wrapped by billr@saab on Wed Jan 27 16:08:51 1993
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'src/steal.c' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'src/steal.c'\"
  31. else
  32. echo shar: Extracting \"'src/steal.c'\" \(8343 characters\)
  33. sed "s/^X//" >'src/steal.c' <<'END_OF_FILE'
  34. X/*    SCCS Id: @(#)steal.c    3.1    92/10/14    */
  35. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  36. X/* NetHack may be freely redistributed.  See license for details. */
  37. X
  38. X#include "hack.h"
  39. X
  40. XSTATIC_DCL int NDECL(stealarm);
  41. X
  42. X#ifdef OVLB
  43. Xstatic const char * FDECL(equipname, (struct obj *));
  44. X
  45. Xstatic const char *
  46. Xequipname(otmp)
  47. X
  48. X    register struct obj *otmp;
  49. X{
  50. X
  51. X    return (
  52. X#ifdef TOURIST
  53. X        (otmp == uarmu) ? "shirt" :
  54. X#endif
  55. X        (otmp == uarmf) ? "boots" :
  56. X        (otmp == uarms) ? "shield" :
  57. X        (otmp == uarmg) ? "gloves" :
  58. X        (otmp == uarmc) ? "cloak" :
  59. X        (otmp == uarmh) ? "helmet" : "armor");
  60. X}
  61. X
  62. Xlong        /* actually returns something that fits in an int */
  63. Xsomegold(){
  64. X#ifdef LINT    /* long conv. ok */
  65. X    return(0L);
  66. X#else
  67. X    return (long)( (u.ugold < 100) ? u.ugold :
  68. X        (u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold) );
  69. X#endif
  70. X}
  71. X
  72. Xvoid
  73. Xstealgold(mtmp)
  74. Xregister struct monst *mtmp;
  75. X{
  76. X    register struct obj *gold = g_at(u.ux, u.uy);
  77. X    register long tmp;
  78. X
  79. X    if (gold && ( !u.ugold || gold->quan > u.ugold || !rn2(5))) {
  80. X        mtmp->mgold += gold->quan;
  81. X        delobj(gold);
  82. X        newsym(u.ux, u.uy);
  83. X        pline("%s quickly snatches some gold from between your %s!",
  84. X            Monnam(mtmp), makeplural(body_part(FOOT)));
  85. X        if(!u.ugold || !rn2(5)) {
  86. X        rloc(mtmp);
  87. X        mtmp->mflee = 1;
  88. X        }
  89. X    } else if(u.ugold) {
  90. X        u.ugold -= (tmp = somegold());
  91. X        Your("purse feels lighter.");
  92. X        mtmp->mgold += tmp;
  93. X        rloc(mtmp);
  94. X        mtmp->mflee = 1;
  95. X        flags.botl = 1;
  96. X    }
  97. X}
  98. X
  99. X/* steal armor after you finish taking it off */
  100. Xunsigned int stealoid;        /* object to be stolen */
  101. Xunsigned int stealmid;        /* monster doing the stealing */
  102. X
  103. XSTATIC_OVL int
  104. Xstealarm(){
  105. X    register struct monst *mtmp;
  106. X    register struct obj *otmp;
  107. X
  108. X    for(otmp = invent; otmp; otmp = otmp->nobj)
  109. X      if(otmp->o_id == stealoid) {
  110. X        for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  111. X          if(mtmp->m_id == stealmid) {
  112. X          if(otmp->unpaid) 
  113. X               subfrombill(otmp, shop_keeper(*u.ushops));
  114. X          freeinv(otmp);
  115. X          pline("%s steals %s!", Monnam(mtmp), doname(otmp));
  116. X          mpickobj(mtmp,otmp);
  117. X          mtmp->mflee = 1;
  118. X          rloc(mtmp);
  119. X        break;
  120. X          }
  121. X        break;
  122. X      }
  123. X    stealoid = 0;
  124. X    return 0;
  125. X}
  126. X
  127. X/* Returns 1 when something was stolen (or at least, when N should flee now)
  128. X * Returns -1 if the monster died in the attempt
  129. X * Avoid stealing the object stealoid
  130. X */
  131. Xint
  132. Xsteal(mtmp)
  133. Xstruct monst *mtmp;
  134. X{
  135. X    register struct obj *otmp;
  136. X    register int tmp;
  137. X    register int named = 0;
  138. X
  139. X    /* the following is true if successful on first of two attacks. */
  140. X    if(!monnear(mtmp, u.ux, u.uy)) return(0);
  141. X
  142. X    if(!invent
  143. X#ifdef POLYSELF
  144. X           || (inv_cnt() == 1 && uskin)
  145. X#endif
  146. X                        ){
  147. X        /* Not even a thousand men in armor can strip a naked man. */
  148. X        if(Blind)
  149. X          pline("Somebody tries to rob you, but finds nothing to steal.");
  150. X        else
  151. X          pline("%s tries to rob you, but she finds nothing to steal!",
  152. X        Monnam(mtmp));
  153. X        return(1);    /* let her flee */
  154. X    }
  155. X
  156. X    if(Adornment & LEFT_RING) {
  157. X        otmp = uleft;
  158. X        goto gotobj;
  159. X    } else if(Adornment & RIGHT_RING) {
  160. X        otmp = uright;
  161. X        goto gotobj;
  162. X    }
  163. X
  164. X    tmp = 0;
  165. X    for(otmp = invent; otmp; otmp = otmp->nobj)
  166. X        if((!uarm || otmp != uarmc)
  167. X#ifdef POLYSELF
  168. X                    && otmp != uskin
  169. X#endif
  170. X                            )
  171. X        tmp += ((otmp->owornmask &
  172. X            (W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1);
  173. X    tmp = rn2(tmp);
  174. X    for(otmp = invent; otmp; otmp = otmp->nobj)
  175. X        if((!uarm || otmp != uarmc)
  176. X#ifdef POLYSELF
  177. X                    && otmp != uskin
  178. X#endif
  179. X                            )
  180. X        if((tmp -= ((otmp->owornmask &
  181. X            (W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1)) < 0)
  182. X            break;
  183. X    if(!otmp) {
  184. X        impossible("Steal fails!");
  185. X        return(0);
  186. X    }
  187. X    /* can't steal gloves while wielding - so steal the wielded item. */
  188. X    if (otmp == uarmg && uwep)
  189. X        otmp = uwep;
  190. X    /* can't steal armor while wearing cloak - so steal the cloak. */
  191. X    else if(otmp == uarm && uarmc) otmp = uarmc;
  192. X#ifdef TOURIST
  193. X    else if(otmp == uarmu && uarmc) otmp = uarmc;
  194. X    else if(otmp == uarmu && uarm) otmp = uarm;
  195. X#endif
  196. Xgotobj:
  197. X    if(otmp->o_id == stealoid) return(0);
  198. X
  199. X#ifdef WALKIES
  200. X    if(otmp->otyp == LEASH && otmp->leashmon) o_unleash(otmp);
  201. X#endif
  202. X
  203. X    if((otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))){
  204. X        switch(otmp->oclass) {
  205. X        case TOOL_CLASS:
  206. X            Blindf_off(otmp);
  207. X            break;
  208. X        case AMULET_CLASS:
  209. X            Amulet_off();
  210. X            break;
  211. X        case RING_CLASS:
  212. X            Ring_gone(otmp);
  213. X            break;
  214. X        case ARMOR_CLASS:
  215. X            /* Stop putting on armor which has been stolen. */
  216. X            if (donning(otmp)) {
  217. X              cancel_don();
  218. X              if (otmp == uarm)  (void) Armor_off();
  219. X              /* else if (otmp == uarmc) (void) Cloak_off(); */
  220. X              else if (otmp == uarmf) (void) Boots_off();
  221. X              else if (otmp == uarmg) (void) Gloves_off();
  222. X              else if (otmp == uarmh) (void) Helmet_off();
  223. X              /* else if (otmp == uarms) (void) Shield_off(); */
  224. X              else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
  225. X              break;
  226. X            }
  227. X            { int curssv = otmp->cursed;
  228. X            otmp->cursed = 0;
  229. X            stop_occupation();
  230. X            if(flags.female)
  231. X                pline("%s charms you.  You gladly %s your %s.",
  232. X                  Blind ? "She" : Monnam(mtmp),
  233. X                  curssv ? "let her take" : "hand over",
  234. X                  equipname(otmp));
  235. X            else
  236. X                pline("%s seduces you and %s off your %s.",
  237. X                  Blind ? "It" : Adjmonnam(mtmp, "beautiful"),
  238. X                  curssv ? "helps you to take" : "you start taking",
  239. X                  equipname(otmp));
  240. X            named++;
  241. X            /* the following is to set multi for later on */
  242. X            nomul(-objects[otmp->otyp].oc_delay);
  243. X
  244. X            if (otmp == uarm)  (void) Armor_off();
  245. X            else if (otmp == uarmc) (void) Cloak_off();
  246. X            else if (otmp == uarmf) (void) Boots_off();
  247. X            else if (otmp == uarmg) (void) Gloves_off();
  248. X            else if (otmp == uarmh) (void) Helmet_off();
  249. X            else if (otmp == uarms) (void) Shield_off();
  250. X            else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
  251. X            otmp->cursed = curssv;
  252. X            if(multi < 0){
  253. X                /*
  254. X                multi = 0;
  255. X                nomovemsg = 0;
  256. X                afternmv = 0;
  257. X                */
  258. X                stealoid = otmp->o_id;
  259. X                stealmid = mtmp->m_id;
  260. X                afternmv = stealarm;
  261. X                return(0);
  262. X            }
  263. X            break;
  264. X            }
  265. X        default:
  266. X            impossible("Tried to steal a strange worn thing.");
  267. X        }
  268. X    }
  269. X    else if(otmp == uwep) uwepgone();
  270. X
  271. X    if(otmp == uball) unpunish();
  272. X
  273. X    freeinv(otmp);
  274. X    pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
  275. X    (void) snuff_candle(otmp);
  276. X    mpickobj(mtmp,otmp);
  277. X    if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE
  278. X        && !resists_ston(mtmp->data)) {
  279. X        pline("%s turns to stone.", Monnam(mtmp));
  280. X        stoned = TRUE;
  281. X        xkilled(mtmp, 0);
  282. X        return -1;
  283. X    }
  284. X    return((multi < 0) ? 0 : 1);
  285. X}
  286. X
  287. X#endif /* OVLB */
  288. X#ifdef OVL1
  289. X
  290. Xvoid
  291. Xmpickobj(mtmp,otmp)
  292. Xregister struct monst *mtmp;
  293. Xregister struct obj *otmp;
  294. X{
  295. X    otmp->nobj = mtmp->minvent;
  296. X    mtmp->minvent = otmp;
  297. X}
  298. X
  299. X#endif /* OVL1 */
  300. X#ifdef OVLB
  301. X
  302. Xvoid
  303. Xstealamulet(mtmp)
  304. Xregister struct monst *mtmp;
  305. X{
  306. X    register struct obj *otmp;
  307. X
  308. X    for(otmp = invent; otmp; otmp = otmp->nobj) {
  309. X        if(otmp->otyp == AMULET_OF_YENDOR ||
  310. X           (otmp->otyp == FAKE_AMULET_OF_YENDOR && !mtmp->iswiz)) {
  311. X        /* might be an imitation one */
  312. X        setnotworn(otmp);
  313. X        freeinv(otmp);
  314. X        mpickobj(mtmp,otmp);
  315. X        pline("%s stole %s!", Monnam(mtmp), doname(otmp));
  316. X        if (can_teleport(mtmp->data)) rloc(mtmp);
  317. X        return;
  318. X        }
  319. X    }
  320. X}
  321. X
  322. X#endif /* OVLB */
  323. X#ifdef OVL0
  324. X
  325. X/* release the objects the killed animal was carrying */
  326. Xvoid
  327. Xrelobj(mtmp,show,is_pet)
  328. Xregister struct monst *mtmp;
  329. Xregister int show;
  330. Xboolean is_pet;        /* If true, pet should keep wielded weapon */
  331. X{
  332. X    register struct obj *otmp, *otmp2;
  333. X    register int omx = mtmp->mx, omy = mtmp->my;
  334. X
  335. X#ifdef MUSE
  336. X    otmp2 = otmp = 0;
  337. X    if (is_pet) {
  338. X        sort_mwep(mtmp);
  339. X        if ((otmp2 = MON_WEP(mtmp))) {
  340. X            otmp = otmp2->nobj;
  341. X            otmp2->nobj = 0;
  342. X        }
  343. X    }
  344. X    if (!otmp2)
  345. X#endif
  346. X    {    otmp = mtmp->minvent;
  347. X        mtmp->minvent = 0;
  348. X    }
  349. X
  350. X    for (; otmp; otmp = otmp2) {
  351. X#ifdef MUSE
  352. X        if (otmp->owornmask) {
  353. X            mtmp->misc_worn_check &= ~(otmp->owornmask);
  354. X            otmp->owornmask = 0L;
  355. X        }
  356. X#endif
  357. X        otmp2 = otmp->nobj;
  358. X        if (is_pet && cansee(omx, omy) && flags.verbose)
  359. X            pline("%s drops %s.", Monnam(mtmp),
  360. X                    distant_name(otmp, doname));
  361. X        if (flooreffects(otmp, omx, omy, "fall")) continue;
  362. X        place_object(otmp, omx, omy);
  363. X        otmp->nobj = fobj;
  364. X        fobj = otmp;
  365. X        stackobj(fobj);
  366. X    }
  367. X    if (mtmp->mgold) {
  368. X        register long g = mtmp->mgold;
  369. X        mkgold(g, omx, omy);
  370. X        if (is_pet && cansee(omx, omy) && flags.verbose)
  371. X            pline("%s drops %ld gold piece%s.", Monnam(mtmp),
  372. X                g, plur(g));
  373. X        mtmp->mgold = 0L;
  374. X    }
  375. X    if (show & cansee(omx, omy))
  376. X        newsym(omx, omy);
  377. X}
  378. X
  379. X#endif /* OVL0 */
  380. X
  381. X/*steal.c*/
  382. END_OF_FILE
  383. if test 8343 -ne `wc -c <'src/steal.c'`; then
  384.     echo shar: \"'src/steal.c'\" unpacked with wrong size!
  385. fi
  386. # end of 'src/steal.c'
  387. fi
  388. if test -f 'util/makedefs.c' -a "${1}" != "-c" ; then 
  389.   echo shar: Will not clobber existing file \"'util/makedefs.c'\"
  390. else
  391. echo shar: Extracting \"'util/makedefs.c'\" \(45073 characters\)
  392. sed "s/^X//" >'util/makedefs.c' <<'END_OF_FILE'
  393. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  394. X/* Copyright (c) M. Stephenson, 1990, 1991.              */
  395. X/* Copyright (c) Dean Luick, 1990.                  */
  396. X/* NetHack may be freely redistributed.  See license for details. */
  397. X/* makedefs.c - NetHack version 3.1 */
  398. X
  399. X#define    MAKEDEFS_C    /* use to conditionally include file sections */
  400. X/* #define DEBUG /* uncomment for debugging info */
  401. X
  402. X#include "config.h"
  403. X#include "permonst.h"
  404. X#include "objclass.h"
  405. X#include "monsym.h"
  406. X#include "artilist.h"
  407. X
  408. X#ifdef MAC
  409. X# ifdef applec    /* Means the MPW compiler, I hope */
  410. X#  define MPWTOOL
  411. X#  include <CursorCtl.h>
  412. X# else        /* MAC without MPWTOOL */
  413. X#  define MACsansMPWTOOL
  414. X# endif
  415. X#include <string.h>
  416. X#include <ctype.h>
  417. X#endif /* MAC */
  418. X
  419. X#ifndef MPWTOOL
  420. X# define SpinCursor(x)
  421. X#endif
  422. X
  423. X#define Fprintf    (void) fprintf
  424. X#define Fclose    (void) fclose
  425. X#define Unlink    (void) unlink
  426. X#if !defined(AMIGA) || defined(AZTEC_C)
  427. X#define rewind(fp) fseek((fp),0L,SEEK_SET)    /* guarantee a return value */
  428. X#endif
  429. X
  430. X#ifdef NULL
  431. X#undef NULL
  432. X#endif
  433. X#define NULL    ((char *)0)
  434. X
  435. X#if !defined(LINT) && !defined(GCC_WARN)
  436. Xstatic    const char    SCCS_Id[] = "@(#)makedefs.c\t3.1\t93/01/20";
  437. X#endif
  438. X
  439. X#ifdef MICRO
  440. X# undef    exit
  441. Xextern void FDECL(exit, (int));
  442. X#endif
  443. X
  444. X#define WRMODE  "w+"
  445. X#define RDMODE  "r"
  446. X/* the quest.dat file is binary, while everything else is text... */
  447. X#if defined(MICRO) && !defined(AMIGA)
  448. X# define WRBMODE "w+b"
  449. X#else
  450. X# define WRBMODE "w+"
  451. X#endif
  452. X
  453. X#ifndef SEEK_SET
  454. X# define SEEK_SET 0
  455. X#endif
  456. X#ifndef SEEK_END
  457. X# define SEEK_END 2
  458. X#endif
  459. X
  460. X    /* names of files to be generated */
  461. X#define DATE_FILE    "date.h"
  462. X#define MONST_FILE    "pm.h"
  463. X#define ONAME_FILE    "onames.h"
  464. X#define OPTIONS_FILE    "options"
  465. X#define ORACLE_FILE    "oracles"
  466. X#define DATA_FILE    "data"
  467. X#define RUMOR_FILE    "rumors"
  468. X#define DGN_I_FILE    "dungeon.def"
  469. X#define DGN_O_FILE    "dungeon.pdf"
  470. X#define MON_STR_C    "monstr.c"
  471. X#define QTXT_I_FILE    "quest.txt"
  472. X#define QTXT_O_FILE    "quest.dat"
  473. X#define VIS_TAB_H    "vis_tab.h"
  474. X#define VIS_TAB_C    "vis_tab.c"
  475. X    /* locations for those files */
  476. X#ifdef AMIGA
  477. X# define INCLUDE_TEMPLATE    "Incl:t.%s"
  478. X# define SOURCE_TEMPLATE    "NHS:%s"
  479. X# define DATA_TEMPLATE        "Dat:%s"
  480. X#else
  481. X# ifdef MAC
  482. X#   define INCLUDE_TEMPLATE    ":include:%s"
  483. X#   define SOURCE_TEMPLATE    ":src:%s"
  484. X#   define DATA_TEMPLATE    ":dat:%s"
  485. X# else /* MAC */
  486. X#   define INCLUDE_TEMPLATE    "../include/%s"
  487. X#   define SOURCE_TEMPLATE    "../src/%s"
  488. X#   define DATA_TEMPLATE    "../dat/%s"
  489. X# endif /* MAC */
  490. X#endif    /* AMIGA */
  491. X
  492. Xstatic const char
  493. X    *Dont_Edit_Code =
  494. X    "/* This source file is generated by 'makedefs'.  Do not edit. */\n",
  495. X    *Dont_Edit_Data =
  496. X    "#\tThis data file is generated by 'makedefs'.  Do not edit. \n";
  497. X
  498. X/* definitions used for vision tables */
  499. X#define TEST_WIDTH  COLNO
  500. X#define TEST_HEIGHT ROWNO
  501. X#define BLOCK_WIDTH (TEST_WIDTH + 10)
  502. X#define BLOCK_HEIGHT TEST_HEIGHT    /* don't need extra spaces */
  503. X#define MAX_ROW (BLOCK_HEIGHT + TEST_HEIGHT)
  504. X#define MAX_COL (BLOCK_WIDTH + TEST_WIDTH)
  505. X/* Use this as an out-of-bound value in the close table.  */
  506. X#define CLOSE_OFF_TABLE_STRING "99,"    /* for the close table */
  507. X#define FAR_OFF_TABLE_STRING "0xff,"    /* for the far table */
  508. X
  509. X#define sign(z) ((z) < 0 ? -1 : ((z) ? 1 : 0))
  510. X#ifdef VISION_TABLES
  511. Xstatic char xclear[MAX_ROW][MAX_COL];
  512. X#endif
  513. X/*-end of vision defs-*/
  514. X
  515. Xstatic char    in_line[256], filename[30];
  516. X
  517. X#ifdef MACsansMPWTOOL
  518. Xvoid FDECL(macstart, (void));
  519. Xint FDECL(main, (void));
  520. X#else
  521. Xint FDECL(main, (int, char **));
  522. X#endif
  523. Xint FDECL(do_makedefs, (int, char **));
  524. Xvoid NDECL(do_objs);
  525. Xvoid NDECL(do_data);
  526. Xvoid NDECL(do_dungeon);
  527. Xvoid NDECL(do_date);
  528. Xvoid NDECL(do_options);
  529. Xvoid NDECL(do_monstr);
  530. Xvoid NDECL(do_permonst);
  531. Xvoid NDECL(do_questtxt);
  532. Xvoid NDECL(do_rumors);
  533. Xvoid NDECL(do_oracles);
  534. Xvoid NDECL(do_vision);
  535. X
  536. Xextern void NDECL(monst_init);        /* monst.c */
  537. Xextern void NDECL(objects_init);    /* objects.c */
  538. X
  539. Xstatic char *FDECL(xcrypt, (const char *));
  540. Xstatic int FDECL(check_control, (char *));
  541. Xstatic char *FDECL(without_control, (char *));
  542. Xstatic boolean FDECL(d_filter, (char *));
  543. Xstatic boolean FDECL(h_filter, (char *));
  544. Xstatic boolean FDECL(ranged_attk,(struct permonst*));
  545. Xstatic int FDECL(mstrength,(struct permonst *));
  546. X
  547. X#ifdef MULDGN
  548. Xstatic boolean FDECL(qt_comment, (char *));
  549. Xstatic boolean FDECL(qt_control, (char *));
  550. Xstatic int FDECL(get_hdr, (CHAR_P));
  551. Xstatic boolean FDECL(known_id, (CHAR_P));
  552. Xstatic boolean FDECL(new_id, (CHAR_P));
  553. Xstatic boolean FDECL(known_msg, (CHAR_P, char *));
  554. Xstatic void FDECL(new_msg, (char *));
  555. Xstatic void FDECL(do_qt_control, (char *));
  556. Xstatic void FDECL(do_qt_text, (char *));
  557. Xstatic void NDECL(adjust_qt_hdrs);
  558. Xstatic void NDECL(put_qt_hdrs);
  559. X#endif
  560. X
  561. X#ifdef VISION_TABLES
  562. Xstatic void NDECL(H_close_gen);
  563. Xstatic void NDECL(H_far_gen);
  564. Xstatic void NDECL(C_close_gen);
  565. Xstatic void NDECL(C_far_gen);
  566. Xstatic int FDECL(clear_path, (int,int,int,int));
  567. X#endif
  568. X
  569. Xchar * FDECL(tmpdup, (const char *));
  570. Xchar * FDECL(limit, (char *,int));
  571. X
  572. X/* input, output, tmp */
  573. X
  574. XFILE    *ifp, *ofp, *tfp;
  575. X
  576. X#ifdef MACsansMPWTOOL
  577. Xchar mac_opt;
  578. X
  579. Xvoid
  580. Xmacstart()
  581. X{
  582. X    static char buf[100];
  583. X    static char *ptr = NULL;
  584. X
  585. Xagain :
  586. X    if (!ptr || !*ptr) {
  587. X        Fprintf(stderr, "Options: otdemvpqrhz\n");
  588. X        buf[0] = 0;
  589. X        fgets(buf, 100, stdin);
  590. X        ptr = buf;
  591. X    }
  592. X
  593. X    do {
  594. X        mac_opt = *ptr++;
  595. X    } while (mac_opt && isspace(mac_opt));
  596. X
  597. X    if (!mac_opt) {
  598. X        Fprintf(stderr, "Makedefs done.\n");
  599. X        exit(0);
  600. X    }
  601. X}
  602. X#endif /* MAC */
  603. X
  604. X
  605. Xint
  606. X#ifdef MACsansMPWTOOL
  607. Xmain(void)
  608. X{
  609. X    int argc;
  610. X    char **argv;
  611. X#else /* ! MAC */
  612. Xmain(argc, argv)
  613. Xint    argc;
  614. Xchar    *argv[];
  615. X{
  616. X#endif /* MAC */
  617. X    /* Note:  these initializers don't do anything except guarantee that
  618. X        we're linked properly.
  619. X    */
  620. X    monst_init();
  621. X    objects_init();
  622. X
  623. X#ifdef MACsansMPWTOOL
  624. X    while (1) {
  625. X        macstart();
  626. X        do_makedefs(argc, argv);
  627. X    }
  628. X#else
  629. X    if (do_makedefs(argc, argv))
  630. X        exit(1);
  631. X#endif
  632. X#ifndef VMS
  633. X    return 0;
  634. X#else
  635. X    return 1;       /* vms success */
  636. X#endif /*VMS*/
  637. X}
  638. X
  639. Xint
  640. Xdo_makedefs(arrgc, arrgv)
  641. Xint    arrgc;
  642. Xchar    *arrgv[];
  643. X{
  644. X#ifdef MACsansMPWTOOL
  645. X    if (1) {
  646. X        Fprintf(stderr, "makedefs -%c\n", mac_opt);
  647. X        switch (mac_opt) {
  648. X#else /* !MAC */
  649. X    if (arrgc == 2) {
  650. X        char *option = arrgv[1];
  651. X        switch (option[1]) {
  652. X#endif /* MAC */
  653. X        case 'o':
  654. X        case 'O':    do_objs();
  655. X                break;
  656. X        case 't':            /* this may go away... */
  657. X        case 'T':    Fprintf(stderr,    "`-t' option is obsolete.\n");
  658. X                break;
  659. X        case 'd':
  660. X        case 'D':    do_data();
  661. X                break;
  662. X        case 'e':
  663. X        case 'E':    do_dungeon();
  664. X                break;
  665. X        case 'm':
  666. X        case 'M':    do_monstr();
  667. X                break;
  668. X        case 'v':
  669. X        case 'V':    do_date();
  670. X                do_options();
  671. X                break;
  672. X        case 'p':
  673. X        case 'P':    do_permonst();
  674. X                break;
  675. X        case 'q':
  676. X        case 'Q':    do_questtxt();
  677. X                break;
  678. X        case 'r':
  679. X        case 'R':    do_rumors();
  680. X                break;
  681. X        case 'h':
  682. X        case 'H':    do_oracles();
  683. X                break;
  684. X        case 'z':
  685. X        case 'Z':    do_vision();
  686. X                break;
  687. X
  688. X        default:
  689. X                Fprintf(stderr,    "Unknown option '%c'.\n",
  690. X#ifdef MACsansMPWTOOL
  691. X                    mac_opt
  692. X#else /* MAC */
  693. X                    option[1]
  694. X#endif /* MAC */
  695. X                    );
  696. X                (void) fflush(stderr);
  697. X                return(1);
  698. X        }
  699. X        return 0;
  700. X    } else {
  701. X        Fprintf(stderr, "Bad arg count (%d).\n", arrgc-1);
  702. X        (void) fflush(stderr);
  703. X        return 1;
  704. X    }
  705. X}
  706. X
  707. X
  708. X/* trivial text encryption routine which can't be broken with `tr' */
  709. Xstatic
  710. Xchar *xcrypt(str)
  711. Xconst char *str;
  712. X{                /* duplicated in src/hacklib.c */
  713. X    static char buf[BUFSZ];
  714. X    register const char *p;
  715. X    register char *q;
  716. X    register int bitmask;
  717. X
  718. X    for (bitmask = 1, p = str, q = buf; *p; q++) {
  719. X        *q = *p++;
  720. X        if (*q & (32|64)) *q ^= bitmask;
  721. X        if ((bitmask <<= 1) >= 32) bitmask = 1;
  722. X    }
  723. X    *q = '\0';
  724. X    return buf;
  725. X}
  726. X
  727. Xvoid
  728. Xdo_rumors()
  729. X{
  730. X    char    infile[30];
  731. X    long    true_rumor_size;
  732. X
  733. X    Sprintf(filename, DATA_TEMPLATE, RUMOR_FILE);
  734. X    if (!(ofp = fopen(filename, WRMODE))) {
  735. X        perror(filename);
  736. X        exit(1);
  737. X    }
  738. X    Fprintf(ofp,Dont_Edit_Data);
  739. X
  740. X    Strcat(strcpy(infile, filename), ".tru");
  741. X    if (!(ifp = fopen(infile, RDMODE))) {
  742. X        perror(infile);
  743. X        Fclose(ofp);
  744. X        Unlink(filename);    /* kill empty output file */
  745. X        exit(1);
  746. X    }
  747. X
  748. X    /* get size of true rumors file */
  749. X#ifndef VMS
  750. X    (void) fseek(ifp, 0L, SEEK_END);
  751. X    true_rumor_size = ftell(ifp);
  752. X#else
  753. X    /* seek+tell is only valid for stream format files; since rumors.%%%
  754. X       might be in record format, count the actual data bytes instead.
  755. X     */
  756. X    true_rumor_size = 0;
  757. X    while (fgets(in_line,sizeof(in_line),ifp) != NULL)
  758. X        true_rumor_size += strlen(in_line);    /* includes newline */
  759. X#endif /* VMS */
  760. X    Fprintf(ofp,"%06lx\n", true_rumor_size);
  761. X    (void) fseek(ifp, 0L, SEEK_SET);
  762. X
  763. X    /* copy true rumors */
  764. X    while(fgets(in_line,sizeof(in_line),ifp) != NULL)
  765. X        (void) fputs(xcrypt(in_line), ofp);
  766. X
  767. X    Fclose(ifp);
  768. X    Strcat(strcpy(infile, filename), ".fal");
  769. X    if (!(ifp = fopen(infile, RDMODE))) {
  770. X        perror(infile);
  771. X        Fclose(ofp);
  772. X        Unlink(filename);    /* kill incomplete output file */
  773. X        exit(1);
  774. X    }
  775. X
  776. X    /* copy false rumors */
  777. X    while(fgets(in_line,sizeof(in_line),ifp) != NULL)
  778. X        (void) fputs(xcrypt(in_line), ofp);
  779. X
  780. X    Fclose(ifp);
  781. X    Fclose(ofp);
  782. X    return;
  783. X}
  784. X
  785. Xvoid
  786. Xdo_date()
  787. X{
  788. X    long    clocktim;
  789. X    char    cbuf[30], *c;
  790. X
  791. X    Sprintf(filename, INCLUDE_TEMPLATE, DATE_FILE);
  792. X    if (!(ofp = fopen(filename, WRMODE))) {
  793. X        perror(filename);
  794. X        exit(1);
  795. X    }
  796. X    Fprintf(ofp,"/*\tSCCS Id: @(#)date.h\t3.1\t92/01/04 */\n\n");
  797. X    Fprintf(ofp,Dont_Edit_Code);
  798. X
  799. X#ifdef KR1ED
  800. X    (void) time(&clocktim);
  801. X    Strcpy(cbuf, ctime(&clocktim));
  802. X#else
  803. X    (void) time((time_t *)&clocktim);
  804. X    Strcpy(cbuf, ctime((time_t *)&clocktim));
  805. X#endif
  806. X    for(c = cbuf; *c != '\n'; c++);    *c = 0; /* strip off the '\n' */
  807. X    Fprintf(ofp,"#define BUILD_DATE \"%s\"\n", cbuf);
  808. X    Fprintf(ofp,"#define BUILD_TIME (%ldL)\n", clocktim);
  809. X#ifdef AMIGA
  810. X    {
  811. X    struct tm *tm = localtime((time_t *) &clocktim);
  812. X    Fprintf(ofp,"#ifdef AMIGA\n");
  813. X    Fprintf(ofp,"const char amiga_version_string[] = ");
  814. X    Fprintf(ofp,"\"\\0$VER: NetHack %s (%d.%d.%d)\";\n",VERSION,tm->tm_mday,
  815. X        tm->tm_mon+1,tm->tm_year);
  816. X    Fprintf(ofp,"#endif\n");
  817. X    }
  818. X#endif
  819. X    Fclose(ofp);
  820. X    return;
  821. X}
  822. X
  823. Xstatic const char *build_opts[] = {
  824. X#ifdef AMIGA_WBENCH
  825. X        "Amiga WorkBench support",
  826. X#endif
  827. X#ifdef ANSI_DEFAULT
  828. X        "ANSI default terminal",
  829. X#endif
  830. X#ifdef ARMY
  831. X        "armies",
  832. X#endif
  833. X#ifdef TEXTCOLOR
  834. X        "color",
  835. X#endif
  836. X#ifdef COM_COMPL
  837. X        "command line completion",
  838. X#endif
  839. X#ifdef COMPRESS
  840. X        "compress bones/level/save files",
  841. X#endif
  842. X#ifdef ELBERETH
  843. X        "Elbereth",
  844. X#endif
  845. X#ifdef EXP_ON_BOTL
  846. X        "experience points on bottom line",
  847. X#endif
  848. X#ifdef EXPLORE_MODE
  849. X        "explore mode",
  850. X#endif
  851. X#ifdef WALLIFIED_MAZE
  852. X        "fancy mazes",
  853. X#endif
  854. X#ifdef MFLOPPY
  855. X        "floppy drive support",
  856. X#endif
  857. X#ifdef TUTTI_FRUTTI
  858. X        "fruits",
  859. X#endif
  860. X#ifdef KOPS
  861. X        "Keystone Kops",
  862. X#endif
  863. X#ifdef WALKIES
  864. X        "leashes",
  865. X#endif
  866. X#ifdef LOGFILE
  867. X        "log file",
  868. X#endif
  869. X#ifdef MAIL
  870. X        "mail daemon",
  871. X#endif
  872. X#ifdef MUSE
  873. X        "monster item use",
  874. X#endif
  875. X#ifdef GNUDOS
  876. X        "MSDOS protected mode",
  877. X#endif
  878. X#ifdef NEWS
  879. X        "news file",
  880. X#endif
  881. X#ifdef OVERLAY
  882. X        "overlays",
  883. X#endif
  884. X#ifdef MULDGN
  885. X        "quest dungeon",
  886. X#endif
  887. X#ifdef REDO
  888. X        "redoing commands",
  889. X#endif
  890. X#ifdef REINCARNATION
  891. X        "rogue level",
  892. X#endif
  893. X#ifdef SCORE_ON_BOTL
  894. X        "score on bottom line",
  895. X#endif
  896. X#ifdef CLIPPING
  897. X        "screen clipping",
  898. X#endif
  899. X#ifdef SEDUCE
  900. X        "seduction",
  901. X#endif
  902. X#ifdef POLYSELF
  903. X        "self-polymorphing",
  904. X#endif
  905. X#ifdef SHELL
  906. X        "shell command",
  907. X#endif
  908. X#ifdef SINKS
  909. X        "sinks",
  910. X#endif
  911. X#ifdef SOUNDS
  912. X        "sounds",
  913. X#endif
  914. X#ifdef SUSPEND
  915. X        "suspend command",
  916. X#endif
  917. X#ifdef TERMINFO
  918. X        "terminal info library",
  919. X#else
  920. X# if defined(TERMLIB) || (!defined(MICRO) && defined(TTY_GRAPHICS))
  921. X        "terminal capability library",
  922. X# endif
  923. X#endif
  924. X#ifdef TOURIST
  925. X        "tourists",
  926. X#endif
  927. X#ifdef VISION_TABLES
  928. X        "vision tables",
  929. X#endif
  930. X#ifdef WIZARD
  931. X        "wizard mode",
  932. X#endif
  933. X#ifdef ZEROCOMP
  934. X        "zero-compressed save files",
  935. X#endif
  936. X        "basic NetHack features"
  937. X    };
  938. X
  939. Xstatic const char *window_opts[] = {
  940. X#ifdef TTY_GRAPHICS
  941. X        "traditional tty-based graphics",
  942. X#endif
  943. X#ifdef X11_GRAPHICS
  944. X        "X11",
  945. X#endif
  946. X#ifdef MAC
  947. X        "Mac",
  948. X#endif
  949. X#ifdef AMIGA_INTUITION
  950. X        "Amiga Intuition",
  951. X#endif
  952. X        NULL
  953. X    };
  954. X
  955. Xvoid
  956. Xdo_options()
  957. X{
  958. X    register int i, length;
  959. X    register const char *str, *indent = "    ";
  960. X
  961. X    Sprintf(filename, DATA_TEMPLATE, OPTIONS_FILE);
  962. X    if (!(ofp = fopen(filename, WRMODE))) {
  963. X        perror(filename);
  964. X        exit(1);
  965. X    }
  966. X     /* Fprintf(ofp,Dont_Edit_Data); */
  967. X    Fprintf(ofp,"\nOptions compiled into this version of NetHack:\n");
  968. X
  969. X    length = COLNO + 1;    /* force 1st item onto new line */
  970. X    for (i = 0; i < SIZE(build_opts); i++) {
  971. X        str = build_opts[i];
  972. X        if (length + strlen(str) > COLNO - 5)
  973. X        Fprintf(ofp,"\n%s", indent),  length = strlen(indent);
  974. X        else
  975. X        Fprintf(ofp," "),  length++;
  976. X        Fprintf(ofp,"%s", str),  length += strlen(str);
  977. X        Fprintf(ofp,(i < SIZE(build_opts) - 1) ? "," : "."),  length++;
  978. X    }
  979. X
  980. X    Fprintf(ofp,"\n\nSupported windowing systems:\n");
  981. X
  982. X    length = COLNO + 1;    /* force 1st item onto new line */
  983. X    for (i = 0; i < SIZE(window_opts) - 1; i++) {
  984. X        str = window_opts[i];
  985. X        if (length + strlen(str) > COLNO - 5)
  986. X        Fprintf(ofp,"\n%s", indent),  length = strlen(indent);
  987. X        else
  988. X        Fprintf(ofp," "),  length++;
  989. X        Fprintf(ofp,"%s", str),  length += strlen(str);
  990. X        Fprintf(ofp, ","),  length++;
  991. X    }
  992. X    Fprintf(ofp, "\n%swith a default of %s.", indent, DEFAULT_WINDOW_SYS);
  993. X    Fprintf(ofp,"\n\n");
  994. X
  995. X    Fclose(ofp);
  996. X    return;
  997. X}
  998. X
  999. X/* routine to decide whether to discard something from data.base */
  1000. Xstatic boolean
  1001. Xd_filter(line)
  1002. X    char *line;
  1003. X{
  1004. X    if (*line == '#') return TRUE;    /* ignore comment lines */
  1005. X#ifndef ARMY
  1006. X  { static int ignore_army = 0;
  1007. X
  1008. X    switch (ignore_army) {
  1009. X      case 0:   if (!strcmp(line, "*soldier")) ignore_army = 1;
  1010. X        break;        /* 0 => not in army related data */
  1011. X      case 1:   if (*line <= ' ') ignore_army = 2;
  1012. X        break;        /* 1 => in army name list */
  1013. X      case 2:   if (*line > ' ')  ignore_army = 0;
  1014. X        break;        /* 2 => in army descriptive text */
  1015. X    }
  1016. X    if (ignore_army) return TRUE;
  1017. X  }
  1018. X#endif
  1019. X    return FALSE;
  1020. X}
  1021. X
  1022. X   /*
  1023. X    *
  1024. X    New format (v3.1) of 'data' file which allows much faster lookups [pr]
  1025. X"do not edit"        first record is a comment line
  1026. X01234567        hexadecimal formatted offset to text area
  1027. Xname-a            first name of interest
  1028. X123,4            offset to name's text, and number of lines for it
  1029. Xname-b            next name of interest
  1030. Xname-c            multiple names which share same description also
  1031. X456,7            share a single offset,count line
  1032. X.            sentinel to mark end of names
  1033. X789,0            dummy record containing offset,count of EOF
  1034. Xtext-a            4 lines of descriptive text for name-a
  1035. Xtext-a            at file position 0x01234567L + 123L
  1036. Xtext-a
  1037. Xtext-a
  1038. Xtext-b/text-c        7 lines of text for names-b and -c
  1039. Xtext-b/text-c        at fseek(0x01234567L + 456L)
  1040. X...
  1041. X    *
  1042. X    */
  1043. X
  1044. Xvoid
  1045. Xdo_data()
  1046. X{
  1047. X    char    infile[30], tempfile[30];
  1048. X    boolean ok;
  1049. X    long    txt_offset;
  1050. X    unsigned entry_cnt, line_cnt;
  1051. X
  1052. X    Sprintf(tempfile, DATA_TEMPLATE, "database.tmp");
  1053. X    Sprintf(filename, DATA_TEMPLATE, DATA_FILE);
  1054. X    Strcat(strcpy(infile, filename),
  1055. X#ifdef OS2
  1056. X        ".bas"
  1057. X#else
  1058. X        ".base"
  1059. X#endif
  1060. X        );
  1061. X    if (!(ifp = fopen(infile, RDMODE))) {        /* data.base */
  1062. X        perror(infile);
  1063. X        exit(1);
  1064. X    }
  1065. X    if (!(ofp = fopen(filename, WRMODE))) {        /* data */
  1066. X        perror(filename);
  1067. X        Fclose(ifp);
  1068. X        exit(1);
  1069. X    }
  1070. X    if (!(tfp = fopen(tempfile, WRMODE))) {        /* database.tmp */
  1071. X        perror(tempfile);
  1072. X        Fclose(ifp);
  1073. X        Fclose(ofp);
  1074. X        Unlink(filename);
  1075. X        exit(1);
  1076. X    }
  1077. X
  1078. X    /* output a dummy header record; we'll rewind and overwrite it later */
  1079. X    Fprintf(ofp, "%s%08lx\n", Dont_Edit_Data, 0L);
  1080. X
  1081. X    entry_cnt = line_cnt = 0;
  1082. X    /* read through the input file and split it into two sections */
  1083. X    while (fgets(in_line, sizeof in_line, ifp)) {
  1084. X        if (d_filter(in_line)) continue;
  1085. X        if (*in_line > ' ') {    /* got an entry name */
  1086. X        /* first finish previous entry */
  1087. X        if (line_cnt)  Fprintf(ofp, "%d\n", line_cnt),  line_cnt = 0;
  1088. X        /* output the entry name */
  1089. X        (void) fputs(in_line, ofp);
  1090. X        entry_cnt++;        /* update number of entries */
  1091. X        } else if (entry_cnt) {    /* got some descriptive text */
  1092. X        /* update previous entry with current text offset */
  1093. X        if (!line_cnt)  Fprintf(ofp, "%ld,", ftell(tfp));
  1094. X        /* save the text line in the scratch file */
  1095. X        (void) fputs(in_line, tfp);
  1096. X        line_cnt++;        /* update line counter */
  1097. X        }
  1098. X    }
  1099. X    /* output an end marker and then record the current position */
  1100. X    if (line_cnt)  Fprintf(ofp, "%d\n", line_cnt);
  1101. X    Fprintf(ofp, ".\n%ld,%d\n", ftell(tfp), 0);
  1102. X    txt_offset = ftell(ofp);
  1103. X    Fclose(ifp);        /* all done with original input file */
  1104. X
  1105. X    /* reprocess the scratch file; 1st format an error msg, just in case */
  1106. X    Sprintf(in_line, "rewind of \"%s\"", tempfile);
  1107. X    if (rewind(tfp) != 0)  goto dead_data;
  1108. X    /* copy all lines of text from the scratch file into the output file */
  1109. X    while (fgets(in_line, sizeof in_line, tfp))
  1110. X        (void) fputs(in_line, ofp);
  1111. X
  1112. X    /* finished with scratch file */
  1113. X    Fclose(tfp);
  1114. X    Unlink(tempfile);    /* remove it */
  1115. X
  1116. X    /* update the first record of the output file; prepare error msg 1st */
  1117. X    Sprintf(in_line, "rewind of \"%s\"", filename);
  1118. X    ok = (rewind(ofp) == 0);
  1119. X    if (ok) {
  1120. X       Sprintf(in_line, "header rewrite of \"%s\"", filename);
  1121. X       ok = (fprintf(ofp, "%s%08lx\n", Dont_Edit_Data, txt_offset) >= 0);
  1122. X    }
  1123. X    if (!ok) {
  1124. Xdead_data:  perror(in_line);    /* report the problem */
  1125. X        /* close and kill the aborted output file, then give up */
  1126. X        Fclose(ofp);
  1127. X        Unlink(filename);
  1128. X        exit(1);
  1129. X    }
  1130. X
  1131. X    /* all done */
  1132. X    Fclose(ofp);
  1133. X
  1134. X    return;
  1135. X}
  1136. X
  1137. X/* routine to decide whether to discard something from oracles.txt */
  1138. Xstatic boolean
  1139. Xh_filter(line)
  1140. X    char *line;
  1141. X{
  1142. X    static boolean skip = FALSE;
  1143. X    char tag[sizeof in_line];
  1144. X
  1145. X    SpinCursor(3);
  1146. X
  1147. X    if (*line == '#') return TRUE;    /* ignore comment lines */
  1148. X    if (sscanf(line, "----- %s", tag) == 1) {
  1149. X    skip = FALSE;
  1150. X#ifndef SINKS
  1151. X    if (!strcmp(tag, "SINKS")) skip = TRUE;
  1152. X#endif
  1153. X#ifndef ELBERETH
  1154. X    if (!strcmp(tag, "ELBERETH")) skip = TRUE;
  1155. X#endif
  1156. X    } else if (skip && !strncmp(line, "-----", 5))
  1157. X    skip = FALSE;
  1158. X    return skip;
  1159. X}
  1160. X
  1161. Xstatic const char *special_oracle[] = {
  1162. X    "\"...it is rather disconcerting to be confronted with the",
  1163. X    "following theorem from [Baker, Gill, and Solovay, 1975].",
  1164. X    "",
  1165. X    "Theorem 7.18  There exist recursive languages A and B such that",
  1166. X    "  (1)  P(A) == NP(A), and",
  1167. X    "  (2)  P(B) != NP(B)",
  1168. X    "",
  1169. X    "This provides impressive evidence that the techniques that are",
  1170. X    "currently available will not suffice for proving that P != NP or          ",
  1171. X    "that P == NP.\"  [Garey and Johnson, p. 185.]"
  1172. X};
  1173. X
  1174. X/*
  1175. X   The oracle file consists of a "do not edit" comment, a decimal count N
  1176. X   and set of N+1 hexadecimal fseek offsets, followed by N multiple-line
  1177. X   records, separated by "---" lines.  The first oracle is a special case.
  1178. X   The input data contains just those multi-line records, separated by
  1179. X   "-----" lines.
  1180. X */
  1181. X
  1182. Xvoid
  1183. Xdo_oracles()
  1184. X{
  1185. X    char    infile[30], tempfile[30];
  1186. X    boolean in_oracle, ok;
  1187. X    long    txt_offset, offset, fpos;
  1188. X    unsigned oracle_cnt;
  1189. X    register int i;
  1190. X
  1191. X    Sprintf(tempfile, DATA_TEMPLATE, "oracles.tmp");
  1192. X    Sprintf(filename, DATA_TEMPLATE, ORACLE_FILE);
  1193. X    Strcat(strcpy(infile, filename), ".txt");
  1194. X    if (!(ifp = fopen(infile, RDMODE))) {
  1195. X        perror(infile);
  1196. X        exit(1);
  1197. X    }
  1198. X    if (!(ofp = fopen(filename, WRMODE))) {
  1199. X        perror(filename);
  1200. X        Fclose(ifp);
  1201. X        exit(1);
  1202. X    }
  1203. X    if (!(tfp = fopen(tempfile, WRMODE))) {        /* oracles.tmp */
  1204. X        perror(tempfile);
  1205. X        Fclose(ifp);
  1206. X        Fclose(ofp);
  1207. X        Unlink(filename);
  1208. X        exit(1);
  1209. X    }
  1210. X
  1211. X    /* output a dummy header record; we'll rewind and overwrite it later */
  1212. X    Fprintf(ofp, "%s%5d\n", Dont_Edit_Data, 0);
  1213. X
  1214. X    /* handle special oracle; it must come first */
  1215. X    (void) fputs("---\n", tfp);
  1216. X    Fprintf(ofp, "%05lx\n", ftell(tfp));  /* start pos of special oracle */
  1217. X    for (i = 0; i < SIZE(special_oracle); i++) {
  1218. X        (void) fputs(xcrypt(special_oracle[i]), tfp);
  1219. X        (void) fputc('\n', tfp);
  1220. X    }
  1221. X    SpinCursor(3);
  1222. X
  1223. X    oracle_cnt = 1;
  1224. X    (void) fputs("---\n", tfp);
  1225. X    Fprintf(ofp, "%05lx\n", ftell(tfp));    /* start pos of first oracle */
  1226. X    in_oracle = FALSE;
  1227. X
  1228. X    while (fgets(in_line, sizeof in_line, ifp)) {
  1229. X        SpinCursor(3);
  1230. X
  1231. X        if (h_filter(in_line)) continue;
  1232. X        if (!strncmp(in_line, "-----", 5)) {
  1233. X        if (!in_oracle) continue;
  1234. X        in_oracle = FALSE;
  1235. X        oracle_cnt++;
  1236. X        (void) fputs("---\n", tfp);
  1237. X        Fprintf(ofp, "%05lx\n", ftell(tfp));
  1238. X        /* start pos of this oracle */
  1239. X        } else {
  1240. X        in_oracle = TRUE;
  1241. X        (void) fputs(xcrypt(in_line), tfp);
  1242. X        }
  1243. X    }
  1244. X
  1245. X    if (in_oracle) {    /* need to terminate last oracle */
  1246. X        oracle_cnt++;
  1247. X        (void) fputs("---\n", tfp);
  1248. X        Fprintf(ofp, "%05lx\n", ftell(tfp));    /* eof position */
  1249. X    }
  1250. X
  1251. X    /* record the current position */
  1252. X    txt_offset = ftell(ofp);
  1253. X    Fclose(ifp);        /* all done with original input file */
  1254. X
  1255. X    /* reprocess the scratch file; 1st format an error msg, just in case */
  1256. X    Sprintf(in_line, "rewind of \"%s\"", tempfile);
  1257. X    if (rewind(tfp) != 0)  goto dead_data;
  1258. X    /* copy all lines of text from the scratch file into the output file */
  1259. X    while (fgets(in_line, sizeof in_line, tfp))
  1260. X        (void) fputs(in_line, ofp);
  1261. X
  1262. X    /* finished with scratch file */
  1263. X    Fclose(tfp);
  1264. X    Unlink(tempfile);    /* remove it */
  1265. X
  1266. X    /* update the first record of the output file; prepare error msg 1st */
  1267. X    Sprintf(in_line, "rewind of \"%s\"", filename);
  1268. X    ok = (rewind(ofp) == 0);
  1269. X    if (ok) {
  1270. X        Sprintf(in_line, "header rewrite of \"%s\"", filename);
  1271. X        ok = (fprintf(ofp, "%s%5d\n", Dont_Edit_Data, (int)oracle_cnt) >=0);
  1272. X    }
  1273. X    if (ok) {
  1274. X        Sprintf(in_line, "data rewrite of \"%s\"", filename);
  1275. X        for (i = 0; i <= oracle_cnt; i++) {
  1276. X#ifndef VMS    /* alpha/vms v1.0; this fflush seems to confuse ftell */
  1277. X        if (!(ok = (fflush(ofp) == 0))) break;
  1278. X#endif
  1279. X        if (!(ok = (fpos = ftell(ofp)) >= 0)) break;
  1280. X        if (!(ok = (fseek(ofp, fpos, SEEK_SET) >= 0))) break;
  1281. X        if (!(ok = (fscanf(ofp, "%5lx", &offset) == 1))) break;
  1282. X        if (!(ok = (fseek(ofp, fpos, SEEK_SET) >= 0))) break;
  1283. X        if (!(ok = (fprintf(ofp, "%05lx\n", offset + txt_offset) >= 0)))
  1284. X            break;
  1285. X        }
  1286. X    }
  1287. X    if (!ok) {
  1288. Xdead_data:  perror(in_line);    /* report the problem */
  1289. X        /* close and kill the aborted output file, then give up */
  1290. X        Fclose(ofp);
  1291. X        Unlink(filename);
  1292. X        exit(1);
  1293. X    }
  1294. X
  1295. X    /* all done */
  1296. X    Fclose(ofp);
  1297. X
  1298. X    return;
  1299. X}
  1300. X
  1301. X
  1302. Xstatic    struct deflist {
  1303. X
  1304. X    const char    *defname;
  1305. X    boolean    true_or_false;
  1306. X} deflist[] = {
  1307. X#ifdef REINCARNATION
  1308. X          {    "REINCARNATION", TRUE },
  1309. X#else
  1310. X          {    "REINCARNATION", FALSE },
  1311. X#endif
  1312. X#ifdef MULDGN
  1313. X          {    "MULDGN", TRUE },
  1314. X#else
  1315. X          {    "MULDGN", FALSE },
  1316. X#endif
  1317. X          { 0, 0 } };
  1318. X
  1319. Xstatic int
  1320. Xcheck_control(s)
  1321. X    char    *s;
  1322. X{
  1323. X    int    i;
  1324. X
  1325. X    if(s[0] != '%') return(-1);
  1326. X
  1327. X    for(i = 0; deflist[i].defname; i++)
  1328. X        if(!strncmp(deflist[i].defname, s+1, sizeof(deflist[i].defname)))
  1329. X        return(i);
  1330. X
  1331. X    return(-1);
  1332. X}
  1333. X
  1334. Xstatic char *
  1335. Xwithout_control(s)
  1336. X    char *s;
  1337. X{
  1338. X    return(s + 1 + strlen(deflist[check_control(in_line)].defname));
  1339. X}
  1340. X
  1341. Xvoid
  1342. Xdo_dungeon()
  1343. X{
  1344. X    int rcnt = 0;
  1345. X
  1346. X    Sprintf(filename, DATA_TEMPLATE, DGN_I_FILE);
  1347. X    if (!(ifp = fopen(filename, RDMODE))) {
  1348. X        perror(filename);
  1349. X        exit(1);
  1350. X    }
  1351. X    Sprintf(filename, DATA_TEMPLATE, DGN_O_FILE);
  1352. X    if (!(ofp = fopen(filename, WRMODE))) {
  1353. X        perror(filename);
  1354. X        exit(1);
  1355. X    }
  1356. X    Fprintf(ofp,Dont_Edit_Data);
  1357. X
  1358. X    while(fgets(in_line,sizeof(in_line),ifp) != NULL) {
  1359. X
  1360. X        SpinCursor(3);
  1361. X
  1362. X        rcnt++;
  1363. X        if(in_line[0] == '#') continue;    /* discard comments */
  1364. Xrecheck:
  1365. X        if(in_line[0] == '%') {
  1366. X        int i = check_control(in_line);
  1367. X        if(i >= 0) {
  1368. X            if(!deflist[i].true_or_false)  {
  1369. X            while(fgets(in_line,sizeof(in_line),ifp))
  1370. X                if(check_control(in_line) != i) goto recheck;
  1371. X            } else
  1372. X            (void) fputs(without_control(in_line),ofp);
  1373. X        } else {
  1374. X            Fprintf(stderr, "Unknown control option '%s' in file %s at line %d.\n",
  1375. X                in_line, DGN_I_FILE, rcnt);
  1376. X            exit(1);
  1377. X        }
  1378. X        } else
  1379. X        (void) fputs(in_line,ofp);
  1380. X    }
  1381. X    Fclose(ifp);
  1382. X    Fclose(ofp);
  1383. X
  1384. X    return;
  1385. X}
  1386. X
  1387. Xstatic boolean
  1388. Xranged_attk(ptr)    /* returns TRUE if monster can attack at range */
  1389. X    register struct permonst *ptr;
  1390. X{
  1391. X    register int    i, j;
  1392. X    register int atk_mask = (1<<AT_BREA) | (1<<AT_SPIT) | (1<<AT_GAZE);
  1393. X
  1394. X    for(i = 0; i < NATTK; i++) {
  1395. X        if((j=ptr->mattk[i].aatyp) >= AT_WEAP || (atk_mask & (1<<j)))
  1396. X        return TRUE;
  1397. X    }
  1398. X
  1399. X    return(FALSE);
  1400. X}
  1401. X
  1402. X/* This routine is designed to return an integer value which represents
  1403. X * an approximation of monster strength.  It uses a similar method of
  1404. X * determination as "experience()" to arrive at the strength.
  1405. X */
  1406. Xstatic int
  1407. Xmstrength(ptr)
  1408. Xstruct permonst *ptr;
  1409. X{
  1410. X    int    i, tmp2, n, tmp = ptr->mlevel;
  1411. X
  1412. X    if(tmp > 49)        /* special fixed hp monster */
  1413. X        tmp = 2*(tmp - 6) / 4;
  1414. X
  1415. X/*    For creation in groups */
  1416. X    n = (!!(ptr->geno & G_SGROUP));
  1417. X    n += (!!(ptr->geno & G_LGROUP)) << 1;
  1418. X
  1419. X/*    For ranged attacks */
  1420. X    if (ranged_attk(ptr)) n++;
  1421. X
  1422. X/*    For higher ac values */
  1423. X    n += (ptr->ac < 4);
  1424. X    n += (ptr->ac < 0);
  1425. X
  1426. X/*    For very fast monsters */
  1427. X    n += (ptr->mmove >= 18);
  1428. X
  1429. X/*    For each attack and "special" attack */
  1430. X    for(i = 0; i < NATTK; i++) {
  1431. X
  1432. X        tmp2 = ptr->mattk[i].aatyp;
  1433. X        n += (tmp2 > 0);
  1434. X        n += (tmp2 == AT_MAGC);
  1435. X        n += (tmp2 == AT_WEAP && (ptr->mflags2 & M2_STRONG));
  1436. X    }
  1437. X
  1438. X/*    For each "special" damage type */
  1439. X    for(i = 0; i < NATTK; i++) {
  1440. X
  1441. X        tmp2 = ptr->mattk[i].adtyp;
  1442. X        if((tmp2 == AD_DRLI) || (tmp2 == AD_STON) || (tmp2 == AD_DRST)
  1443. X            || (tmp2 == AD_DRDX) || (tmp2 == AD_DRCO)
  1444. X#ifdef POLYSELF
  1445. X                    || (tmp2 == AD_WERE)
  1446. X#endif
  1447. X                                ) n += 2;
  1448. X        else if (strcmp(ptr->mname, "grid bug")) n += (tmp2 != AD_PHYS);
  1449. X        n += ((int) (ptr->mattk[i].damd * ptr->mattk[i].damn) > 23);
  1450. X    }
  1451. X
  1452. X/*    Leprechauns are special cases.  They have many hit dice so they
  1453. X    can hit and are hard to kill, but they don't really do much damage. */
  1454. X    if (!strcmp(ptr->mname, "leprechaun")) n -= 2;
  1455. X
  1456. X/*    Finally, adjust the monster level  0 <= n <= 24 (approx.) */
  1457. X    if(n == 0) tmp--;
  1458. X    else if(n >= 6) tmp += ( n / 2 );
  1459. X    else tmp += ( n / 3 + 1);
  1460. X
  1461. X    return((tmp >= 0) ? tmp : 0);
  1462. X}
  1463. X
  1464. Xvoid
  1465. Xdo_monstr()
  1466. X{
  1467. X    register struct permonst *ptr;
  1468. X    register int i, j;
  1469. X
  1470. X    /*
  1471. X     * create the source file, "monstr.c"
  1472. X     */
  1473. X    Sprintf(filename, SOURCE_TEMPLATE, MON_STR_C);
  1474. X    if (!(ofp = fopen(filename, WRMODE))) {
  1475. X    perror(filename);
  1476. X    exit(1);
  1477. X    }
  1478. X    Fprintf(ofp,Dont_Edit_Code);
  1479. X    Fprintf(ofp,"#include \"config.h\"\n");
  1480. X    Fprintf(ofp,"\nint monstr[] = {\n");
  1481. X    for (ptr = &mons[0], j = 0; ptr->mlet; ptr++) {
  1482. X
  1483. X    SpinCursor(3);
  1484. X
  1485. X    i = mstrength(ptr);
  1486. X    Fprintf(ofp,"%2d,%c", i, (++j & 15) ? ' ' : '\n');
  1487. X    }
  1488. X    /* might want to insert a final 0 entry here instead of just newline */
  1489. X    Fprintf(ofp,"%s};\n", (j & 15) ? "\n" : "");
  1490. X
  1491. X    Fprintf(ofp,"\nvoid NDECL(monstr_init);\n");
  1492. X    Fprintf(ofp,"\nvoid\n");
  1493. X    Fprintf(ofp,"monstr_init()\n");
  1494. X    Fprintf(ofp,"{\n");
  1495. X    Fprintf(ofp,"    return;\n");
  1496. X    Fprintf(ofp,"}\n");
  1497. X    Fprintf(ofp,"\n/*monstr.c*/\n");
  1498. X
  1499. X    Fclose(ofp);
  1500. X    return;
  1501. X}
  1502. X
  1503. Xvoid
  1504. Xdo_permonst()
  1505. X{
  1506. X    int    i;
  1507. X    char    *c, *nam;
  1508. X
  1509. X    Sprintf(filename, INCLUDE_TEMPLATE, MONST_FILE);
  1510. X    if (!(ofp = fopen(filename, WRMODE))) {
  1511. X        perror(filename);
  1512. X        exit(1);
  1513. X    }
  1514. X    Fprintf(ofp,"/*\tSCCS Id: @(#)pm.h\t3.1\t92/01/04 */\n\n");
  1515. X    Fprintf(ofp,Dont_Edit_Code);
  1516. X    Fprintf(ofp,"#ifndef PM_H\n#define PM_H\n");
  1517. X
  1518. X    for(i = 0; mons[i].mlet; i++) {
  1519. X
  1520. X        SpinCursor(3);
  1521. X
  1522. X        Fprintf(ofp,"\n#define\tPM_");
  1523. X        if (mons[i].mlet == S_HUMAN &&
  1524. X                !strncmp(mons[i].mname, "were", 4))
  1525. X            Fprintf(ofp, "HUMAN_");
  1526. X        for (nam = c = tmpdup(mons[i].mname); *c; c++)
  1527. X            if (*c >= 'a' && *c <= 'z') *c -= (char)('a' - 'A');
  1528. X            else if (*c < 'A' || *c > 'Z') *c = '_';
  1529. X        Fprintf(ofp,"%s\t%d", nam, i);
  1530. X    }
  1531. X    Fprintf(ofp,"\n\n#define\tNUMMONS\t%d\n", i);
  1532. X    Fprintf(ofp,"\n#endif /* PM_H */\n");
  1533. X    Fclose(ofp);
  1534. X    return;
  1535. X}
  1536. X
  1537. X#ifdef MULDGN
  1538. X/*    Start of Quest text file processing. */
  1539. X#include "qtext.h"
  1540. X
  1541. Xstatic struct qthdr    qt_hdr;
  1542. Xstatic struct msghdr    msg_hdr[N_HDR];
  1543. Xstatic struct qtmsg    *curr_msg;
  1544. X
  1545. Xstatic int    qt_line;
  1546. X
  1547. Xstatic boolean    in_msg;
  1548. X#define    NO_MSG    1    /* strlen of a null line returned by fgets() */
  1549. X
  1550. Xstatic boolean
  1551. Xqt_comment(s)
  1552. X
  1553. X    char *s;
  1554. X{
  1555. X    if(s[0] == '#') return(TRUE);
  1556. X    return(!in_msg  && strlen(s) == NO_MSG);
  1557. X}
  1558. X
  1559. Xstatic boolean
  1560. Xqt_control(s)
  1561. X
  1562. X    char *s;
  1563. X{
  1564. X    return(s[0] == '%' && (s[1] == 'C' || s[1] == 'E'));
  1565. X}
  1566. X
  1567. Xstatic int
  1568. Xget_hdr(c)
  1569. X
  1570. X    char c;
  1571. X{
  1572. X    int    i;
  1573. X
  1574. X    for(i = 0; i < qt_hdr.n_hdr; i++)
  1575. X        if(c == qt_hdr.id[i]) return (++i);
  1576. X
  1577. X    return(0);
  1578. X}
  1579. X
  1580. Xstatic boolean
  1581. Xknown_id(c)
  1582. X
  1583. X    char c;
  1584. X{
  1585. X    return(get_hdr(c) > 0);
  1586. X}
  1587. X
  1588. Xstatic boolean
  1589. Xnew_id(c)
  1590. X
  1591. X    char c;
  1592. X{
  1593. X    if(qt_hdr.n_hdr >= N_HDR) {
  1594. X
  1595. X        Fprintf(stderr, OUT_OF_HEADERS, qt_line);
  1596. X        return(FALSE);
  1597. X    }
  1598. X
  1599. X    qt_hdr.id[qt_hdr.n_hdr] = c;
  1600. X    msg_hdr[qt_hdr.n_hdr].n_msg = 0;
  1601. X    qt_hdr.offset[qt_hdr.n_hdr++] = 0L;
  1602. X    return(TRUE);
  1603. X}
  1604. X
  1605. Xstatic boolean
  1606. Xknown_msg(c, s)
  1607. X
  1608. X    char c, *s;
  1609. X{
  1610. X    int i = get_hdr(c) - 1,
  1611. X        j, n = atoi(s);
  1612. X
  1613. X    for(j = 0; j < msg_hdr[i].n_msg; j++)
  1614. X        if(msg_hdr[i].qt_msg[j].msgnum == n) return(TRUE);
  1615. X
  1616. X    return(FALSE);
  1617. X}
  1618. X
  1619. X
  1620. Xstatic void
  1621. Xnew_msg(s)
  1622. Xchar *s;
  1623. X{
  1624. X    struct    qtmsg    *qt_msg;
  1625. X    int    i = get_hdr(s[4]) - 1;
  1626. X
  1627. X    if(msg_hdr[i].n_msg >= N_MSG) {
  1628. X        Fprintf(stderr, OUT_OF_MESSAGES, qt_line);
  1629. X    } else {
  1630. X        qt_msg = &(msg_hdr[i].qt_msg[msg_hdr[i].n_msg++]);
  1631. X        qt_msg->msgnum = atoi(s+5);
  1632. X        qt_msg->delivery = s[2];
  1633. X        qt_msg->offset = qt_msg->size = 0L;
  1634. X
  1635. X        curr_msg = qt_msg;
  1636. X    }
  1637. X}
  1638. X
  1639. Xstatic void
  1640. Xdo_qt_control(s)
  1641. X
  1642. X    char *s;
  1643. X{
  1644. X    switch(s[1]) {
  1645. X
  1646. X        case 'C':    if(in_msg) {
  1647. X                Fprintf(stderr, CREC_IN_MSG, qt_line);
  1648. X                break;
  1649. X            } else {
  1650. X                in_msg = TRUE;
  1651. X                if(!known_id(s[4]))
  1652. X                if(!new_id(s[4])) break;
  1653. X                if(known_msg(s[4],&s[5]))
  1654. X                Fprintf(stderr, DUP_MSG, qt_line);
  1655. X                else new_msg(s);
  1656. X            }
  1657. X            break;
  1658. X
  1659. X        case 'E':    if(!in_msg) {
  1660. X                Fprintf(stderr, END_NOT_IN_MSG, qt_line);
  1661. X                break;
  1662. X            } else in_msg = FALSE;
  1663. X            break;
  1664. X
  1665. X        default:    Fprintf(stderr, UNREC_CREC, qt_line);
  1666. X            break;
  1667. X    }
  1668. X}
  1669. X
  1670. Xstatic void
  1671. Xdo_qt_text(s)
  1672. X
  1673. X    char *s;
  1674. X{
  1675. X    curr_msg->size += strlen(s);
  1676. X}
  1677. X
  1678. Xstatic void
  1679. Xadjust_qt_hdrs() {
  1680. X
  1681. X    int    i, j;
  1682. X    long    count = 0L,
  1683. X        hdr_offset = sizeof(int) +
  1684. X                 (sizeof(char) + sizeof(long)) * qt_hdr.n_hdr;
  1685. X
  1686. X    for(i = 0; i < qt_hdr.n_hdr; i++) {
  1687. X
  1688. X        qt_hdr.offset[i] = hdr_offset;
  1689. X        hdr_offset += sizeof(int) + sizeof(struct qtmsg) * msg_hdr[i].n_msg;
  1690. X    }
  1691. X
  1692. X    for(i = 0; i < qt_hdr.n_hdr; i++)
  1693. X        for(j = 0; j < msg_hdr[i].n_msg; j++) {
  1694. X
  1695. X        msg_hdr[i].qt_msg[j].offset = hdr_offset + count;
  1696. X        count += msg_hdr[i].qt_msg[j].size;
  1697. X        }
  1698. X}
  1699. X
  1700. Xstatic void
  1701. Xput_qt_hdrs() {
  1702. X
  1703. X    int    i;
  1704. X
  1705. X    /*
  1706. X     *    The main header record.
  1707. X     */
  1708. X#ifdef DEBUG
  1709. X    Fprintf(stderr, "%ld: header info.\n", ftell(ofp));
  1710. X#endif
  1711. X    (void) fwrite(&(qt_hdr.n_hdr), sizeof(int), 1, ofp);
  1712. X    (void) fwrite(&(qt_hdr.id[0]), sizeof(char), qt_hdr.n_hdr, ofp);
  1713. X    (void) fwrite(&(qt_hdr.offset[0]), sizeof(long), qt_hdr.n_hdr, ofp);
  1714. X#ifdef DEBUG
  1715. X    for(i = 0; i < qt_hdr.n_hdr; i++)
  1716. X        Fprintf(stderr, "%c @ %ld, ", qt_hdr.id[i], qt_hdr.offset[i]);
  1717. X
  1718. X    Fprintf(stderr, "\n");
  1719. X#endif
  1720. X
  1721. X    /*
  1722. X     *    The individual class headers.
  1723. X     */
  1724. X    for(i = 0; i < qt_hdr.n_hdr; i++) {
  1725. X
  1726. X#ifdef DEBUG
  1727. X        Fprintf(stderr, "%ld: %c header info.\n", ftell(ofp),
  1728. X            qt_hdr.id[i]);
  1729. X#endif
  1730. X        (void) fwrite(&(msg_hdr[i].n_msg), sizeof(int), 1, ofp);
  1731. X        (void) fwrite(&(msg_hdr[i].qt_msg[0]), sizeof(struct qtmsg),
  1732. X           msg_hdr[i].n_msg, ofp);
  1733. X#ifdef DEBUG
  1734. X        { int j;
  1735. X          for(j = 0; j < msg_hdr[i].n_msg; j++)
  1736. X        Fprintf(stderr, "msg %d @ %ld (%ld)\n",
  1737. X            msg_hdr[i].qt_msg[j].msgnum,
  1738. X            msg_hdr[i].qt_msg[j].offset,
  1739. X            msg_hdr[i].qt_msg[j].size);
  1740. X        }
  1741. X#endif
  1742. X    }
  1743. X}
  1744. X
  1745. Xvoid
  1746. Xdo_questtxt()
  1747. X{
  1748. X    Sprintf(filename, DATA_TEMPLATE, QTXT_I_FILE);
  1749. X    if(!(ifp = fopen(filename, RDMODE))) {
  1750. X        perror(filename);
  1751. X        exit(1);
  1752. X    }
  1753. X
  1754. X    Sprintf(filename, DATA_TEMPLATE, QTXT_O_FILE);
  1755. X    if(!(ofp = fopen(filename, WRBMODE))) {
  1756. X        perror(filename);
  1757. X        Fclose(ifp);
  1758. X        exit(1);
  1759. X    }
  1760. X
  1761. X    qt_hdr.n_hdr = 0;
  1762. X    qt_line = 0;
  1763. X    in_msg = FALSE;
  1764. X
  1765. X    while(fgets(in_line, 80, ifp) != NULL) {
  1766. X
  1767. X        SpinCursor (3);
  1768. X
  1769. X        qt_line++;
  1770. X        if(qt_control(in_line)) do_qt_control(in_line);
  1771. X        else if(qt_comment(in_line)) continue;
  1772. X        else            do_qt_text(in_line);
  1773. X    }
  1774. X
  1775. X    (void) rewind(ifp);
  1776. X    in_msg = FALSE;
  1777. X    adjust_qt_hdrs(); put_qt_hdrs();
  1778. X    while(fgets(in_line, 80, ifp) != NULL) {
  1779. X
  1780. X        if(qt_control(in_line)) {
  1781. X            in_msg = (in_line[1] == 'C');
  1782. X            continue;
  1783. X        } else if(qt_comment(in_line)) continue;
  1784. X#ifdef DEBUG
  1785. X        Fprintf(stderr, "%ld: %s", ftell(stdout), in_line);
  1786. X#endif
  1787. X        (void) fputs(xcrypt(in_line), ofp);
  1788. X    }
  1789. X    Fclose(ifp);
  1790. X    Fclose(ofp);
  1791. X    return;
  1792. X}
  1793. X#else    /* not MULDGN */
  1794. X
  1795. Xvoid
  1796. Xdo_questtxt()
  1797. X{
  1798. X    Fprintf(stderr, "makedefs: `-q' option ignored.\n");
  1799. X    /* create an empty file to satisfy `make' */
  1800. X    Sprintf(filename, DATA_TEMPLATE, QTXT_O_FILE);
  1801. X    ofp = fopen(filename, WRBMODE);
  1802. X    Fclose(ofp);
  1803. X    return;
  1804. X}
  1805. X
  1806. X#endif /* MULDGN */
  1807. X
  1808. Xstatic    char    temp[32];
  1809. X
  1810. Xchar *
  1811. Xlimit(name,pref)    /* limit a name to 30 characters length */
  1812. Xchar    *name;
  1813. Xint    pref;
  1814. X{
  1815. X    (void) strncpy(temp, name, pref ? 26 : 30);
  1816. X    temp[pref ? 26 : 30] = 0;
  1817. X    return temp;
  1818. X}
  1819. X
  1820. Xvoid
  1821. Xdo_objs()
  1822. X{
  1823. X    int i, sum = 0;
  1824. X    char *c, *objnam;
  1825. X    int nspell = 0;
  1826. X    int prefix = 0;
  1827. X    char class = '\0';
  1828. X    boolean    sumerr = FALSE;
  1829. X
  1830. X    Sprintf(filename, INCLUDE_TEMPLATE, ONAME_FILE);
  1831. X    if (!(ofp = fopen(filename, WRMODE))) {
  1832. X        perror(filename);
  1833. X        exit(1);
  1834. X    }
  1835. X    Fprintf(ofp,"/*\tSCCS Id: @(#)onames.h\t3.1\t92/11/01 */\n\n");
  1836. X    Fprintf(ofp,Dont_Edit_Code);
  1837. X    Fprintf(ofp,"#ifndef ONAMES_H\n#define ONAMES_H\n\n");
  1838. X
  1839. X    for(i = 0; !i || objects[i].oc_class != ILLOBJ_CLASS; i++) {
  1840. X        SpinCursor(3);
  1841. X
  1842. X        objects[i].oc_name_idx = objects[i].oc_descr_idx = i;    /* init */
  1843. X        if (!(objnam = tmpdup(OBJ_NAME(objects[i])))) continue;
  1844. X
  1845. X        /* make sure probabilities add up to 1000 */
  1846. X        if(objects[i].oc_class != class) {
  1847. X            if (sum && sum != 1000) {
  1848. X                Fprintf(stderr, "prob error for class %d (%d%%)",
  1849. X                    class, sum);
  1850. X                (void) fflush(stderr);
  1851. X                sumerr = TRUE;
  1852. X            }
  1853. X            class = objects[i].oc_class;
  1854. X            sum = 0;
  1855. X        }
  1856. X
  1857. X        for (c = objnam; *c; c++)
  1858. X            if (*c >= 'a' && *c <= 'z') *c -= (char)('a' - 'A');
  1859. X            else if (*c < 'A' || *c > 'Z') *c = '_';
  1860. X
  1861. X        switch (class) {
  1862. X            case WAND_CLASS:
  1863. X            Fprintf(ofp,"#define\tWAN_"); prefix = 1; break;
  1864. X            case RING_CLASS:
  1865. X            Fprintf(ofp,"#define\tRIN_"); prefix = 1; break;
  1866. X            case POTION_CLASS:
  1867. X            Fprintf(ofp,"#define\tPOT_"); prefix = 1; break;
  1868. X            case SPBOOK_CLASS:
  1869. X            Fprintf(ofp,"#define\tSPE_"); prefix = 1; nspell++; break;
  1870. X            case SCROLL_CLASS:
  1871. X            Fprintf(ofp,"#define\tSCR_"); prefix = 1; break;
  1872. X            case AMULET_CLASS:
  1873. X            /* avoid trouble with stupid C preprocessors */
  1874. X            Fprintf(ofp,"#define\t");
  1875. X            if(objects[i].oc_material == PLASTIC) {
  1876. X                Fprintf(ofp,"FAKE_AMULET_OF_YENDOR\t%d\n", i);
  1877. X                prefix = -1;
  1878. X                break;
  1879. X            }
  1880. X            break;
  1881. X            case GEM_CLASS:
  1882. X            /* avoid trouble with stupid C preprocessors */
  1883. X            if(objects[i].oc_material == GLASS) {
  1884. X                Fprintf(ofp,"/* #define\t%s\t%d */\n",
  1885. X                            objnam, i);
  1886. X                prefix = -1;
  1887. X                break;
  1888. X            }
  1889. X            default:
  1890. X            Fprintf(ofp,"#define\t");
  1891. X        }
  1892. X        if (prefix >= 0)
  1893. X            Fprintf(ofp,"%s\t%d\n", limit(objnam, prefix), i);
  1894. X        prefix = 0;
  1895. X
  1896. X        sum += objects[i].oc_prob;
  1897. X    }
  1898. X
  1899. X    /* check last set of probabilities */
  1900. X    if (sum && sum != 1000) {
  1901. X        Fprintf(stderr, "prob error for class %d (%d%%)", class, sum);
  1902. X        (void) fflush(stderr);
  1903. X        sumerr = TRUE;
  1904. X    }
  1905. X
  1906. X    Fprintf(ofp,"#define\tLAST_GEM\t(JADE)\n");
  1907. X    Fprintf(ofp,"#define\tMAXSPELL\t%d\n", nspell+1);
  1908. X    Fprintf(ofp,"#define\tNROFOBJECTS\t%d\n", i-1);
  1909. X
  1910. X    Fprintf(ofp, "\n/* Artifacts (unique objects) */\n\n");
  1911. X
  1912. X    for (i = 1; artifact_names[i]; i++) {
  1913. X        SpinCursor(3);
  1914. X
  1915. X        for (c = objnam = tmpdup(artifact_names[i]); *c; c++)
  1916. X            if (*c >= 'a' && *c <= 'z') *c -= (char)('a' - 'A');
  1917. X            else if (*c < 'A' || *c > 'Z') *c = '_';
  1918. X
  1919. X        if (!strncmp(objnam, "THE_", 4))
  1920. X            objnam += 4;
  1921. X#ifdef TOURIST
  1922. X        /* fudge _platinum_ YENDORIAN EXPRESS CARD */
  1923. X        if (!strncmp(objnam, "PLATINUM_", 9))
  1924. X            objnam += 9;
  1925. X#endif
  1926. X        Fprintf(ofp,"#define\tART_%s\t%d\n", limit(objnam, 1), i);
  1927. X    }
  1928. X
  1929. X    Fprintf(ofp, "#define\tNROFARTIFACTS\t%d\n", i-1);
  1930. X    Fprintf(ofp,"\n#endif /* ONAMES_H */\n");
  1931. X    Fclose(ofp);
  1932. X    if (sumerr) exit(1);
  1933. X    return;
  1934. X}
  1935. X
  1936. Xchar *
  1937. Xtmpdup(str)
  1938. Xconst char *str;
  1939. X{
  1940. X    static char buf[128];
  1941. X
  1942. X    if (!str) return (char *)0;
  1943. X    (void)strncpy(buf, str, 127);
  1944. X    return buf;
  1945. X}
  1946. X
  1947. X
  1948. X/*
  1949. X * macros used to control vision algorithms:
  1950. X *      VISION_TABLES => generate tables
  1951. X *      BRACES        => table elements should be enclosed in "{ }"
  1952. X */
  1953. X
  1954. Xvoid
  1955. Xdo_vision()
  1956. X{
  1957. X#ifdef VISION_TABLES
  1958. X    int i, j;
  1959. X
  1960. X    /* Everything is clear.  xclear may be malloc'ed.
  1961. X     * Block the upper left corner (BLOCK_HEIGHTxBLOCK_WIDTH)
  1962. X     */
  1963. X    for (i = 0; i < MAX_ROW; i++)
  1964. X    for (j = 0; j < MAX_COL; j++)
  1965. X        if (i < BLOCK_HEIGHT && j < BLOCK_WIDTH)
  1966. X        xclear[i][j] = '\000';
  1967. X        else
  1968. X        xclear[i][j] = '\001';
  1969. X#endif /* VISION_TABLES */
  1970. X
  1971. X    SpinCursor(3);
  1972. X
  1973. X    /*
  1974. X     * create the include file, "vis_tab.h"
  1975. X     */
  1976. X    Sprintf(filename, INCLUDE_TEMPLATE, VIS_TAB_H);
  1977. X    if (!(ofp = fopen(filename, WRMODE))) {
  1978. X    perror(filename);
  1979. X    exit(1);
  1980. X    }
  1981. X    Fprintf(ofp,Dont_Edit_Code);
  1982. X    Fprintf(ofp,"#ifdef VISION_TABLES\n");
  1983. X#ifdef VISION_TABLES
  1984. X    H_close_gen();
  1985. X    H_far_gen();
  1986. X#endif /* VISION_TABLES */
  1987. X    Fprintf(ofp,"\n#endif /* VISION_TABLES */\n");
  1988. X    Fclose(ofp);
  1989. X
  1990. X    SpinCursor(3);
  1991. X
  1992. X    /*
  1993. X     * create the source file, "vis_tab.c"
  1994. X     */
  1995. X    Sprintf(filename, SOURCE_TEMPLATE, VIS_TAB_C);
  1996. X    if (!(ofp = fopen(filename, WRMODE))) {
  1997. X    perror(filename);
  1998. X    Sprintf(filename, INCLUDE_TEMPLATE, VIS_TAB_H);
  1999. X    Unlink(filename);
  2000. X    exit(1);
  2001. X    }
  2002. X    Fprintf(ofp,Dont_Edit_Code);
  2003. X    Fprintf(ofp,"#include \"config.h\"\n");
  2004. X    Fprintf(ofp,"#ifdef VISION_TABLES\n");
  2005. X    Fprintf(ofp,"#include \"vis_tab.h\"\n");
  2006. X
  2007. X    SpinCursor(3);
  2008. X
  2009. X#ifdef VISION_TABLES
  2010. X    C_close_gen();
  2011. X    C_far_gen();
  2012. X    Fprintf(ofp,"\nvoid vis_tab_init() { return; }\n");
  2013. X#endif /* VISION_TABLES */
  2014. X
  2015. X    SpinCursor(3);
  2016. X
  2017. X    Fprintf(ofp,"\n#endif /* VISION_TABLES */\n");
  2018. X    Fprintf(ofp,"\n/*vis_tab.c*/\n");
  2019. X
  2020. X    Fclose(ofp);
  2021. X    return;
  2022. X}
  2023. X
  2024. X#ifdef VISION_TABLES
  2025. X
  2026. X/*--------------  vision tables  --------------*\
  2027. X *
  2028. X *  Generate the close and far tables.  This is done by setting up a
  2029. X *  fake dungeon and moving our source to different positions relative
  2030. X *  to a block and finding the first/last visible position.  The fake
  2031. X *  dungeon is all clear execpt for the upper left corner (BLOCK_HEIGHT
  2032. X *  by BLOCK_WIDTH) is blocked.  Then we move the source around relative
  2033. X *  to the corner of the block.  For each new position of the source
  2034. X *  we check positions on rows "kittycorner" from the source.  We check
  2035. X *  positions until they are either in sight or out of sight (depends on
  2036. X *  which table we are generating).  The picture below shows the setup
  2037. X *  for the generation of the close table.  The generation of the far
  2038. X *  table would switch the quadrants of the '@' and the "Check rows
  2039. X *  here".
  2040. X *
  2041. X *
  2042. X *  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
  2043. X *  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
  2044. X *  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,,,,,,,, Check rows here ,,,,,,,,,,,,
  2045. X *  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
  2046. X *  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXB,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
  2047. X *  ...............................
  2048. X *  ...............................
  2049. X *  .........@.....................
  2050. X *  ...............................
  2051. X *
  2052. X *      Table generation figure (close_table).  The 'X's are blocked points.
  2053. X *      The 'B' is a special blocked point.  The '@' is the source.  The ','s
  2054. X *      are the target area.  The '.' are just open areas.
  2055. X *
  2056. X *
  2057. X *  Example usage of close_table[][][].
  2058. X *
  2059. X *  The table is as follows:
  2060. X *
  2061. X *      dy = |row of '@' - row of 'B'|  - 1
  2062. X *      dx = |col of '@' - col of 'B'|
  2063. X *
  2064. X *  The first indices are the deltas from the source '@' and the block 'B'.
  2065. X *  You must check for the value inside the abs value bars being zero.  If
  2066. X *  so then the block is on the same row and you don't need to do a table
  2067. X *  lookup.  The last value:
  2068. X *
  2069. X *      dcy = |row of block - row to be checked|
  2070. X *
  2071. X *  Is the value of the first visible spot on the check row from the
  2072. X *  block column.  So
  2073. X *
  2074. X *  first visible col = close_table[dy][dx][dcy] + col of 'B'
  2075. X *
  2076. X\*--------------  vision tables  --------------*/
  2077. X
  2078. Xstatic void
  2079. XH_close_gen()
  2080. X{
  2081. X    Fprintf(ofp,"\n/* Close */\n");
  2082. X    Fprintf(ofp,"#define CLOSE_MAX_SB_DY %2d\t/* |src row - block row| - 1\t*/\n",
  2083. X        TEST_HEIGHT-1);
  2084. X    Fprintf(ofp,"#define CLOSE_MAX_SB_DX %2d\t/* |src col - block col|\t*/\n",
  2085. X        TEST_WIDTH);
  2086. X    Fprintf(ofp,"#define CLOSE_MAX_BC_DY %2d\t/* |block row - check row|\t*/\n",
  2087. X        TEST_HEIGHT);
  2088. X    Fprintf(ofp,"typedef struct {\n");
  2089. X    Fprintf(ofp,"    unsigned char close[CLOSE_MAX_SB_DX][CLOSE_MAX_BC_DY];\n");
  2090. X    Fprintf(ofp,"} close2d;\n");
  2091. X    Fprintf(ofp,"extern close2d close_table[CLOSE_MAX_SB_DY];\n");
  2092. X    return;
  2093. X}
  2094. X
  2095. Xstatic void
  2096. XH_far_gen()
  2097. X{
  2098. X    Fprintf(ofp,"\n/* Far */\n");
  2099. X    Fprintf(ofp,"#define FAR_MAX_SB_DY %2d\t/* |src row - block row|\t*/\n",
  2100. X        TEST_HEIGHT);
  2101. X    Fprintf(ofp,"#define FAR_MAX_SB_DX %2d\t/* |src col - block col| - 1\t*/\n",
  2102. X        TEST_WIDTH-1);
  2103. X    Fprintf(ofp,"#define FAR_MAX_BC_DY %2d\t/* |block row - check row| - 1\t*/\n",
  2104. X        TEST_HEIGHT-1);
  2105. X    Fprintf(ofp,"typedef struct {\n");
  2106. X    Fprintf(ofp,"    unsigned char far_q[FAR_MAX_SB_DX][FAR_MAX_BC_DY];\n");
  2107. X    Fprintf(ofp,"} far2d;\n");
  2108. X    Fprintf(ofp,"extern far2d far_table[FAR_MAX_SB_DY];\n");
  2109. X    return;
  2110. X}
  2111. X
  2112. X# ifdef BRACES
  2113. X#  define L_BRACE "{"
  2114. X#  define R_BRACE "},"
  2115. X# else
  2116. X#  define L_BRACE ""
  2117. X#  define R_BRACE ""
  2118. X# endif /* BRACES */
  2119. X
  2120. Xstatic void
  2121. XC_close_gen()
  2122. X{
  2123. X    int i,dx,dy;
  2124. X    int src_row, src_col;    /* source */
  2125. X    int block_row, block_col;    /* block */
  2126. X    int this_row;
  2127. X    int no_more;
  2128. X
  2129. X    block_row = BLOCK_HEIGHT-1;
  2130. X    block_col = BLOCK_WIDTH-1;
  2131. X
  2132. X    Fprintf(ofp,"\n#ifndef FAR_TABLE_ONLY\n");
  2133. X    Fprintf(ofp,"\nclose2d close_table[CLOSE_MAX_SB_DY] = {\n");
  2134. X#ifndef no_vision_progress
  2135. X    Fprintf(stderr,"\nclose:");
  2136. X#endif
  2137. X
  2138. X    for (dy = 1; dy < TEST_HEIGHT; dy++) {
  2139. X    src_row = block_row + dy;
  2140. X    Fprintf(ofp,"/* DY = %2d (- 1)*/\n  {\n",dy);
  2141. X#ifndef no_vision_progress
  2142. X    Fprintf(stderr," %2d",dy),  (void)fflush(stderr);
  2143. X#endif
  2144. X    for (dx = 0; dx < TEST_WIDTH; dx++) {
  2145. X        src_col = block_col - dx;
  2146. X        Fprintf(ofp,"  /*%2d*/  %s",dx, L_BRACE);
  2147. X
  2148. X        no_more = 0;
  2149. X        for (this_row = 0; this_row < TEST_HEIGHT; this_row++) {
  2150. X        if (no_more) {
  2151. X            Fprintf(ofp,CLOSE_OFF_TABLE_STRING);
  2152. X            continue;
  2153. X        }
  2154. X
  2155. X        SpinCursor(3);
  2156. X
  2157. X        /* Find the first column that we can see. */
  2158. X        for (i = block_col+1; i < MAX_COL; i++) {
  2159. X
  2160. X            if (clear_path(src_row,src_col,block_row-this_row,i))
  2161. X            break;
  2162. X        }
  2163. X
  2164. X        if (i == MAX_COL) no_more = 1;
  2165. X        Fprintf(ofp,"%2d,",i-block_col);
  2166. X        }
  2167. X        Fprintf(ofp,"%s\n", R_BRACE);
  2168. X    }
  2169. X    Fprintf(ofp,"  },\n");
  2170. X    }
  2171. X
  2172. X    Fprintf(ofp,"}; /* close_table[] */\n");        /* closing brace for table */
  2173. X    Fprintf(ofp,"#endif /* !FAR_TABLE_ONLY */\n");
  2174. X#ifndef no_vision_progress
  2175. X    Fprintf(stderr,"\n");
  2176. X#endif
  2177. X    return;
  2178. X}
  2179. X
  2180. Xstatic void
  2181. XC_far_gen()
  2182. X{
  2183. X    int i,dx,dy;
  2184. X    int src_row, src_col;    /* source */
  2185. X    int block_row, block_col;    /* block */
  2186. X    int this_row;
  2187. X
  2188. X    block_row = BLOCK_HEIGHT-1;
  2189. X    block_col = BLOCK_WIDTH-1;
  2190. X
  2191. X    Fprintf(ofp,"\n#ifndef CLOSE_TABLE_ONLY\n");
  2192. X    Fprintf(ofp,"\nfar2d far_table[FAR_MAX_SB_DY] = {\n");
  2193. X#ifndef no_vision_progress
  2194. X    Fprintf(stderr,"\n_far_:");
  2195. X#endif
  2196. X
  2197. X    for (dy = 0; dy < TEST_HEIGHT; dy++) {
  2198. X    src_row = block_row - dy;
  2199. X    Fprintf(ofp,"/* DY = %2d */\n  {\n",dy);
  2200. X#ifndef no_vision_progress
  2201. X    Fprintf(stderr," %2d",dy),  (void)fflush(stderr);
  2202. X#endif
  2203. X    for (dx = 1; dx < TEST_WIDTH; dx++) {
  2204. X        src_col = block_col + dx;
  2205. X        Fprintf(ofp,"  /*%2d(-1)*/ %s",dx, L_BRACE);
  2206. X
  2207. X        for (this_row = block_row+1; this_row < block_row+TEST_HEIGHT;
  2208. X                                this_row++) {
  2209. X        /* Find first col that we can see. */
  2210. X        for (i = 0; i <= block_col; i++) {
  2211. X
  2212. X            SpinCursor(3);
  2213. X
  2214. X            if (clear_path(src_row,src_col,this_row,i)) break;
  2215. X        }
  2216. X
  2217. X        if (block_col-i < 0)
  2218. X            Fprintf(ofp,FAR_OFF_TABLE_STRING);
  2219. X        else
  2220. X            Fprintf(ofp,"%2d,",block_col-i);
  2221. X        }
  2222. X        Fprintf(ofp,"%s\n", R_BRACE);
  2223. X    }
  2224. X    Fprintf(ofp,"  },\n");
  2225. X    }
  2226. X
  2227. X    Fprintf(ofp,"}; /* far_table[] */\n");    /* closing brace for table */
  2228. X    Fprintf(ofp,"#endif /* !CLOSE_TABLE_ONLY */\n");
  2229. X#ifndef no_vision_progress
  2230. X    Fprintf(stderr,"\n");
  2231. X#endif
  2232. X    return;
  2233. X}
  2234. X
  2235. X/*
  2236. X *  "Draw" a line from the hero to the given location.  Stop of we hit a
  2237. X *  wall.
  2238. X *
  2239. X *  Generalized integer Bresenham's algorithm (fast line drawing) for
  2240. X *  all quadrants.  From _Procedural Elements for Computer Graphics_, by
  2241. X *  David F. Rogers.  McGraw-Hill, 1985.
  2242. X *
  2243. X *  I have tried a little bit of optimization by pulling compares out of
  2244. X *  the inner loops.
  2245. X *
  2246. X *  NOTE:  This had better *not* be called from a position on the
  2247. X *  same row as the hero.
  2248. X */
  2249. Xstatic int
  2250. Xclear_path(you_row,you_col,y2,x2)
  2251. X    int you_row, you_col, y2, x2;
  2252. X{
  2253. X    int dx, dy, s1, s2;
  2254. X    register int i, error, x, y, dxs, dys;
  2255. X
  2256. X    x  = you_col;        y  = you_row;
  2257. X    dx = abs(x2-you_col);    dy = abs(y2-you_row);
  2258. X    s1 = sign(x2-you_col);    s2 = sign(y2-you_row);
  2259. X
  2260. X    if (s1 == 0) {    /* same column */
  2261. X    if (s2 == 1) {    /* below (larger y2 value) */
  2262. X        for (i = you_row+1; i < y2; i++)
  2263. X        if (!xclear[i][you_col]) return 0;
  2264. X    } else {    /* above (smaller y2 value) */
  2265. X        for (i = y2+1; i < you_row; i++)
  2266. X        if (!xclear[i][you_col]) return 0;
  2267. X    }
  2268. X    return 1;
  2269. X    }
  2270. X
  2271. X    /*
  2272. X     *  Lines at 0 and 90 degrees have been weeded out.
  2273. X     */
  2274. X    if (dy > dx) {
  2275. X    error = dx; dx = dy; dy = error;    /* swap the values */
  2276. X    dxs = dx << 1;        /* save the shifted values */
  2277. X    dys = dy << 1;
  2278. X    error = dys - dx;    /* NOTE: error is used as a temporary above */
  2279. X
  2280. X    for (i = 0; i < dx; i++) {
  2281. X        if (!xclear[y][x]) return 0;    /* plot point */
  2282. X
  2283. X        while (error >= 0) {
  2284. X        x += s1;
  2285. X        error -= dxs;
  2286. X        }
  2287. X        y += s2;
  2288. X        error += dys;
  2289. X    }
  2290. X    } else {
  2291. X    dxs = dx << 1;        /* save the shifted values */
  2292. X    dys = dy << 1;
  2293. X    error = dys - dx;
  2294. X
  2295. X    for (i = 0; i < dx; i++) {
  2296. X        if (!xclear[y][x]) return 0;    /* plot point */
  2297. X
  2298. X        while (error >= 0) {
  2299. X        y += s2;
  2300. X        error -= dxs;
  2301. X        }
  2302. X        x += s1;
  2303. X        error += dys;
  2304. X    }
  2305. X    }
  2306. X    return 1;
  2307. X}
  2308. X#endif /* VISION_TABLES */
  2309. X
  2310. X/*makedefs.c*/
  2311. END_OF_FILE
  2312. if test 45073 -ne `wc -c <'util/makedefs.c'`; then
  2313.     echo shar: \"'util/makedefs.c'\" unpacked with wrong size!
  2314. fi
  2315. # end of 'util/makedefs.c'
  2316. fi
  2317. echo shar: End of archive 17 \(of 108\).
  2318. cp /dev/null ark17isdone
  2319. MISSING=""
  2320. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2321. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2322. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2323. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2324. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2325. 101 102 103 104 105 106 107 108 ; do
  2326.     if test ! -f ark${I}isdone ; then
  2327.     MISSING="${MISSING} ${I}"
  2328.     fi
  2329. done
  2330. if test "${MISSING}" = "" ; then
  2331.     echo You have unpacked all 108 archives.
  2332.     echo "Now execute 'rebuild.sh'"
  2333.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2334. else
  2335.     echo You still need to unpack the following archives:
  2336.     echo "        " ${MISSING}
  2337. fi
  2338. ##  End of shell archive.
  2339. exit 0
  2340.