home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / part92 < prev    next >
Encoding:
Internet Message Format  |  1993-02-05  |  58.3 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: v16i100:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part92/108
  5. Message-ID: <4465@master.CNA.TEK.COM>
  6. Date: 5 Feb 93 22:02:44 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2409
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1651
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 100
  14. Archive-name: nethack31/Part92
  15. Supersedes: nethack3p9: Volume 10, Issue 46-108
  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 92 (of 108)."
  27. # Contents:  dat/tower.des doc/lev_comp.6 src/botl.c sys/amiga/amidos.c
  28. #   sys/vms/vmsmain.c win/X11/winmenu.c
  29. # Wrapped by billr@saab on Wed Jan 27 16:09:25 1993
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. if test -f 'dat/tower.des' -a "${1}" != "-c" ; then 
  32.   echo shar: Will not clobber existing file \"'dat/tower.des'\"
  33. else
  34. echo shar: Extracting \"'dat/tower.des'\" \(3290 characters\)
  35. sed "s/^X//" >'dat/tower.des' <<'END_OF_FILE'
  36. X#    SCCS Id: @(#)tower.des    3.1    90/02/26
  37. X#    Copyright (c) 1989 by Jean-Christophe Collet
  38. X# NetHack may be freely redistributed.  See license for details.
  39. X#
  40. X# Upper stage of Vlad's tower
  41. XMAZE:"tower1",' '
  42. XFLAGS: noteleport,hardfloor
  43. XGEOMETRY:half-left,center
  44. XMAP
  45. X  --- --- ---  
  46. X  |.| |.| |.|  
  47. X---S---S---S---
  48. X|.......+.+...|
  49. X---+-----.-----
  50. X  |...\.|.+.|  
  51. X---+-----.-----
  52. X|.......+.+...|
  53. X---S---S---S---
  54. X  |.| |.| |.|  
  55. X  --- --- ---  
  56. XENDMAP
  57. XLADDER:(11,05),down
  58. X# The lord and his court
  59. XMONSTER:'V',"Vlad the Impaler",(06,05)
  60. XMONSTER:'V',random,(03,09)
  61. XMONSTER:'V',random,(07,09)
  62. XMONSTER:'V',random,(11,09)
  63. XMONSTER:'V',random,(03,01)
  64. XMONSTER:'V',random,(07,01)
  65. XMONSTER:'V',random,(11,01)
  66. X# The doors
  67. XDOOR:closed,(08,03)
  68. XDOOR:closed,(10,03)
  69. XDOOR:closed,(03,04)
  70. XDOOR:locked,(10,05)
  71. XDOOR:locked,(08,07)
  72. XDOOR:locked,(10,07)
  73. XDOOR:closed,(03,06)
  74. X# treasures
  75. XOBJECT:'(',"chest",(07,05)
  76. XOBJECT:'(',"chest",(03,09)
  77. XOBJECT:'(',"chest",(07,09)
  78. XOBJECT:'(',"chest",(11,09)
  79. XOBJECT:'(',"chest",(03,01)
  80. XOBJECT:'(',"chest",(07,01)
  81. XOBJECT:'(',"chest",(11,01)
  82. X# We have to protect the tower against outside attacks
  83. XNON_DIGGABLE:(00,00,14,10)
  84. X
  85. X
  86. X# Intermediate stage of Vlad's tower
  87. XMAZE:"tower2",' '
  88. XFLAGS: noteleport,hardfloor
  89. XGEOMETRY:half-left,center
  90. XMAP
  91. X  --- --- ---  
  92. X  |.| |.| |.|  
  93. X---S---S---S---
  94. X|.S.........S.|
  95. X---.------+----
  96. X  |......|..|  
  97. X--------.------
  98. X|.S......+..S.|
  99. X---S---S---S---
  100. X  |.| |.| |.|  
  101. X  --- --- ---  
  102. XENDMAP
  103. X# Random places are the 10 niches
  104. XRANDOM_PLACES:(03,01),(07,01),(11,01),(01,03),(13,03),
  105. X          (01,07),(13,07),(03,09),(07,09),(11,09)
  106. XLADDER:(11,05),up
  107. XLADDER:(03,07),down
  108. XDOOR:locked,(10,04)
  109. XDOOR:locked,(09,07)
  110. XMONSTER:'&',random,place[0]
  111. XMONSTER:'&',random,place[1]
  112. XMONSTER:'d',"hell hound pup",place[2]
  113. XMONSTER:'d',"hell hound pup",place[3]
  114. XMONSTER:'d',"winter wolf",place[4]
  115. XOBJECT:'"',"amulet of life saving",place[5]
  116. XOBJECT:'"',"amulet of strangulation",place[6]
  117. XOBJECT:'[',"water walking boots",place[7]
  118. XOBJECT:'[',"crystal plate mail",place[8]
  119. XOBJECT:'+',"invisibility",place[9]
  120. X# Walls in the tower are non diggable
  121. XNON_DIGGABLE:(00,00,14,10)
  122. X
  123. X
  124. X# Bottom most stage of Vlad's tower
  125. XMAZE:"tower3",' '
  126. XFLAGS: noteleport,hardfloor
  127. XGEOMETRY:half-left,center
  128. XMAP
  129. X    --- --- ---  
  130. X    |.| |.| |.|  
  131. X  ---S---S---S---
  132. X  |.S.........S.|
  133. X-----.........-----
  134. X|...|.........+...|
  135. X|.---.........---.|
  136. X|.|.S.........S.|.|
  137. X|.---S---S---S---.|
  138. X|...|.|.|.|.|.|...|
  139. X---.---.---.---.---
  140. X  |.............|  
  141. X  ---------------  
  142. XENDMAP
  143. X# Random places are the 10 niches
  144. XRANDOM_PLACES:(05,01),(09,01),(13,01),(03,03),(15,03),
  145. X          (03,07),(15,07),(05,09),(09,09),(13,09)
  146. XBRANCH:(02,05,02,05),(00,00,00,00)
  147. XLADDER:(05,07),up
  148. X# Entry door is, of course, locked
  149. XDOOR:locked,(14,05)
  150. X# Let's put a dragon behind the door, just for the fun...
  151. XMONSTER:'D',random,(13,05)
  152. XMONSTER:random,random,(12,04)
  153. XMONSTER:random,random,(12,06)
  154. XMONSTER:random,random,random
  155. XMONSTER:random,random,random
  156. XMONSTER:random,random,random
  157. XMONSTER:random,random,random
  158. XMONSTER:random,random,random
  159. XMONSTER:random,random,random
  160. XOBJECT:')',"long sword",place[0]
  161. XTRAP:random,place[0]
  162. XOBJECT:'(',"lock pick",place[1]
  163. XTRAP:random,place[1]
  164. XOBJECT:'[',"elven cloak",place[2]
  165. XTRAP:random,place[2]
  166. XOBJECT:'(',"blindfold",place[3]
  167. XTRAP:random,place[3]
  168. X# Walls in the tower are non diggable
  169. XNON_DIGGABLE:(00,00,18,12)
  170. END_OF_FILE
  171. if test 3290 -ne `wc -c <'dat/tower.des'`; then
  172.     echo shar: \"'dat/tower.des'\" unpacked with wrong size!
  173. fi
  174. # end of 'dat/tower.des'
  175. fi
  176. if test -f 'doc/lev_comp.6' -a "${1}" != "-c" ; then 
  177.   echo shar: Will not clobber existing file \"'doc/lev_comp.6'\"
  178. else
  179. echo shar: Extracting \"'doc/lev_comp.6'\" \(10188 characters\)
  180. sed "s/^X//" >'doc/lev_comp.6' <<'END_OF_FILE'
  181. X.TH LEV_COMP 6 "29 Dec 1992"
  182. X.UC 4
  183. X.SH NAME
  184. Xlev_comp \- NetHack special levels compiler
  185. X.SH SYNOPSIS
  186. X.B lev_comp
  187. X[
  188. X.B \-w
  189. X]
  190. X[
  191. X.I files
  192. X]
  193. X.PP
  194. XIf no arguments are given, it reads standard input.
  195. X.SH DESCRIPTION
  196. X.PP
  197. X.I Lev_comp
  198. Xis a special level compiler for NetHack version 3.1 and higher.  It
  199. Xtakes description files as arguments and produces level files that can
  200. Xbe loaded by NetHack at runtime.
  201. X.PP
  202. XThe purpose of this tool is to provide NetHack administrators and
  203. Ximplementors with a convenient way for adding special levels to the
  204. Xgame, or modifying existing ones, without having to recompile the
  205. Xentire world.
  206. X.PP
  207. XThe
  208. X.B \-w
  209. Xoption causes
  210. X.I lev_comp
  211. Xto perform extra checks on the level and display extra warnings, however
  212. Xthese warnings are sometimes superfluous, so they are not normally displayed.
  213. X
  214. X.SH GRAMMAR
  215. X.PP
  216. X.LP
  217. X.nf
  218. X.ta +8n +8n +8n +8n
  219. X
  220. Xfile        : /* nothing */
  221. X        | levels
  222. X
  223. Xlevels        : level
  224. X        | level levels
  225. X
  226. Xlevel        : maze_level
  227. X            | room_level
  228. X
  229. Xmaze_level    : maze_def flags lev_init messages regions
  230. X
  231. Xroom_level    : level_def flags lev_init messages
  232. X          rreg_init rooms corridors_def
  233. X
  234. Xlevel_def    : "LEVEL" ':' string
  235. X
  236. Xlev_init    : /* nothing */
  237. X        | "INIT_MAP" ':' fgtyp ',' bgtyp ',' smooth ','
  238. X          joined ',' light_state ',' walled
  239. X
  240. Xfgtyp        : CHAR /* a MAP map_contents character */
  241. X
  242. Xbgtyp        : CHAR /* a MAP map_contents character */
  243. X
  244. Xsmooth        : boolean
  245. X
  246. Xjoined        : boolean
  247. X
  248. Xwalled        : boolean | "random"
  249. X
  250. Xflags        : /* nothing */
  251. X        | "FLAGS" ':' flag_list
  252. X
  253. Xflag_list    : flag_type
  254. X        | flag_type ',' flag_list
  255. X
  256. Xflag_type    : "noteleport" | "hardfloor" | "nommap"  | "shortsighted"
  257. X
  258. Xmessages    : /* nothing */
  259. X        | message messages
  260. X
  261. Xmessage        : "MESSAGE" ':' STRING
  262. X
  263. Xrreg_init    : /* nothing */
  264. X        | rreg_init init_rreg
  265. X
  266. Xinit_rreg    : "RANDOM_OBJECTS" ':' object_list
  267. X        | "RANDOM_MONSTERS" ':' monster_list
  268. X
  269. Xrooms        : /* nothing */
  270. X        | roomlist
  271. X
  272. Xroomlist    : aroom
  273. X        | aroom rooms
  274. X
  275. Xcorridors_def    : random_corridors
  276. X        | corridors
  277. X
  278. Xrandom_corridors: "RANDOM_CORRIDOR"
  279. X
  280. Xcorridors    : /* nothing */
  281. X        | corridors corridor
  282. X
  283. Xcorridor    : "CORRIDOR" ':' corr_spec ',' corr_spec
  284. X        | "CORRIDOR" ':' corr_spec ',' INTEGER
  285. X
  286. Xcorr_spec    : '(' INTEGER ',' direction ',' door_pos ')'
  287. X
  288. Xdirection    : "north" | "south" | "east" | "west"
  289. X
  290. Xaroom        : room_def room_details
  291. X        | subroom_def room_details
  292. X
  293. Xsubroom_def    : "SUBROOM" ':' room_type ',' light_state ','
  294. X          subroom_pos ',' room_size ',' string
  295. X
  296. Xroom_def    : "ROOM" ':' room_type ',' light_state ','
  297. X          room_pos ',' room_align ',' room_size
  298. X
  299. Xroom_pos    : '(' INTEGER ',' INTEGER ')'
  300. X        | "random"
  301. X
  302. Xsubroom_pos    : '(' INTEGER ',' INTEGER ')'
  303. X        | "random"
  304. X
  305. Xroom_align    : '(' h_justif ',' v_justif ')'
  306. X        | "random"
  307. X
  308. Xroom_size    : '(' INTEGER ',' INTEGER ')'
  309. X        | "random"
  310. X
  311. Xroom_details    : /* nothing */
  312. X        | room_details room_detail
  313. X
  314. Xroom_detail    : room_name
  315. X        | room_chance
  316. X        | room_door
  317. X        | monster_detail
  318. X        | object_detail
  319. X        | trap_detail
  320. X        | altar_detail
  321. X        | fountain_detail
  322. X        | sink_detail
  323. X        | pool_detail
  324. X        | gold_detail
  325. X        | engraving_detail
  326. X        | stair_detail
  327. X
  328. Xroom_name    : "NAME" ':' string
  329. X
  330. Xroom_chance    : "CHANCE" ':' INTEGER
  331. X
  332. Xroom_door    : "DOOR" ':' secret ',' door_state ','
  333. X          door_wall ',' door_pos
  334. X
  335. Xsecret        : boolean
  336. X        | "random"
  337. X
  338. Xdoor_wall    : direction
  339. X        | "random"
  340. X
  341. Xdoor_pos    : INTEGER
  342. X        | "random"
  343. X
  344. Xboolean        : "true" | "false"
  345. X
  346. Xmaze_def    : "MAZE" ':' string ',' filling
  347. X
  348. Xfilling        : CHAR
  349. X        | "random"
  350. Xregions     : aregion
  351. X        | aregion regions
  352. X
  353. Xaregion     : map_definition reg_init map_details
  354. X
  355. Xmap_definition    : "NOMAP"
  356. X        | map_geometry "MAP" map_contents "ENDMAP"
  357. X
  358. Xmap_geometry    : "GEOMETRY" ':' h_justif ',' v_justif
  359. X
  360. Xmap_contents    : /* see discussion below */
  361. X
  362. Xh_justif    : "left" | "half-left" | "right" | "half-right"
  363. X        | "center"
  364. X
  365. Xv_justif    : "top" | "bottom"
  366. X        | "center"
  367. X
  368. Xreg_init    : /* nothing */
  369. X        | reg_init init_reg
  370. X
  371. Xinit_reg    : "RANDOM_OBJECTS" ':' object_list
  372. X        | "RANDOM_PLACES" ':' place_list
  373. X        | "RANDOM_MONSTERS" ':' monster_list
  374. X
  375. Xobject_list    : object
  376. X        | object ',' object_list
  377. X
  378. Xmonster_list    : monster
  379. X        | monster ',' monster_list
  380. X
  381. Xplace_list    : place
  382. X        | place ',' place_list
  383. X
  384. Xmap_details    : /* nothing */
  385. X        | map_details map_detail
  386. X
  387. Xmap_detail    : monster_detail
  388. X        | object_detail
  389. X        | door_detail
  390. X        | trap_detail
  391. X        | drawbridge_detail
  392. X        | region_detail
  393. X        | stair_region
  394. X        | portal_region
  395. X        | teleprt_region
  396. X        | branch_region
  397. X        | altar_detail
  398. X        | fountain_detail
  399. X        | mazewalk_detail
  400. X                | wallify_detail
  401. X        | ladder_detail
  402. X        | stair_detail
  403. X        | gold_detail
  404. X        | engraving_detail
  405. X        | diggable_detail
  406. X
  407. Xmonster_detail    : "MONSTER" ':' monster_c ',' m_name ',' coordinate
  408. X          monster_infos
  409. X
  410. Xmonster_infos    : /* nothing */
  411. X        | monster_infos monster_info
  412. X
  413. Xmonster_info    : ',' string
  414. X        | ',' mon_attitude
  415. X        | ',' mon_alertness
  416. X        | ',' alignment
  417. X        | ',' "m_feature" string
  418. X        | ',' "m_monster" string
  419. X        | ',' "m_object" string
  420. X
  421. Xmon_attitude    : "peaceful" | "hostile"
  422. X
  423. Xmon_alertness    : "asleep" | "awake"
  424. X
  425. Xobject_detail    : "OBJECT" ':' object_c ',' o_name ',' coordinate
  426. X          object_infos
  427. X
  428. Xobject_infos    : /* nothing */
  429. X        | ',' STRING ',' enchantment
  430. X            | ',' curse_state ',' enchantment ',' art_name
  431. X
  432. Xcurse_state    : "random"
  433. X        | "blessed" | "uncursed" | "cursed"
  434. X
  435. Xenchantment    : INTEGER
  436. X        | "random"
  437. X
  438. Xdoor_detail    : "DOOR" ':' door_state ',' coordinate
  439. X
  440. Xtrap_detail    : "TRAP" ':' trap_name ',' coordinate
  441. X
  442. Xdrawbridge_detail: "DRAWBRIDGE" ':' coordinate ','
  443. X          direction ',' door_state
  444. X
  445. Xmazewalk_detail    : "MAZEWALK" ':' coordinate ',' direction
  446. X
  447. Xwallify_detail    : "WALLIFY"
  448. X
  449. Xladder_detail    : "LADDER" ':' coordinate ',' up_or_down
  450. X
  451. Xstair_detail    : "STAIR" ':' coordinate ',' up_or_down
  452. X
  453. Xstair_region    : "STAIR" ':' lev_region ',' lev_region ',' up_or_down
  454. X
  455. Xup_or_down:    : "up" | "down"
  456. X
  457. Xportal_region    : "PORTAL" ':' lev_region ',' lev_region ',' string
  458. X
  459. Xteleprt_region    : "TELEPORT_REGION" ':' lev_region
  460. X          ',' lev_region teleprt_detail
  461. X
  462. Xbranch_region    : "BRANCH" ':' lev_region ',' lev_region
  463. X
  464. Xteleprt_detail    : /* empty */
  465. X        | ',' up_or_down
  466. X
  467. Xlev_region    : region
  468. X        | "levregion"
  469. X          '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'
  470. X
  471. Xfountain_detail    : "FOUNTAIN" ':' coordinate
  472. X
  473. Xsink_detail    : "SINK" ':' coordinate
  474. X
  475. Xpool_detail    : "POOL" ':' coordinate
  476. X
  477. Xdiggable_detail    : "NON_DIGGABLE" ':' region
  478. X
  479. Xregion_detail    : "REGION" ':' region ',' light_state ','
  480. X          room_type prefilled
  481. X
  482. Xaltar_detail    : "ALTAR" ':' coordinate ',' alignment ',' altar_type
  483. X
  484. Xgold_detail    : "GOLD" ':' amount ',' coordinate
  485. X
  486. Xengraving_detail: "ENGRAVING" ':' coordinate ','
  487. X          engraving_type ',' string
  488. X
  489. Xmonster_c    : monster
  490. X        | "random"
  491. X        | m_register
  492. X
  493. Xobject_c    : object
  494. X        | "random"
  495. X        | o_register
  496. X
  497. Xm_name        : string
  498. X        | "random"
  499. X
  500. Xo_name        : string
  501. X        | "random"
  502. X
  503. Xtrap_name    : string
  504. X        | "random"
  505. X
  506. Xroom_type    : string
  507. X        | "random"
  508. X
  509. Xprefilled    : /* empty */
  510. X        | ',' filling
  511. X        | ',' filling ',' irregular
  512. X
  513. Xfilling        : "filled" | "unfilled"
  514. X
  515. Xirregular    : boolean /* irregular shaped room around region */
  516. X
  517. Xcoordinate    : coord
  518. X        | p_register
  519. X        | "random"
  520. X
  521. Xdoor_state    : "open" | "closed" | "locked" | "nodoor" | "broken"
  522. X        | "random"
  523. X
  524. Xlight_state    : "lit" | "unlit"
  525. X        | "random"
  526. X
  527. Xalignment    : "noalign" | "law" | "neutral" | "chaos"
  528. X        | a_register
  529. X        | "random"
  530. X
  531. Xaltar_type    : "sanctum" | "shrine" | "altar"
  532. X        | "random"
  533. X
  534. Xp_register    : "place" '[' INTEGER ']'
  535. X
  536. Xo_register    : "object" '[' INTEGER ']'
  537. X
  538. Xm_register    : "monster" '[' INTEGER ']'
  539. X
  540. Xa_register    : "align" '[' INTEGER ']'
  541. X
  542. Xplace        : coord
  543. X
  544. Xmonster     : CHAR
  545. X
  546. Xobject        : CHAR
  547. X
  548. Xstring        : STRING
  549. X
  550. Xart_name    : STRING
  551. X        | "none"
  552. X
  553. Xamount        : INTEGER
  554. X        | "random"
  555. X
  556. Xengraving_type    : "dust" | "engrave" | "burn" | "mark"
  557. X        | "random"
  558. X
  559. Xcoord        : '(' INTEGER ',' INTEGER ')'
  560. X
  561. Xregion        : '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'
  562. X.fi
  563. X.PP
  564. X.I NOTE:
  565. X.br
  566. XLines beginning with '#' are considered comments.
  567. X.PP
  568. XThe contents of a "MAP" description of a maze is a rectangle showing the exact
  569. Xlevel map that should be used for the given part of a maze.
  570. XEach character in the map corresponds to a location on the screen.
  571. XDifferent location types are denoted using different ASCII characters.
  572. XThe following characters are recognized.
  573. XTo give an idea of how these are used, see the EXAMPLE, below.
  574. XThe maximum size of a map is normally 76 columns by 21 rows.
  575. X.LP
  576. X.nf
  577. X.ta +8n +8n +8n
  578. X\&'-'    horizontal wall
  579. X\&'|'    vertical wall
  580. X\&'+'    a doorway (state is specified in a DOOR declaration)
  581. X\&'A'    open air
  582. X\&'B'    boundary room location (for bounding unwalled irregular regions)
  583. X\&'C'    cloudy air
  584. X\&'I'    ice
  585. X\&'S'    a secret door
  586. X\&'{'    a fountain
  587. X\&'\\'    a throne
  588. X\&'K'    a sink (if SINKS is defined, else a room location)
  589. X\&'}'    a part of a moat or other deep water
  590. X\&'P'    a pool
  591. X\&'L'    lava
  592. X\&'#'    a corridor
  593. X\&'.'    a normal room location (unlit unless lit in a REGION declaration)
  594. X\&' '    stone
  595. X.fi
  596. X.SH EXAMPLE
  597. X.PP
  598. XHere is an example of a description file (a very simple one):
  599. X.LP
  600. X.nf
  601. X.ta +8n +8n +8n
  602. XMAZE : "fortress", random
  603. XGEOMETRY : center , center
  604. XMAP
  605. X}}}}}}}}}
  606. X}}}|-|}}}
  607. X}}|-.-|}}
  608. X}|-...-|}
  609. X}|.....|}
  610. X}|-...-|}
  611. X}}|-.-|}}
  612. X}}}|-|}}}
  613. X}}}}}}}}}
  614. XENDMAP
  615. XMONSTER: '@', "Wizard of Yendor", (4,4)
  616. XOBJECT: '"', "Amulet of Yendor", (4,4)
  617. X# a hell hound flanking the Wiz on a random side
  618. XRANDOM_PLACES: (4,3), (4,5), (3,4), (5,4)
  619. XMONSTER: 'd', "hell hound", place[0]
  620. X# a chest on another random side
  621. XOBJECT: '(', "chest", place[1]
  622. X# a random dragon somewhere
  623. XMONSTER: 'D', random, random
  624. X# a random trap in the EAST end
  625. XTRAP: random, (6,4)
  626. X# an electric eel below the SOUTH end
  627. XMONSTER: ';', "electric eel", (4,8)
  628. X# make the walls non-diggable
  629. XNON_DIGGABLE: (0,0,8,8)
  630. XTELEPORT_REGION: lev_region(0,0,79,20), (0,0,8,8)
  631. X.fi
  632. X.PP
  633. XThis example will produce a file named "fortress" that can be integrated into
  634. Xone of the numerous mazes of the game.
  635. X.PP
  636. XNote especially the final, TELEPORT_REGION specification.  This says
  637. Xthat level teleports or other non-stairway arrivals on this level can
  638. Xland anywhere on the level except the area of the map.  This shows the
  639. Xuse of the ``lev_region'' prefix allowed in certain region specifications.
  640. XNormally, regions apply only to the most recent MAP specification, but
  641. Xwhen prefixed with ``lev_region'', one can refer to any area of the
  642. Xlevel, regardless of the placement of the current MAP in the level.
  643. X.SH AUTHOR
  644. X.PP
  645. XJean-Christophe Collet, David Cohrs.
  646. X.SH "SEE ALSO"
  647. X.PP
  648. Xdgn_comp(6), nethack(6)
  649. X.SH BUGS
  650. X.PP
  651. XProbably infinite.
  652. XMost importantly, still needs additional bounds checking.
  653. END_OF_FILE
  654. if test 10188 -ne `wc -c <'doc/lev_comp.6'`; then
  655.     echo shar: \"'doc/lev_comp.6'\" unpacked with wrong size!
  656. fi
  657. # end of 'doc/lev_comp.6'
  658. fi
  659. if test -f 'src/botl.c' -a "${1}" != "-c" ; then 
  660.   echo shar: Will not clobber existing file \"'src/botl.c'\"
  661. else
  662. echo shar: Extracting \"'src/botl.c'\" \(9881 characters\)
  663. sed "s/^X//" >'src/botl.c' <<'END_OF_FILE'
  664. X/*    SCCS Id: @(#)botl.c    3.1    93/01/17    */
  665. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  666. X/* NetHack may be freely redistributed.  See license for details. */
  667. X
  668. X#include "hack.h"
  669. X
  670. X#ifdef OVL0
  671. Xextern const char *hu_stat[];    /* defined in eat.c */
  672. X
  673. Xconst char *enc_stat[] = {
  674. X    "",
  675. X    "Burdened",
  676. X    "Stressed",
  677. X    "Strained",
  678. X    "Overtaxed",
  679. X    "Overloaded"
  680. X};
  681. X
  682. Xstatic void NDECL(bot1);
  683. Xstatic void NDECL(bot2);
  684. X#endif /* OVL0 */
  685. X
  686. X/* 100 suffices for bot(); must be larger than COLNO */
  687. X#if COLNO <= 80
  688. X#define MAXCO 100
  689. X#else
  690. X#define MAXCO (COLNO+20)
  691. X#endif
  692. X
  693. X#ifndef OVLB
  694. XSTATIC_DCL int mrank_sz;
  695. X#else /* OVLB */
  696. XSTATIC_OVL int NEARDATA mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */
  697. X#endif /* OVLB */
  698. X
  699. Xstruct rank_title {
  700. X    char const * const    m;    /* male title */
  701. X    char const * const    f;    /* female title, or 0 if same as male */
  702. X};
  703. Xstruct class_ranks {
  704. X    char        plclass, fill_;
  705. X    short        mplayer_class;
  706. X    struct rank_title    titles[9];
  707. X};
  708. X
  709. XSTATIC_DCL const struct rank_title *FDECL(rank_array, (CHAR_P));
  710. XSTATIC_DCL const char *NDECL(rank);
  711. X
  712. X#ifdef OVL1
  713. X
  714. X/* 9 pairs of ranks for each class */
  715. X
  716. Xstatic const
  717. Xstruct class_ranks all_classes[] = {
  718. X  {                    'A',0,    PM_ARCHEOLOGIST, {
  719. X    {"Digger",    0},
  720. X    {"Field Worker",0},
  721. X    {"Investigator",0},
  722. X    {"Exhumer",    0},
  723. X    {"Excavator",    0},
  724. X    {"Spelunker",    0},
  725. X    {"Speleologist",0},
  726. X    {"Collector",    0},
  727. X    {"Curator",    0}
  728. X  } },
  729. X  {                    'B',0,    PM_BARBARIAN, {
  730. X    {"Plunderer",    "Plunderess"},
  731. X    {"Pillager",    0},
  732. X    {"Bandit",    0},
  733. X    {"Brigand",    0},
  734. X    {"Raider",    0},
  735. X    {"Reaver",    0},
  736. X    {"Slayer",    0},
  737. X    {"Chieftain",    "Chieftainess"},
  738. X    {"Conqueror",    "Conqueress"}
  739. X  } },
  740. X  {                    'C',0,    PM_CAVEMAN, {
  741. X    {"Troglodyte",    0},
  742. X    {"Aborigine",    0},
  743. X    {"Wanderer",    0},
  744. X    {"Vagrant",    0},
  745. X    {"Wayfarer",    0},
  746. X    {"Roamer",    0},
  747. X    {"Nomad",    0},
  748. X    {"Rover",    0},
  749. X    {"Pioneer",    0}
  750. X  } },
  751. X  {                    'E',0,    PM_ELF, {
  752. X    {"Edhel",    "Elleth"},
  753. X    {"Edhel",    "Elleth"},    /* elf-maid */
  754. X    {"Ohtar",    "Ohtie"},    /* warrior */
  755. X    {"Kano",            /* commander (Q.) ['a] */
  756. X            "Kanie"}, /* educated guess, until further research- SAC */
  757. X    {"Arandur",          /* king's servant, minister (Q.) - guess */
  758. X            "Aranduriel"},    /* educated guess */
  759. X    {"Hir",        "Hiril"},    /* lord, lady (S.) ['ir] */
  760. X    {"Aredhel",    "Arwen"},    /* noble elf, maiden (S.) */
  761. X    {"Ernil",    "Elentariel"},    /* prince (S.), elf-maiden (Q.) */
  762. X    {"Elentar",    "Elentari"}    /* Star-king, -queen (Q.) */
  763. X  } },
  764. X  {                    'H',0,    PM_HEALER, {
  765. X    {"Barber",    "Midwife"},
  766. X    {"Leech",    0},
  767. X    {"Embalmer",    0},
  768. X    {"Dresser",    0},
  769. X    {"Bone Setter",    0},
  770. X    {"Herbalist",    0},
  771. X    {"Apothecary",    0},
  772. X    {"Physician",    0},
  773. X    {"Chirurgeon",    0}
  774. X  } },
  775. X  {                    'K',0,    PM_KNIGHT, {
  776. X    {"Gallant",    0},
  777. X    {"Esquire",    0},
  778. X    {"Bachelor",    0},
  779. X    {"Sergeant",    0},
  780. X    {"Knight",    0},
  781. X    {"Banneret",    0},
  782. X    {"Chevalier",    0},
  783. X    {"Seignieur",    0},
  784. X    {"Paladin",    0}
  785. X  } },
  786. X  {                    'P',0,    PM_PRIEST, {
  787. X    {"Aspirant",    0},
  788. X    {"Acolyte",    0},
  789. X    {"Adept",    0},
  790. X    {"Priest",    "Priestess"},
  791. X    {"Curate",    0},
  792. X    {"Canon",    "Canoness"},
  793. X    {"Lama",    0},
  794. X    {"Patriarch",    "Matriarch"},
  795. X    {"High Priest", "High Priestess"}
  796. X  } },
  797. X  {                    'R',0,    PM_ROGUE, {
  798. X    {"Footpad",    0},
  799. X    {"Cutpurse",    0},
  800. X    {"Rogue",    0},
  801. X    {"Pilferer",    0},
  802. X    {"Robber",    0},
  803. X    {"Burglar",    0},
  804. X    {"Filcher",    0},
  805. X    {"Magsman",    "Magswoman"},
  806. X    {"Thief",    0}
  807. X  } },
  808. X  {                    'S',0,    PM_SAMURAI, {
  809. X    {"Hatamoto",    0},  /* Banner Knight */
  810. X    {"Ronin",    0},  /* no allegiance */
  811. X    {"Ninja",    0},  /* secret society */
  812. X    {"Joshu",    0},  /* heads a castle */
  813. X    {"Ryoshu",    0},  /* has a territory */
  814. X    {"Kokushu",    0},  /* heads a province */
  815. X    {"Daimyo",    0},  /* a samurai lord */
  816. X    {"Kuge",    0},  /* Noble of the Court */
  817. X    {"Shogun",    0}   /* supreme commander, warlord */
  818. X  } },
  819. X#ifdef TOURIST
  820. X  {                    'T',0,    PM_TOURIST, {
  821. X    {"Rambler",    0},
  822. X    {"Sightseer",    0},
  823. X    {"Excursionist",0},
  824. X    {"Peregrinator","Peregrinatrix"},
  825. X    {"Traveler",    0},
  826. X    {"Journeyer",    0},
  827. X    {"Voyager",    0},
  828. X    {"Explorer",    0},
  829. X    {"Adventurer",    0}
  830. X  } },
  831. X#endif
  832. X  {                    'V',0,    PM_VALKYRIE, {
  833. X    {"Stripling",    0},
  834. X    {"Skirmisher",    0},
  835. X    {"Fighter",    0},
  836. X    {"Man-at-arms", "Woman-at-arms"},
  837. X    {"Warrior",    0},
  838. X    {"Swashbuckler",0},
  839. X    {"Hero",    "Heroine"},
  840. X    {"Champion",    0},
  841. X    {"Lord",    "Lady"}
  842. X  } },
  843. X  {                    'W',0,    PM_WIZARD, {
  844. X    {"Evoker",    0},
  845. X    {"Conjurer",    0},
  846. X    {"Thaumaturge", 0},
  847. X    {"Magician",    0},
  848. X    {"Enchanter",    "Enchantress"},
  849. X    {"Sorcerer",    "Sorceress"},
  850. X    {"Necromancer", 0},
  851. X    {"Wizard",    0},
  852. X    {"Mage",    0}
  853. X  } },
  854. X};
  855. X
  856. XSTATIC_OVL const struct rank_title *
  857. Xrank_array(pc)
  858. Xchar pc;
  859. X{
  860. X    register int i;
  861. X
  862. X    for (i = 0; i < SIZE(all_classes); i++)
  863. X        if (all_classes[i].plclass == pc) return all_classes[i].titles;
  864. X    return 0;
  865. X}
  866. X
  867. X/* convert experience level (1..30) to rank index (0..8) */
  868. Xint xlev_to_rank(xlev)
  869. Xint xlev;
  870. X{
  871. X    return (xlev <= 2) ? 0 : (xlev <= 30) ? ((xlev + 2) / 4) : 8;
  872. X}
  873. X
  874. X#if 0    /* not currently needed */
  875. X/* convert rank index (0..8) to experience level (1..30) */
  876. Xint rank_to_xlev(rank)
  877. Xint rank;
  878. X{
  879. X    return (rank <= 0) ? 1 : (rank <= 8) ? ((rank * 4) - 2) : 30;
  880. X}
  881. X#endif
  882. X
  883. Xconst char *
  884. Xrank_of(lev, pc, female)
  885. Xregister unsigned lev;
  886. Xchar pc;
  887. Xboolean female;
  888. X{
  889. X    register int idx = xlev_to_rank((int)lev);
  890. X    const struct rank_title *ranks = rank_array(pc);
  891. X
  892. X    if (ranks)
  893. X        return( female && ranks[idx].f ? ranks[idx].f : ranks[idx].m );
  894. X    return(pl_character);
  895. X}
  896. X
  897. XSTATIC_OVL const char *
  898. Xrank()
  899. X{
  900. X    return(rank_of(u.ulevel, pl_character[0], flags.female));
  901. X}
  902. X
  903. Xint
  904. Xtitle_to_mon(str, rank_indx, title_length)
  905. Xconst char *str;
  906. Xint *rank_indx, *title_length;
  907. X{
  908. X    register int i, j;
  909. X    register const struct rank_title *ttl;
  910. X
  911. X    for (i = 0; i < SIZE(all_classes); i++)
  912. X        for (j = 0; j < 9; j++) {
  913. X        ttl = &all_classes[i].titles[j];
  914. X        if (!strncmpi(ttl->m, str, strlen(ttl->m))) {
  915. X            if (rank_indx) *rank_indx = j;
  916. X            if (title_length) *title_length = strlen(ttl->m);
  917. X            return all_classes[i].mplayer_class;
  918. X        } else if (ttl->f && !strncmpi(ttl->f, str, strlen(ttl->f))) {
  919. X            if (rank_indx) *rank_indx = j;
  920. X            if (title_length) *title_length = strlen(ttl->f);
  921. X            return all_classes[i].plclass == 'C' ? PM_CAVEWOMAN :
  922. X               all_classes[i].plclass == 'P' ? PM_PRIESTESS :
  923. X               all_classes[i].mplayer_class;
  924. X        }
  925. X        }
  926. X    return -1;    /* not found */
  927. X}
  928. X
  929. X#endif /* OVL1 */
  930. X#ifdef OVLB
  931. X
  932. Xvoid
  933. Xmax_rank_sz()
  934. X{
  935. X    register int i, r, maxr = 0;
  936. X    const struct rank_title *ranks = rank_array(pl_character[0]);
  937. X
  938. X    if (ranks) {
  939. X        for (i = 0; i < 9; i++) {
  940. X        if ((r = strlen(ranks[i].m)) > maxr) maxr = r;
  941. X        if (ranks[i].f)
  942. X            if ((r = strlen(ranks[i].f)) > maxr) maxr = r;
  943. X        }
  944. X        mrank_sz = maxr;
  945. X    }
  946. X    else mrank_sz = strlen(pl_character);
  947. X}
  948. X
  949. X#endif /* OVLB */
  950. X#ifdef OVL0
  951. X
  952. Xstatic void
  953. Xbot1()
  954. X{
  955. X    char newbot1[MAXCO];
  956. X    register char *nb;
  957. X    register int i,j;
  958. X
  959. X    Strcpy(newbot1, plname);
  960. X    if('a' <= newbot1[0] && newbot1[0] <= 'z') newbot1[0] += 'A'-'a';
  961. X    newbot1[10] = 0;
  962. X    Sprintf(nb = eos(newbot1)," the ");
  963. X#ifdef POLYSELF
  964. X    if (u.mtimedone) {
  965. X        char mbot[BUFSZ];
  966. X        int k = 0;
  967. X
  968. X        Strcpy(mbot, mons[u.umonnum].mname);
  969. X        while(mbot[k] != 0) {
  970. X            if ((k == 0 || (k > 0 && mbot[k-1] == ' ')) &&
  971. X                    'a' <= mbot[k] && mbot[k] <= 'z')
  972. X            mbot[k] += 'A' - 'a';
  973. X            k++;
  974. X        }
  975. X        Sprintf(nb = eos(nb), mbot);
  976. X    } else
  977. X        Sprintf(nb = eos(nb), rank());
  978. X#else
  979. X    Sprintf(nb = eos(nb), rank());
  980. X#endif
  981. X    Sprintf(nb = eos(nb),"  ");
  982. X    i = mrank_sz + 15;
  983. X    j = (nb + 2) - newbot1; /* aka strlen(newbot1) but less computation */
  984. X    if((i - j) > 0)
  985. X        Sprintf(nb = eos(nb),"%*s", i-j, " ");    /* pad with spaces */
  986. X    if (ACURR(A_STR) > 18) {
  987. X        if (ACURR(A_STR) > 118)
  988. X            Sprintf(nb = eos(nb),"St:%2d ",ACURR(A_STR)-100);
  989. X        else if (ACURR(A_STR) < 118)
  990. X            Sprintf(nb = eos(nb), "St:18/%02d ",ACURR(A_STR)-18);
  991. X        else
  992. X            Sprintf(nb = eos(nb),"St:18/** ");
  993. X    } else
  994. X        Sprintf(nb = eos(nb), "St:%-1d ",ACURR(A_STR));
  995. X    Sprintf(nb = eos(nb),
  996. X        "Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
  997. X        ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS), ACURR(A_CHA));
  998. X    Sprintf(nb = eos(nb), (u.ualign.type == A_CHAOTIC) ? "  Chaotic" :
  999. X            (u.ualign.type == A_NEUTRAL) ? "  Neutral" : "  Lawful");
  1000. X#ifdef SCORE_ON_BOTL
  1001. X    if (flags.showscore) {
  1002. X        int deepest = deepest_lev_reached(FALSE);
  1003. X        long ugold = u.ugold + hidden_gold();
  1004. X
  1005. X        if ((ugold -= u.ugold0) < 0L) ugold = 0L;
  1006. X        Sprintf(nb = eos(nb), " S:%ld",
  1007. X            ugold + u.urexp + (long)(50 * (deepest - 1))
  1008. X              + (long)(deepest > 30 ? 10000 :
  1009. X                   deepest > 20 ? 1000*(deepest - 20) : 0));
  1010. X    }
  1011. X#endif
  1012. X    curs(WIN_STATUS, 1, 0);
  1013. X    putstr(WIN_STATUS, 0, newbot1);
  1014. X}
  1015. X
  1016. Xstatic void
  1017. Xbot2()
  1018. X{
  1019. X    char  newbot2[MAXCO];
  1020. X    register char *nb;
  1021. X    int hp, hpmax;
  1022. X    int cap = near_capacity();
  1023. X
  1024. X#ifdef POLYSELF
  1025. X    hp = u.mtimedone ? u.mh : u.uhp;
  1026. X    hpmax = u.mtimedone ? u.mhmax : u.uhpmax;
  1027. X#else
  1028. X    hp = u.uhp;
  1029. X    hpmax = u.uhpmax;
  1030. X#endif
  1031. X    if(hp < 0) hp = 0;
  1032. X/* TODO:    Add in dungeon name */
  1033. X#ifdef MULDGN
  1034. X    if(Is_knox(&u.uz)) Sprintf(newbot2, "%s ", dungeons[u.uz.dnum].dname);
  1035. X    else
  1036. X    if(In_quest(&u.uz)) Sprintf(newbot2, "Home %d ", dunlev(&u.uz));
  1037. X    else
  1038. X#endif
  1039. X    if(In_endgame(&u.uz))
  1040. X        Sprintf(newbot2,
  1041. X            Is_astralevel(&u.uz) ? "Astral Plane " : "End Game ");
  1042. X    else
  1043. X        Sprintf(newbot2, "Dlvl:%-2d ", depth(&u.uz));
  1044. X    Sprintf(nb = eos(newbot2),
  1045. X        "%c:%-2ld HP:%d(%d) Pw:%d(%d) AC:%-2d", oc_syms[GOLD_CLASS],
  1046. X        u.ugold, hp, hpmax, u.uen, u.uenmax, u.uac);
  1047. X#ifdef POLYSELF
  1048. X    if (u.mtimedone)
  1049. X        Sprintf(nb = eos(nb), " HD:%d", mons[u.umonnum].mlevel);
  1050. X    else
  1051. X#endif
  1052. X#ifdef EXP_ON_BOTL
  1053. X    if(flags.showexp)
  1054. X        Sprintf(nb = eos(nb), " Xp:%u/%-1ld", u.ulevel,u.uexp);
  1055. X    else
  1056. X#endif
  1057. X    Sprintf(nb = eos(nb), " Exp:%u", u.ulevel);
  1058. X    if(flags.time)
  1059. X        Sprintf(nb = eos(nb), " T:%ld", moves);
  1060. X    if(strcmp(hu_stat[u.uhs], "        ")) {
  1061. X        Sprintf(nb = eos(nb), " ");
  1062. X        Strcat(newbot2, hu_stat[u.uhs]);
  1063. X    }
  1064. X    if(Confusion)       Sprintf(nb = eos(nb), " Conf");
  1065. X    if(Sick)       Sprintf(nb = eos(nb), " Sick");
  1066. X    if(Blind)       Sprintf(nb = eos(nb), " Blind");
  1067. X    if(Stunned)       Sprintf(nb = eos(nb), " Stun");
  1068. X    if(Hallucination)  Sprintf(nb = eos(nb), " Hallu");
  1069. X    if(cap > UNENCUMBERED)
  1070. X        Sprintf(nb = eos(nb), " %s", enc_stat[cap]);
  1071. X    curs(WIN_STATUS, 1, 1);
  1072. X    putstr(WIN_STATUS, 0, newbot2);
  1073. X}
  1074. X
  1075. Xvoid
  1076. Xbot()
  1077. X{
  1078. X    bot1();
  1079. X    bot2();
  1080. X    flags.botl = flags.botlx = 0;
  1081. X}
  1082. X
  1083. X#endif /* OVL0 */
  1084. X
  1085. X/*botl.c*/
  1086. END_OF_FILE
  1087. if test 9881 -ne `wc -c <'src/botl.c'`; then
  1088.     echo shar: \"'src/botl.c'\" unpacked with wrong size!
  1089. fi
  1090. # end of 'src/botl.c'
  1091. fi
  1092. if test -f 'sys/amiga/amidos.c' -a "${1}" != "-c" ; then 
  1093.   echo shar: Will not clobber existing file \"'sys/amiga/amidos.c'\"
  1094. else
  1095. echo shar: Extracting \"'sys/amiga/amidos.c'\" \(9824 characters\)
  1096. sed "s/^X//" >'sys/amiga/amidos.c' <<'END_OF_FILE'
  1097. X/*    SCCS Id: @(#)amidos.c     3.1    93/01/08
  1098. X/* Copyright (c) Olaf Seibert, Nijmegen, The Netherlands, 1988,1990.    */
  1099. X/* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991, 1992, 1993.  */
  1100. X/* NetHack may be freely redistributed.  See license for details.    */
  1101. X
  1102. X/*
  1103. X * An assortment of imitations of cheap plastic MSDOS and Unix functions.
  1104. X */
  1105. X
  1106. X#include "hack.h"
  1107. X#include "winami.h"
  1108. X
  1109. X/* Defined in config.h, let's undefine it here (static function below) */
  1110. X#undef strcmpi
  1111. X
  1112. X#include <libraries/dos.h>
  1113. X#include <exec/execbase.h>
  1114. X#include <intuition/intuition.h>
  1115. X
  1116. X#undef COUNT
  1117. X#ifdef LATTICE
  1118. X# include <proto/exec.h>
  1119. X# include <proto/dos.h>
  1120. X#endif
  1121. X
  1122. X#ifdef AZTEC_50
  1123. X# include <functions.h>
  1124. X# undef strcmpi
  1125. X#endif
  1126. X
  1127. X/* Prototypes */
  1128. X#include "Amiga:winami.p"
  1129. X#include "Amiga:amiwind.p"
  1130. X#include "Amiga:amidos.p"
  1131. X
  1132. Xextern char Initialized;
  1133. X
  1134. X#ifndef __SASC
  1135. Xint Enable_Abort = 0;   /* for stdio package */
  1136. X#endif
  1137. X
  1138. X/* Initial path, so we can find NetHack.cnf */
  1139. Xchar PATH[PATHLEN] = "Ram:;df0:;NetHack:";
  1140. X
  1141. Xstatic boolean record_exists(void);
  1142. X
  1143. Xvoid
  1144. Xflushout()
  1145. X{
  1146. X    (void) fflush(stdout);
  1147. X}
  1148. X
  1149. X#ifndef getuid
  1150. Xgetuid()
  1151. X{
  1152. X    return 1;
  1153. X}
  1154. X#endif
  1155. X
  1156. X#ifndef getlogin
  1157. Xchar *
  1158. Xgetlogin()
  1159. X{
  1160. X    return ((char *) NULL);
  1161. X}
  1162. X#endif
  1163. X
  1164. X#ifndef AZTEC_50
  1165. Xint
  1166. Xabs(x)
  1167. Xint x;
  1168. X{
  1169. X    return x < 0? -x: x;
  1170. X}
  1171. X#endif
  1172. X
  1173. X#ifdef SHELL
  1174. Xint
  1175. Xdosh()
  1176. X{
  1177. X    int i;
  1178. X    char buf[ 500 ];
  1179. X    extern struct ExecBase *SysBase;
  1180. X
  1181. X    /* Only under 2.0 and later ROMs do we have System() */
  1182. X    if( SysBase->LibNode.lib_Version >= 37 )
  1183. X    {
  1184. X    getlin("Enter CLI Command...", buf );
  1185. X    i = System( buf, NULL );
  1186. X    }
  1187. X    else
  1188. X    {
  1189. X    i = 0;
  1190. X    pline("No mysterious force prevented you from using multitasking.");
  1191. X    }
  1192. X    return i;
  1193. X}
  1194. X#endif /* SHELL */
  1195. X
  1196. X#ifdef MFLOPPY
  1197. X# include <ctype.h>
  1198. X
  1199. X# define Sprintf (void) sprintf
  1200. X
  1201. X#define EXTENSION   72
  1202. X
  1203. X/*
  1204. X *  This routine uses an approximation of the free bytes on a disk.
  1205. X *  How large a file you can actually write depends on the number of
  1206. X *  extension blocks you need for it.
  1207. X *  In each extenstion block there are maximum 72 pointers to blocks,
  1208. X *  so every 73 disk blocks have only 72 available for data.
  1209. X *  The (necessary) file header is also good for 72 data block pointers.
  1210. X */
  1211. X/* TODO: update this for FFS */
  1212. Xlong
  1213. Xfreediskspace(path)
  1214. Xchar *path;
  1215. X{
  1216. X    register long freeBytes = 0;
  1217. X    register struct InfoData *infoData; /* Remember... longword aligned */
  1218. X    char fileName[32];
  1219. X
  1220. X    /*
  1221. X     *  Find a valid path on the device of which we want the free space.
  1222. X     *  If there is a colon in the name, it is an absolute path
  1223. X     *  and all up to the colon is everything we need.
  1224. X     *  Remember slashes in a volume name are allowed!
  1225. X     *  If there is no colon, it is relative to the current directory,
  1226. X     *  so must be on the current device, so "" is enough...
  1227. X     */
  1228. X    {
  1229. X    register char *colon;
  1230. X
  1231. X    strncpy(fileName, path, sizeof(fileName) - 1);
  1232. X    fileName[31] = 0;
  1233. X    if (colon = index(fileName, ':'))
  1234. X    colon[1] = '\0';
  1235. X    else
  1236. X    fileName[0] = '\0';
  1237. X    }
  1238. X    {
  1239. X    BPTR fileLock;
  1240. X    infoData = (struct InfoData *) alloc(sizeof(struct InfoData));
  1241. X    if (fileLock = Lock(fileName, SHARED_LOCK)) {
  1242. X    if (Info(fileLock, infoData)) {
  1243. X        /* We got a kind of DOS volume, since we can Lock it. */
  1244. X        /* Calculate number of blocks available for new file */
  1245. X        /* Kludge for the ever-full VOID: (oops RAM:) device */
  1246. X        if (infoData->id_UnitNumber == -1 &&
  1247. X          infoData->id_NumBlocks == infoData->id_NumBlocksUsed) {
  1248. X        freeBytes = AvailMem(0L) - 64 * 1024L;
  1249. X            /* Just a stupid guess at the */
  1250. X            /* Ram-Handler overhead per block: */
  1251. X        freeBytes -= freeBytes/16;
  1252. X        } else {
  1253. X        /* Normal kind of DOS file system device/volume */
  1254. X        freeBytes = infoData->id_NumBlocks - infoData->id_NumBlocksUsed;
  1255. X        freeBytes -= (freeBytes + EXTENSION) / (EXTENSION + 1);
  1256. X        freeBytes *= infoData->id_BytesPerBlock;
  1257. X        }
  1258. X        if (freeBytes < 0)
  1259. X        freeBytes = 0;
  1260. X    }
  1261. X    UnLock(fileLock);
  1262. X    }
  1263. X    free(infoData);
  1264. X    return freeBytes;
  1265. X    }
  1266. X}
  1267. X
  1268. X
  1269. Xlong
  1270. Xfilesize(file)
  1271. Xchar *file;
  1272. X{
  1273. X    register BPTR fileLock;
  1274. X    register struct FileInfoBlock *fileInfoBlock;
  1275. X    register long size = 0;
  1276. X
  1277. X    fileInfoBlock = (struct FileInfoBlock *)alloc(sizeof(struct FileInfoBlock));
  1278. X    if (fileLock = Lock(file, SHARED_LOCK)) {
  1279. X    if (Examine(fileLock, fileInfoBlock)) {
  1280. X        size = fileInfoBlock->fib_Size;
  1281. X    }
  1282. X    UnLock(fileLock);
  1283. X    }
  1284. X    free(fileInfoBlock);
  1285. X    return size;
  1286. X}
  1287. X
  1288. Xvoid
  1289. Xeraseall(path, files)
  1290. Xconst char *path, *files;
  1291. X{
  1292. X    char buf[FILENAME];
  1293. X    short i;
  1294. X    BPTR fileLock, dirLock, dirLock2;
  1295. X    struct FileInfoBlock *fibp;
  1296. X    int chklen;
  1297. X#ifdef BETA
  1298. X    if(files != alllevels)panic("eraseall");
  1299. X#endif
  1300. X    chklen=(int)index(files,'*')-(int)files;
  1301. X
  1302. X    if (dirLock = Lock(path ,SHARED_LOCK)) {
  1303. X    dirLock2=DupLock(dirLock);
  1304. X    dirLock2= CurrentDir(dirLock2);
  1305. X    fibp=AllocMem(sizeof(struct FileInfoBlock),0);
  1306. X    if(fibp){
  1307. X        if(Examine(dirLock,fibp)){
  1308. X        while(ExNext(dirLock,fibp)){
  1309. X            if(!strncmp(fibp->fib_FileName,files,chklen)){
  1310. X            DeleteFile(fibp->fib_FileName);
  1311. X            }
  1312. X        }
  1313. X        }
  1314. X        FreeMem(fibp,sizeof(struct FileInfoBlock));
  1315. X    }
  1316. X    UnLock(dirLock);
  1317. X    UnLock(CurrentDir(dirLock2));
  1318. X    }
  1319. X}
  1320. X
  1321. X/* This size makes that most files can be copied with two Read()/Write()s */
  1322. X
  1323. X#define COPYSIZE    4096
  1324. X
  1325. Xchar *CopyFile(from, to)
  1326. Xconst char *from, *to;
  1327. X{
  1328. X    register BPTR fromFile, toFile;
  1329. X    register char *buffer;
  1330. X    register long size;
  1331. X    char *error = NULL;
  1332. X
  1333. X    buffer = (char *) alloc(COPYSIZE);
  1334. X    if (fromFile = Open(from, MODE_OLDFILE)) {
  1335. X    if (toFile = Open(to, MODE_NEWFILE)) {
  1336. X        while (size = Read(fromFile, buffer, (long)COPYSIZE)) {
  1337. X        if (size == -1){
  1338. X            error = "Read error";
  1339. X            break;
  1340. X        }
  1341. X        if (size != Write(toFile, buffer, size)) {
  1342. X            error = "Write error";
  1343. X            break;
  1344. X        }
  1345. X        }
  1346. X        Close(toFile);
  1347. X    } else
  1348. X        error = "Cannot open destination";
  1349. X    Close(fromFile);
  1350. X    } else
  1351. X    error = "Cannot open source (this should not occur)";
  1352. X    free(buffer);
  1353. X    return error;
  1354. X}
  1355. X
  1356. X
  1357. X/* this should be replaced */
  1358. XsaveDiskPrompt(start)
  1359. X{
  1360. X    extern int saveprompt;
  1361. X    char buf[BUFSIZ], *bp;
  1362. X    BPTR fileLock;
  1363. X
  1364. X    if (saveprompt) {
  1365. X        /* Don't prompt if you can find the save file */
  1366. X    if (fileLock = Lock(SAVEF, SHARED_LOCK)) {
  1367. X        UnLock(fileLock);
  1368. X        clear_nhwindow( WIN_BASE );
  1369. X        return 1;
  1370. X    }
  1371. X    pline( "If save file is on a SAVE disk, put that disk in now." );
  1372. X    if( strlen( SAVEF ) > QBUFSZ - 25 - 22 )
  1373. X        panic( "not enough buffer space for prompt" );
  1374. X    getlind("File name ?", buf, SAVEF);
  1375. X    clear_nhwindow( WIN_BASE );
  1376. X    if (!start && *buf == '\033')
  1377. X        return 0;
  1378. X
  1379. X    /* Strip any whitespace. Also, if nothing was entered except
  1380. X     * whitespace, do not change the value of SAVEF.
  1381. X     */
  1382. X    for (bp = buf; *bp; bp++) {
  1383. X        if (!isspace(*bp)) {
  1384. X        strncpy(SAVEF, bp, PATHLEN);
  1385. X        break;
  1386. X        }
  1387. X    }
  1388. X    }
  1389. X    return 1;
  1390. X}
  1391. X
  1392. X/* Return 1 if the record file was found */
  1393. Xstatic boolean
  1394. Xrecord_exists()
  1395. X{
  1396. X    FILE *file;
  1397. X
  1398. X    if (file = fopenp(RECORD, "r")) {
  1399. X    fclose(file);
  1400. X    return TRUE;
  1401. X    }
  1402. X    return FALSE;
  1403. X}
  1404. X
  1405. X#ifdef MFLOPPY
  1406. X/*
  1407. X * Under MSDOS: Prompt for game disk, then check for record file.
  1408. X * For Amiga: do nothing, but called from restore.c
  1409. X */
  1410. Xvoid
  1411. XgameDiskPrompt(){}
  1412. X#endif
  1413. X
  1414. X/*
  1415. X * Add a slash to any name not ending in / or :.  There must
  1416. X * be room for the /.
  1417. X */
  1418. Xvoid
  1419. Xappend_slash(name)
  1420. Xchar *name;
  1421. X{
  1422. X    char *ptr;
  1423. X
  1424. X    if (!*name)return;
  1425. X
  1426. X    ptr = eos(name) - 1;
  1427. X    if (*ptr != '/' && *ptr != ':') {
  1428. X    *++ptr = '/';
  1429. X    *++ptr = '\0';
  1430. X    }
  1431. X}
  1432. X
  1433. X
  1434. Xvoid
  1435. Xgetreturn(str)
  1436. Xconst char *str;
  1437. X{
  1438. X    int ch;
  1439. X
  1440. X    raw_printf("Hit <RETURN> %s.", str);
  1441. X    while ((ch = nhgetch()) != '\n' && ch != '\r' )
  1442. X    continue;
  1443. X}
  1444. X
  1445. X/* Follow the PATH, trying to fopen the file.
  1446. X */
  1447. X#define PATHSEP    ';'
  1448. X
  1449. XFILE *
  1450. Xfopenp(name, mode)
  1451. Xregister const char *name, *mode;
  1452. X{
  1453. X    register char *bp, *pp, lastch;
  1454. X    register FILE *fp;
  1455. X    register BPTR theLock;
  1456. X    char buf[BUFSIZ];
  1457. X
  1458. X    /* Try the default directory first.  Then look along PATH.
  1459. X     */
  1460. X    strcpy(buf, name);
  1461. X    if (theLock = Lock(buf, SHARED_LOCK)) {
  1462. X    UnLock(theLock);
  1463. X    if (fp = fopen(buf, mode))
  1464. X        return fp;
  1465. X    }
  1466. X    pp = PATH;
  1467. X    while (pp && *pp) {
  1468. X    bp = buf;
  1469. X    while (*pp && *pp != PATHSEP){
  1470. X        if( bp > buf + BUFSIZ - 1 ) return( NULL );
  1471. X        lastch = *bp++ = *pp++;
  1472. X    }
  1473. X    if (lastch != ':' && lastch != '/' && bp != buf)
  1474. X        *bp++ = '/';
  1475. X    strcpy(bp, name);
  1476. X    if (theLock = Lock(buf, SHARED_LOCK)) {
  1477. X        UnLock(theLock);
  1478. X        if (fp = fopen(buf, mode)) return fp;
  1479. X    }
  1480. X    if (*pp)
  1481. X        pp++;
  1482. X    }
  1483. X    return NULL;
  1484. X}
  1485. X#endif /* MFLOPPY */
  1486. X
  1487. X#ifdef CHDIR
  1488. X
  1489. X/*
  1490. X *  A not general-purpose directory changing routine.
  1491. X *  Assumes you want to return to the original directory eventually,
  1492. X *  by chdir()ing to orgdir.
  1493. X *  Assumes -1 is not a valid lock, since 0 is valid.
  1494. X */
  1495. X
  1496. X#define NO_LOCK     ((BPTR) -1)
  1497. X
  1498. Xchar orgdir[1];
  1499. Xstatic BPTR OrgDirLock = NO_LOCK;
  1500. X
  1501. Xchdir(dir)
  1502. Xchar *dir;
  1503. X{
  1504. X    if (dir == orgdir) {
  1505. X        /* We want to go back to where we came from. */
  1506. X    if (OrgDirLock != NO_LOCK) {
  1507. X        UnLock(CurrentDir(OrgDirLock));
  1508. X        OrgDirLock = NO_LOCK;
  1509. X    }
  1510. X    } else {
  1511. X        /*
  1512. X         * Go to some new place. If still at the original
  1513. X         * directory, save the FileLock.
  1514. X         */
  1515. X    BPTR newDir;
  1516. X
  1517. X    if (newDir = Lock(dir, SHARED_LOCK)) {
  1518. X        if (OrgDirLock == NO_LOCK) {
  1519. X        OrgDirLock = CurrentDir(newDir);
  1520. X        } else {
  1521. X        UnLock(CurrentDir(newDir));
  1522. X        }
  1523. X    } else {
  1524. X        return -1;  /* Failed */
  1525. X    }
  1526. X    }
  1527. X    /* CurrentDir always succeeds if you have a lock */
  1528. X    return 0;
  1529. X}
  1530. X
  1531. X#endif /* CHDIR */
  1532. X
  1533. X/* Chdir back to original directory
  1534. X */
  1535. X#undef exit
  1536. Xvoid
  1537. Xmsexit(code)
  1538. X{
  1539. X#ifdef CHDIR
  1540. X    extern char orgdir[];
  1541. X#endif
  1542. X
  1543. X#ifdef CHDIR
  1544. X    chdir(orgdir);      /* chdir, not chdirx */
  1545. X#endif
  1546. X
  1547. X    CleanUp();
  1548. X    exit(code);
  1549. X}
  1550. X
  1551. Xint
  1552. Xuptodate(fd)
  1553. X{
  1554. X    return(1);
  1555. X}
  1556. X
  1557. Xvoid
  1558. Xregularize(s)    /* normalize file name - we don't like :'s or /'s */
  1559. Xregister char *s;
  1560. X{
  1561. X    register char *lp;
  1562. X
  1563. X    while((lp = index(s, ':')) || (lp = index(s, '/')))
  1564. X    *lp = '_';
  1565. X}
  1566. END_OF_FILE
  1567. if test 9824 -ne `wc -c <'sys/amiga/amidos.c'`; then
  1568.     echo shar: \"'sys/amiga/amidos.c'\" unpacked with wrong size!
  1569. fi
  1570. # end of 'sys/amiga/amidos.c'
  1571. fi
  1572. if test -f 'sys/vms/vmsmain.c' -a "${1}" != "-c" ; then 
  1573.   echo shar: Will not clobber existing file \"'sys/vms/vmsmain.c'\"
  1574. else
  1575. echo shar: Extracting \"'sys/vms/vmsmain.c'\" \(9878 characters\)
  1576. sed "s/^X//" >'sys/vms/vmsmain.c' <<'END_OF_FILE'
  1577. X/*    SCCS Id: @(#)vmsmain.c    3.1    93/01/24    */
  1578. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1579. X/* NetHack may be freely redistributed.  See license for details. */
  1580. X/* main.c - VMS NetHack */
  1581. X
  1582. X#include "hack.h"
  1583. X
  1584. X#include <signal.h>
  1585. X
  1586. Xstatic void NDECL(whoami);
  1587. Xstatic void FDECL(process_options, (int, char **));
  1588. Xstatic void NDECL(byebye);
  1589. X#ifndef SAVE_ON_FATAL_ERROR
  1590. X# ifndef __DECC
  1591. Xextern void FDECL(VAXC$ESTABLISH, (int (*)(genericptr_t,genericptr_t)));
  1592. X# endif
  1593. Xstatic int FDECL(vms_handler, (genericptr_t,genericptr_t));
  1594. X#include <ssdef.h>    /* system service status codes */
  1595. X#endif
  1596. X
  1597. Xint
  1598. Xmain(argc,argv)
  1599. Xint argc;
  1600. Xchar *argv[];
  1601. X{
  1602. X    register int fd;
  1603. X#ifdef CHDIR
  1604. X    register char *dir;
  1605. X#endif
  1606. X
  1607. X#ifdef SECURE    /* this should be the very first code executed */
  1608. X    privoff();
  1609. X    fflush((FILE *)0);    /* force stdio to init itself */
  1610. X    privon();
  1611. X#endif
  1612. X
  1613. X    atexit(byebye);
  1614. X    hname = argv[0];
  1615. X    gethdate(hname);        /* find executable's creation date */
  1616. X    hname = basename(hname);    /* name used in 'usage' type messages */
  1617. X    hackpid = getpid();
  1618. X    (void) umask(0);
  1619. X
  1620. X    choose_windows(DEFAULT_WINDOW_SYS);
  1621. X
  1622. X#ifdef CHDIR            /* otherwise no chdir() */
  1623. X    /*
  1624. X     * See if we must change directory to the playground.
  1625. X     * (Perhaps hack is installed with privs and playground is
  1626. X     *  inaccessible for the player.)
  1627. X     * The logical name HACKDIR is overridden by a
  1628. X     *  -d command line option (must be the first option given)
  1629. X     */
  1630. X    dir = getenv("NETHACKDIR");
  1631. X    if (!dir) dir = getenv("HACKDIR");
  1632. X#endif
  1633. X    if(argc > 1) {
  1634. X#ifdef CHDIR
  1635. X        if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
  1636. X        /* avoid matching "-dec" for DECgraphics; since the man page
  1637. X         * says -d directory, hope nobody's using -desomething_else
  1638. X         */
  1639. X        argc--;
  1640. X        argv++;
  1641. X        dir = argv[0]+2;
  1642. X        if(*dir == '=' || *dir == ':') dir++;
  1643. X        if(!*dir && argc > 1) {
  1644. X            argc--;
  1645. X            argv++;
  1646. X            dir = argv[0];
  1647. X        }
  1648. X        if(!*dir)
  1649. X            error("Flag -d must be followed by a directory name.");
  1650. X        } else
  1651. X#endif /* CHDIR */
  1652. X
  1653. X    /*
  1654. X     * Now we know the directory containing 'record' and
  1655. X     * may do a prscore().
  1656. X     */
  1657. X        if (!strncmp(argv[1], "-s", 2)) {
  1658. X#ifdef CHDIR
  1659. X        chdirx(dir, FALSE);
  1660. X#endif
  1661. X        prscore(argc, argv);
  1662. X        exit(0);
  1663. X        }
  1664. X    }
  1665. X
  1666. X#ifdef CHDIR
  1667. X    /* move to the playground directory; 'termcap' might be found there */
  1668. X    chdirx(dir, TRUE);
  1669. X#endif
  1670. X
  1671. X    initoptions();
  1672. X    init_nhwindows();
  1673. X    whoami();
  1674. X
  1675. X    /*
  1676. X     * It seems you really want to play.
  1677. X     */
  1678. X    setrandom();
  1679. X    u.uhp = 1;    /* prevent RIP on early quits */
  1680. X#ifndef SAVE_ON_FATAL_ERROR
  1681. X    /* used to clear hangup stuff while still giving standard traceback */
  1682. X    VAXC$ESTABLISH(vms_handler);
  1683. X#endif
  1684. X    (void) signal(SIGHUP, (SIG_RET_TYPE) hangup);
  1685. X
  1686. X    process_options(argc, argv);    /* command line options */
  1687. X
  1688. X#ifdef WIZARD
  1689. X    if (wizard)
  1690. X        Strcpy(plname, "wizard");
  1691. X    else
  1692. X#endif
  1693. X    if(!*plname || !strncmp(plname, "games", 4))
  1694. X        askname();
  1695. X    plnamesuffix();        /* strip suffix from name; calls askname() */
  1696. X                /* again if suffix was whole name */
  1697. X                /* accepts any suffix */
  1698. X#ifdef WIZARD
  1699. X    if(!wizard) {
  1700. X#endif
  1701. X        /*
  1702. X         * check for multiple games under the same name
  1703. X         * (if !locknum) or check max nr of players (otherwise)
  1704. X         */
  1705. X        (void) signal(SIGQUIT,SIG_IGN);
  1706. X        (void) signal(SIGINT,SIG_IGN);
  1707. X        if(!locknum)
  1708. X            Sprintf(lock, "_%u%s", (unsigned)getuid(), plname);
  1709. X        getlock();
  1710. X#ifdef WIZARD
  1711. X    } else {
  1712. X        Sprintf(lock, "_%u%s", (unsigned)getuid(), plname);
  1713. X        getlock();
  1714. X    }
  1715. X#endif /* WIZARD */
  1716. X
  1717. X    /*
  1718. X     * Initialisation of the boundaries of the mazes
  1719. X     * Both boundaries have to be even.
  1720. X     */
  1721. X
  1722. X    x_maze_max = COLNO-1;
  1723. X    if (x_maze_max % 2)
  1724. X        x_maze_max--;
  1725. X    y_maze_max = ROWNO-1;
  1726. X    if (y_maze_max % 2)
  1727. X        y_maze_max--;
  1728. X
  1729. X    /*
  1730. X     *  Initialize the vision system.  This must be before mklev() on a
  1731. X     *  new game or before a level restore on a saved game.
  1732. X     */
  1733. X    vision_init();
  1734. X
  1735. X    display_gamewindows();
  1736. X
  1737. X    set_savefile_name();
  1738. X    if((fd = open_savefile()) >= 0 &&
  1739. X       /* if not up-to-date, quietly unlink file via false condition */
  1740. X       (uptodate(fd) || delete_savefile())) {
  1741. X#ifdef WIZARD
  1742. X        /* Since wizard is actually flags.debug, restoring might
  1743. X         * overwrite it.
  1744. X         */
  1745. X        boolean remember_wiz_mode = wizard;
  1746. X#endif
  1747. X        (void) chmod(SAVEF,0);    /* disallow parallel restores */
  1748. X        (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  1749. X#ifdef NEWS
  1750. X        if(flags.news) display_file(NEWS, FALSE);
  1751. X#endif
  1752. X        pline("Restoring save file...");
  1753. X        mark_synch();    /* flush output */
  1754. X        if(!dorecover(fd))
  1755. X            goto not_recovered;
  1756. X#ifdef WIZARD
  1757. X        if(!wizard && remember_wiz_mode) wizard = TRUE;
  1758. X#endif
  1759. X        pline("Hello %s, welcome back to NetHack!", plname);
  1760. X        check_special_room(FALSE);
  1761. X#ifdef EXPLORE_MODE
  1762. X        if (discover)
  1763. X            You("are in non-scoring discovery mode.");
  1764. X#endif
  1765. X#if defined(EXPLORE_MODE) || defined(WIZARD)
  1766. X        if (discover || wizard) {
  1767. X            if (yn("Do you want to keep the save file?") == 'n')
  1768. X                (void) delete_savefile();
  1769. X            else
  1770. X                (void) chmod(SAVEF,FCMASK); /* back to readable */
  1771. X        }
  1772. X#endif
  1773. X        flags.move = 0;
  1774. X    } else {
  1775. Xnot_recovered:
  1776. X        player_selection();
  1777. X        newgame();
  1778. X        /* give welcome message before pickup messages */
  1779. X        pline("Hello %s, welcome to NetHack!", plname);
  1780. X#ifdef EXPLORE_MODE
  1781. X        if (discover)
  1782. X            You("are in non-scoring discovery mode.");
  1783. X#endif
  1784. X        flags.move = 0;
  1785. X        set_wear();
  1786. X        pickup(1);
  1787. X    }
  1788. X
  1789. X    flags.moonphase = phase_of_the_moon();
  1790. X    if(flags.moonphase == FULL_MOON) {
  1791. X        You("are lucky!  Full moon tonight.");
  1792. X        change_luck(1);
  1793. X    } else if(flags.moonphase == NEW_MOON) {
  1794. X        pline("Be careful!  New moon tonight.");
  1795. X    }
  1796. X    if ((flags.friday13 = friday_13th()) != 0) {
  1797. X        pline("Watch out!  Bad things can happen on Friday the 13th.");
  1798. X        change_luck(-1);
  1799. X    }
  1800. X
  1801. X    initrack();
  1802. X
  1803. X    moveloop();
  1804. X    return(0);
  1805. X}
  1806. X
  1807. Xstatic void
  1808. Xprocess_options(argc, argv)
  1809. Xint argc;
  1810. Xchar *argv[];
  1811. X{
  1812. X    /*
  1813. X     * Process options.
  1814. X     */
  1815. X    while(argc > 1 && argv[1][0] == '-'){
  1816. X        argv++;
  1817. X        argc--;
  1818. X        switch(argv[0][1]){
  1819. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  1820. X# ifndef EXPLORE_MODE
  1821. X        case 'X':
  1822. X        case 'x':
  1823. X# endif
  1824. X        case 'D':
  1825. X# ifdef WIZARD
  1826. X            if(!strcmpi(getenv("USER"), WIZARD_NAME)) {
  1827. X                wizard = TRUE;
  1828. X                break;
  1829. X            }
  1830. X            /* otherwise fall thru to discover */
  1831. X# endif
  1832. X# ifdef EXPLORE_MODE
  1833. X        case 'X':
  1834. X        case 'x':
  1835. X            discover = TRUE;
  1836. X# endif
  1837. X            break;
  1838. X#endif
  1839. X#ifdef NEWS
  1840. X        case 'n':
  1841. X            flags.news = FALSE;
  1842. X            break;
  1843. X#endif
  1844. X        case 'u':
  1845. X            if(argv[0][2])
  1846. X              (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
  1847. X            else if(argc > 1) {
  1848. X              argc--;
  1849. X              argv++;
  1850. X              (void) strncpy(plname, argv[0], sizeof(plname)-1);
  1851. X            } else
  1852. X                raw_print("Player name expected after -u");
  1853. X            break;
  1854. X        case 'I':
  1855. X        case 'i':
  1856. X            if (!strncmpi(argv[0]+1, "IBM", 3))
  1857. X                switch_graphics(IBM_GRAPHICS);
  1858. X            break;
  1859. X        /*  case 'D': */
  1860. X        case 'd':
  1861. X            if (!strncmpi(argv[0]+1, "DEC", 3))
  1862. X                switch_graphics(DEC_GRAPHICS);
  1863. X            break;
  1864. X        default:
  1865. X            /* allow -T for Tourist, etc. */
  1866. X            (void) strncpy(pl_character, argv[0]+1,
  1867. X                sizeof(pl_character)-1);
  1868. X
  1869. X            /* raw_printf("Unknown option: %s", *argv); */
  1870. X        }
  1871. X    }
  1872. X
  1873. X    if(argc > 1)
  1874. X        locknum = atoi(argv[1]);
  1875. X#ifdef MAX_NR_OF_PLAYERS
  1876. X    if(!locknum || locknum > MAX_NR_OF_PLAYERS)
  1877. X        locknum = MAX_NR_OF_PLAYERS;
  1878. X#endif
  1879. X}
  1880. X
  1881. X#ifdef CHDIR
  1882. Xvoid
  1883. Xchdirx(dir, wr)
  1884. Xchar *dir;
  1885. Xboolean wr;
  1886. X{
  1887. X# ifndef HACKDIR
  1888. X    static char *defdir = ".";
  1889. X# else
  1890. X    static char *defdir = HACKDIR;
  1891. X
  1892. X    if(dir == NULL)
  1893. X        dir = defdir;
  1894. X    else if (wr && !same_dir(HACKDIR, dir))
  1895. X        /* If we're playing anywhere other than HACKDIR, turn off any
  1896. X           privs we may have been installed with. */
  1897. X        privoff();
  1898. X# endif
  1899. X
  1900. X    if(dir && chdir(dir) < 0) {
  1901. X        perror(dir);
  1902. X        error("Cannot chdir to %s.", dir);
  1903. X    }
  1904. X
  1905. X    /* warn the player if we can't write the record file */
  1906. X    if (wr) check_recordfile(dir);
  1907. X
  1908. X    defdir = dir;
  1909. X}
  1910. X#endif /* CHDIR */
  1911. X
  1912. Xstatic void
  1913. Xwhoami()
  1914. X{
  1915. X    /*
  1916. X     * Who am i? Algorithm: 1. Use name as specified in NETHACKOPTIONS
  1917. X     *            2. Use lowercase of $USER  (if 1. fails)
  1918. X     * The resulting name is overridden by command line options.
  1919. X     * If everything fails, or if the resulting name is some generic
  1920. X     * account like "games" then eventually we'll ask him.
  1921. X     * Note that we trust the user here; it is possible to play under
  1922. X     * somebody else's name.
  1923. X     */
  1924. X    register char *s;
  1925. X
  1926. X    if (!*plname && (s = getenv("USER")))
  1927. X        (void) lcase(strncpy(plname, s, sizeof(plname)-1));
  1928. X}
  1929. X
  1930. Xstatic void
  1931. Xbyebye()
  1932. X{
  1933. X    /*    Different versions of both VAX C and GNU C use different return types
  1934. X    for signal functions.  Return type 'int' along with the explicit casts
  1935. X    below satisfy the most combinations of compiler vs <signal.h>.
  1936. X     */
  1937. X    int (*hup)();
  1938. X#ifdef SHELL
  1939. X    extern unsigned long dosh_pid, mail_pid;
  1940. X    extern unsigned long FDECL(SYS$DELPRC,(unsigned long *,const genericptr_t));
  1941. X
  1942. X    /* clean up any subprocess we've spawned that may still be hanging around */
  1943. X    if (dosh_pid) (void) SYS$DELPRC(&dosh_pid, 0), dosh_pid = 0;
  1944. X    if (mail_pid) (void) SYS$DELPRC(&mail_pid, 0), mail_pid = 0;
  1945. X#endif
  1946. X
  1947. X    /* SIGHUP doesn't seem to do anything on VMS, so we fudge it here... */
  1948. X    hup = (int(*)()) signal(SIGHUP, SIG_IGN);
  1949. X    if (hup != (int(*)()) SIG_DFL && hup != (int(*)()) SIG_IGN)
  1950. X    (void) (*hup)();
  1951. X
  1952. X#ifdef CHDIR
  1953. X    (void) chdir(getenv("PATH"));
  1954. X#endif
  1955. X}
  1956. X
  1957. X#ifndef SAVE_ON_FATAL_ERROR
  1958. X/* Condition handler to prevent byebye's hangup simulation
  1959. X   from saving the game after a fatal error has occurred.  */
  1960. Xstatic int            /* should be `unsigned long', but the -*/
  1961. Xvms_handler(sigargs, mechargs)    /*+ prototype in <signal.h> is screwed */
  1962. Xgenericptr_t sigargs, mechargs;    /* [0] is argc, [1..argc] are the real args */
  1963. X{
  1964. X    extern boolean hu;        /* src/save.c */
  1965. X    unsigned long condition = ((unsigned long *)sigargs)[1];
  1966. X
  1967. X    if (condition == SS$_ACCVIO        /* access violation */
  1968. X     || (condition >= SS$_ASTFLT && condition <= SS$_TBIT)
  1969. X     || (condition >= SS$_ARTRES && condition <= SS$_INHCHME)) {
  1970. X    hu = TRUE;    /* pretend that hangup has already been attempted */
  1971. X# if defined(WIZARD) && !defined(BETA)
  1972. X    if (wizard)
  1973. X# endif /*WIZARD && !BETA*/
  1974. X# if defined(WIZARD) ||  defined(BETA)
  1975. X        abort();    /* enter the debugger */
  1976. X# endif /*WIZARD || BETA*/
  1977. X    }
  1978. X    return SS$_RESIGNAL;
  1979. X}
  1980. X#endif
  1981. X
  1982. X/*vmsmain.c*/
  1983. END_OF_FILE
  1984. if test 9878 -ne `wc -c <'sys/vms/vmsmain.c'`; then
  1985.     echo shar: \"'sys/vms/vmsmain.c'\" unpacked with wrong size!
  1986. fi
  1987. # end of 'sys/vms/vmsmain.c'
  1988. fi
  1989. if test -f 'win/X11/winmenu.c' -a "${1}" != "-c" ; then 
  1990.   echo shar: Will not clobber existing file \"'win/X11/winmenu.c'\"
  1991. else
  1992. echo shar: Extracting \"'win/X11/winmenu.c'\" \(9918 characters\)
  1993. sed "s/^X//" >'win/X11/winmenu.c' <<'END_OF_FILE'
  1994. X/*    SCCS Id: @(#)winmenu.c    3.1    92/3/7
  1995. X/* Copyright (c) Dean Luick, 1992                  */
  1996. X/* NetHack may be freely redistributed.  See license for details. */
  1997. X
  1998. X/*
  1999. X * File for creating menus.
  2000. X * 
  2001. X *     + Global functions: start_menu, add_menu, end_menu, select_menu
  2002. X */
  2003. X#include <X11/Intrinsic.h>
  2004. X#include <X11/StringDefs.h>
  2005. X#include <X11/Shell.h>
  2006. X#include <X11/Xaw/List.h>
  2007. X#include <X11/Xaw/Viewport.h>
  2008. X#include <X11/Xaw/Cardinals.h>
  2009. X
  2010. X#include "hack.h"
  2011. X#include "winX.h"
  2012. X
  2013. X
  2014. Xstatic void clear_old_menu();
  2015. Xstatic char *copy_of();
  2016. X
  2017. X#define check_menu(func_name)                    \
  2018. X{                                \
  2019. X    if (!menu_info->is_menu) {                    \
  2020. X    impossible("%s:  called before start_menu", func_name);    \
  2021. X    return;                            \
  2022. X    }                                \
  2023. X}
  2024. X
  2025. Xstatic char menu_selected;    /* selected menu item */
  2026. Xstatic const char menu_translations[] =
  2027. X    "#override\n\
  2028. X     <Key>: menu_key()";
  2029. X
  2030. X/*
  2031. X * Menu callback.
  2032. X */
  2033. X/* ARGSUSED */
  2034. Xstatic void
  2035. Xmenu_select(w, client_data, call_data)
  2036. X    Widget w;
  2037. X    XtPointer client_data, call_data;
  2038. X{
  2039. X    XawListReturnStruct *lrs = (XawListReturnStruct *) call_data;
  2040. X    int i;
  2041. X    struct menu_info_t *menu_info;
  2042. X    struct menu_item *curr;
  2043. X    struct xwindow *wp;
  2044. X
  2045. X    wp = find_widget(w);
  2046. X    menu_info  = wp->menu_information;
  2047. X
  2048. X    for (i = 0, curr = menu_info->base; i < lrs->list_index; i++) {
  2049. X    if (!curr) panic("menu_select: out of menu items!");
  2050. X    curr = curr->next;
  2051. X    }
  2052. X
  2053. X    /* If we don't have a selector, try again. */
  2054. X    if (!curr->selector) {
  2055. X    XawListUnhighlight(w);    /* unhilight non-menu item */
  2056. X    X11_nhbell();
  2057. X    return;
  2058. X    }
  2059. X    menu_selected = curr->selector;
  2060. X
  2061. X    nh_XtPopdown(wp->popup);    /* this removes the event grab */
  2062. X    exit_x_event = TRUE;    /* exit our event handler */
  2063. X}
  2064. X
  2065. X/*
  2066. X * Called when we get a key press event on a menu window.
  2067. X */
  2068. X/* ARGSUSED */
  2069. Xvoid
  2070. Xmenu_key(w, event, params, num_params)
  2071. X    Widget w;
  2072. X    XEvent *event;
  2073. X    String *params;
  2074. X    Cardinal *num_params;
  2075. X{
  2076. X    struct menu_info_t *menu_info;
  2077. X    struct menu_item *curr;
  2078. X    struct xwindow *wp;
  2079. X    char ch;
  2080. X    int count;
  2081. X
  2082. X    wp = find_widget(w);
  2083. X    menu_info  = wp->menu_information;
  2084. X
  2085. X    ch = key_event_to_char((XKeyEvent *) event);
  2086. X
  2087. X    if (ch == '\0') {    /* don't accept nul char/modifier event */
  2088. X    /* don't beep */
  2089. X    return;
  2090. X    }
  2091. X
  2092. X    for (count = 0, curr = menu_info->base; curr; curr = curr->next, count++)
  2093. X    if (curr->selector == ch) break;
  2094. X
  2095. X    if (curr) {
  2096. X    XawListHighlight(w, count);    /* highlit item */
  2097. X    menu_selected = ch;
  2098. X    } else if (menu_info->other_valid && index(menu_info->other_valid, ch)) {
  2099. X    menu_selected = menu_info->other_response;
  2100. X    } else {
  2101. X    X11_nhbell();        /* no match */
  2102. X    return;
  2103. X    }
  2104. X
  2105. X    nh_XtPopdown(wp->popup);    /* this removes the event grab */
  2106. X    exit_x_event = TRUE;    /* exit our event handler */
  2107. X}
  2108. X
  2109. X
  2110. X/* Global functions ======================================================== */
  2111. X
  2112. Xvoid
  2113. XX11_start_menu(window)
  2114. X    winid window;
  2115. X{
  2116. X    struct xwindow *wp;
  2117. X    check_winid(window);
  2118. X
  2119. X    wp = &window_list[window];
  2120. X
  2121. X    if (wp->menu_information->is_menu) {
  2122. X    /* clear old menu and widgets (if any) */
  2123. X    clear_old_menu(wp);
  2124. X    } else {
  2125. X    wp->menu_information->is_menu = TRUE;
  2126. X    }
  2127. X}
  2128. X
  2129. Xvoid
  2130. XX11_add_menu(window, ch, attr, str)
  2131. X    winid window;
  2132. X    char ch;
  2133. X    int attr;
  2134. X    const char *str;
  2135. X{
  2136. X    struct menu_item *item;
  2137. X    struct menu_info_t *menu_info;
  2138. X
  2139. X    check_winid(window);
  2140. X    menu_info = window_list[window].menu_information;
  2141. X    check_menu("add_menu");
  2142. X
  2143. X    item = (struct menu_item *) alloc((unsigned)sizeof(struct menu_item));
  2144. X    item->next = (struct menu_item *) 0;
  2145. X    item->selector = ch;
  2146. X    item->attr = attr;
  2147. X    item->str = copy_of(str);
  2148. X
  2149. X    if (menu_info->last) {
  2150. X    menu_info->last->next = item;
  2151. X    } else {
  2152. X    menu_info->base = item;
  2153. X    }
  2154. X    menu_info->last = item;
  2155. X    menu_info->count++;
  2156. X}
  2157. X
  2158. Xvoid
  2159. XX11_end_menu(window, cancel_ch, cancel_str, morestr)
  2160. X    winid window;
  2161. X    char cancel_ch;
  2162. X    const char *cancel_str;
  2163. X    const char *morestr;
  2164. X{
  2165. X    struct menu_info_t *menu_info;
  2166. X    check_winid(window);
  2167. X    menu_info = window_list[window].menu_information;
  2168. X    check_menu("end_menu");
  2169. X
  2170. X    if(morestr && strlen(morestr))
  2171. X    X11_add_menu(window, 0, 0, morestr);
  2172. X    menu_info->other_valid = cancel_str;
  2173. X    menu_info->other_response = cancel_ch;
  2174. X    menu_info->query = morestr;
  2175. X}
  2176. X
  2177. Xchar
  2178. XX11_select_menu(window)
  2179. X    winid window;
  2180. X{
  2181. X    struct menu_item *curr;
  2182. X    struct xwindow *wp;
  2183. X    struct menu_info_t *menu_info;
  2184. X    Arg args[8];
  2185. X    Cardinal num_args;
  2186. X    String *ptr;
  2187. X    int i;
  2188. X    Widget viewport_widget;
  2189. X    Dimension pixel_height, top_margin, spacing;
  2190. X    XFontStruct *fs;
  2191. X
  2192. X    check_winid(window);
  2193. X    wp = &window_list[window];
  2194. X    menu_info = wp->menu_information;
  2195. X
  2196. X#if defined(LINT) || defined(GCC_WARN)
  2197. X    {
  2198. X    /* cannot use check_menu, since it doesn't return anything */
  2199. X    if (!menu_info->is_menu) {
  2200. X        impossible("%s:  called before start_menu", "select_menu");
  2201. X        return '\0';
  2202. X    }
  2203. X    }
  2204. X#else
  2205. X    check_menu("select_menu");
  2206. X#endif
  2207. X
  2208. X#ifdef VERBOSE
  2209. X    /* ********** */
  2210. X    if (menu_info->other_valid) {
  2211. X    char *cp;
  2212. X    printf("select_menu: other_valid = \"");
  2213. X    for (cp = menu_info->other_valid; *cp; cp++) {
  2214. X        if (*cp < 32) {
  2215. X        printf("^%c", '@' + *cp);
  2216. X        } else
  2217. X        printf("%c", *cp);
  2218. X    }
  2219. X    printf("\"\n");
  2220. X    } else {
  2221. X    printf("select_menu: other_valid = NULL\n");
  2222. X    }
  2223. X    if (menu_info->other_response < 32) {
  2224. X    printf("select_menu: other_response = '^%c'\n",
  2225. X                    '@' + menu_info->other_response);
  2226. X    } else {
  2227. X    printf("select_menu: other_response = '%c'\n",
  2228. X                        menu_info->other_response);
  2229. X    }
  2230. X    if (menu_info->query) {
  2231. X    printf("select_menu: query = \"%s\"\n", menu_info->query);
  2232. X    } else {
  2233. X    printf("select_menu: query = NULL\n");
  2234. X    }
  2235. X    /* ********** */
  2236. X#endif
  2237. X
  2238. X    num_args = 0;
  2239. X    XtSetArg(args[num_args], XtNallowShellResize, True); num_args++;
  2240. X
  2241. X    wp->popup = XtCreatePopupShell("menu", transientShellWidgetClass,
  2242. X                   toplevel, args, num_args);
  2243. X
  2244. X    menu_info->list_pointer =
  2245. X    (String *) alloc((unsigned) (sizeof(String) * (menu_info->count+1)));
  2246. X    for (i = 0, ptr = menu_info->list_pointer, curr = menu_info->base;
  2247. X            i < menu_info->count; i++, ptr++, curr = curr->next) {
  2248. X    *ptr = (String) curr->str;
  2249. X    }
  2250. X    *ptr = (String) 0;
  2251. X
  2252. X    num_args = 0;
  2253. X    XtSetArg(args[num_args], XtNallowVert,      True);           num_args++;
  2254. X
  2255. X    viewport_widget = XtCreateManagedWidget(
  2256. X        "menu_viewport",    /* name */
  2257. X        viewportWidgetClass,
  2258. X        wp->popup,        /* parent widget */
  2259. X        args, num_args);    /* values, and number of values */
  2260. X
  2261. X    num_args = 0;
  2262. X    XtSetArg(args[num_args], XtNforceColumns, True);        num_args++;
  2263. X    XtSetArg(args[num_args], XtNdefaultColumns, 1);        num_args++;
  2264. X    XtSetArg(args[num_args], XtNlist, menu_info->list_pointer);    num_args++;
  2265. X    XtSetArg(args[num_args], XtNtranslations,
  2266. X        XtParseTranslationTable(menu_translations));    num_args++;
  2267. X
  2268. X    wp->w = XtCreateManagedWidget(
  2269. X        "menu_list",        /* name */
  2270. X        listWidgetClass,
  2271. X        viewport_widget,    /* parent widget */
  2272. X        args,            /* set some values */
  2273. X        num_args);        /* number of values to set */
  2274. X
  2275. X    XtAddCallback(wp->w, XtNcallback, menu_select, (XtPointer) 0);
  2276. X
  2277. X    menu_info->valid_widgets = TRUE;
  2278. X
  2279. X    /* Get the font and margin information. */
  2280. X    num_args = 0;
  2281. X    XtSetArg(args[num_args], XtNfont,          &fs);         num_args++;
  2282. X    XtSetArg(args[num_args], XtNinternalHeight, &top_margin);    num_args++;
  2283. X    XtSetArg(args[num_args], XtNrowSpacing,     &spacing);    num_args++;
  2284. X    XtGetValues(wp->w, args, num_args);
  2285. X
  2286. X    /* font height is ascent + descent */
  2287. X    pixel_height = top_margin +
  2288. X    ((menu_info->count + 4) *
  2289. X     (fs->max_bounds.ascent + fs->max_bounds.descent + spacing));
  2290. X
  2291. X    /* if viewport will be bigger than the screen, limit its height */
  2292. X    if ((Dimension) XtScreen(wp->w)->height <= pixel_height) {
  2293. X    pixel_height = XtScreen(wp->w)->height / 2;
  2294. X
  2295. X    num_args = 0;
  2296. X    XtSetArg(args[num_args], XtNheight, pixel_height); num_args++;
  2297. X    XtSetValues(viewport_widget, args, num_args);
  2298. X    }
  2299. X
  2300. X    XtRealizeWidget(wp->popup);    /* need to realize before we position */
  2301. X    positionpopup(wp->popup);
  2302. X
  2303. X    menu_selected = '\0';
  2304. X
  2305. X    nh_XtPopup(wp->popup, XtGrabExclusive, wp->w);
  2306. X    (void) x_event(EXIT_ON_EXIT);
  2307. X
  2308. X    return menu_selected;
  2309. X}
  2310. X
  2311. X/* End global functions ==================================================== */
  2312. X
  2313. Xstatic char *
  2314. Xcopy_of(s)
  2315. X    char *s;
  2316. X{
  2317. X    char *copy;
  2318. X    if (s) {
  2319. X    copy = (char *) alloc((unsigned) (strlen(s)+1));
  2320. X    Strcpy(copy,s);
  2321. X    } else {
  2322. X    copy = (char *) alloc((unsigned) 1);
  2323. X    *copy = '\0';
  2324. X    }
  2325. X
  2326. X    return copy;
  2327. X}
  2328. X
  2329. Xstatic void
  2330. Xclear_old_menu(wp)
  2331. X    struct xwindow *wp;
  2332. X{
  2333. X    struct menu_info_t *menu_info = wp->menu_information;
  2334. X
  2335. X    while (menu_info->base) {
  2336. X    menu_info->last = menu_info->base;
  2337. X    menu_info->base = menu_info->base->next;
  2338. X
  2339. X    free(menu_info->last->str);
  2340. X    free((char *)menu_info->last);
  2341. X    }
  2342. X    menu_info->last = (struct menu_item *) 0;
  2343. X    menu_info->other_valid = (char *) 0;
  2344. X    menu_info->other_response = '\0';
  2345. X    menu_info->query = (char *) 0;
  2346. X    menu_info->count = 0;
  2347. X
  2348. X    if (menu_info->valid_widgets) {
  2349. X    nh_XtPopdown(wp->popup);
  2350. X    XtDestroyWidget(wp->popup);
  2351. X    menu_info->valid_widgets = FALSE;
  2352. X    free((char *) menu_info->list_pointer);
  2353. X    }
  2354. X}
  2355. X
  2356. Xvoid
  2357. Xcreate_menu_window(wp)
  2358. X    struct xwindow *wp;
  2359. X{
  2360. X    struct menu_info_t *menu_info;
  2361. X
  2362. X    wp->type = NHW_MENU;
  2363. X
  2364. X    wp->menu_information = menu_info = 
  2365. X            (struct menu_info_t *) alloc(sizeof(struct menu_info_t));
  2366. X
  2367. X    menu_info->base          = (struct menu_item *) 0;
  2368. X    menu_info->last          = (struct menu_item *) 0;
  2369. X    menu_info->query          = (char *) 0;
  2370. X    menu_info->other_valid    = (char *) 0;
  2371. X    menu_info->other_response = '\0';
  2372. X    menu_info->count          = 0;
  2373. X    menu_info->list_pointer   = (String *) 0;
  2374. X    menu_info->valid_widgets  = FALSE;
  2375. X    wp->w = wp->popup = (Widget) 0;
  2376. X    menu_info->is_menu          = FALSE;
  2377. X}
  2378. X
  2379. Xvoid
  2380. Xdestroy_menu_window(wp)
  2381. X    struct xwindow *wp;
  2382. X{
  2383. X    /* printf("destroy_menu_window\n"); */
  2384. X
  2385. X    clear_old_menu(wp);        /* this will also destroy the widgets */
  2386. X    free((char *) wp->menu_information);
  2387. X
  2388. X    wp->type = NHW_NONE;    /* allow re-use */
  2389. X}
  2390. X
  2391. X
  2392. END_OF_FILE
  2393. if test 9918 -ne `wc -c <'win/X11/winmenu.c'`; then
  2394.     echo shar: \"'win/X11/winmenu.c'\" unpacked with wrong size!
  2395. fi
  2396. # end of 'win/X11/winmenu.c'
  2397. fi
  2398. echo shar: End of archive 92 \(of 108\).
  2399. cp /dev/null ark92isdone
  2400. MISSING=""
  2401. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2402. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2403. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2404. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2405. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2406. 101 102 103 104 105 106 107 108 ; do
  2407.     if test ! -f ark${I}isdone ; then
  2408.     MISSING="${MISSING} ${I}"
  2409.     fi
  2410. done
  2411. if test "${MISSING}" = "" ; then
  2412.     echo You have unpacked all 108 archives.
  2413.     echo "Now execute 'rebuild.sh'"
  2414.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2415. else
  2416.     echo You still need to unpack the following archives:
  2417.     echo "        " ${MISSING}
  2418. fi
  2419. ##  End of shell archive.
  2420. exit 0
  2421.