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