home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume17 / gbp / part01 < prev    next >
Encoding:
Internet Message Format  |  1993-03-20  |  51.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: v17i013:  gbp - Galactic Bloodshed+, an empire-like war game, Part01/21
  5. Message-ID: <4541@master.CNA.TEK.COM>
  6. Date: 12 Feb 93 17:28:13 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1670
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1692
  11.  
  12. Submitted-by: deragon@harpo.cs.nyu.edu (Seeker)
  13. Posting-number: Volume 17, Issue 13
  14. Archive-name: gbp/Part01
  15. Supersedes: gb3: Volume 10, Issue 1-14
  16. Environment: sockets, curses
  17.  
  18.  
  19. [ From the author...
  20.    This is a new version of Galactic Bloodshed (GB), called GB+.
  21. Up to about 2 months ago the main author was Garrett VanCleef,
  22. but he has since relinquished all the work to me, and the gbdt
  23. (Galactic Bloodshed Development team).
  24.    I am currently the main author for the work, and I am responsible
  25. for releases of it. (This is also available via ftp from scam.berkeley.edu.)
  26.  
  27. John Deragon           deragon@cs.nyu.edu | deragon@jethro.cs.nyu.edu ]
  28.  
  29.  
  30. #! /bin/sh
  31. # This is a shell archive.  Remove anything before this line, then unpack
  32. # it by saving it into a file and typing "sh file".  To overwrite existing
  33. # files, type "sh file -c".  You can also feed this as standard input via
  34. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  35. # will see the following message at the end:
  36. #        "End of archive 1 (of 21)."
  37. # Contents:  README MANIFEST doc hdrs hdrs/buffers.h misc server user
  38. #   utils utils/racegen.c
  39. # Wrapped by billr@saab on Fri Feb 12 09:14:23 1993
  40. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  41. if test -f 'README' -a "${1}" != "-c" ; then 
  42.   echo shar: Will not clobber existing file \"'README'\"
  43. else
  44. echo shar: Extracting \"'README'\" \(2607 characters\)
  45. sed "s/^X//" >'README' <<'END_OF_FILE'
  46. X
  47. X
  48. X    This is the new and improved GB.  At least in the installation
  49. Xportion anyway! :-)
  50. X
  51. X    Basically the whole directory structure has been redone.  It also
  52. Xcomes with Larry Walls "Configure" script to ease the pain of installtion,
  53. Xthe the manual editing of files.
  54. X
  55. X
  56. X    Given the fact you are reading this, I take it you extracted the
  57. Xarchive alread.  It will probably be best if you extracted the contents
  58. Xof the archive into an empty directory called GB.  
  59. X
  60. X    Regardless, you should have a handfull of directorys now, (hdrs,
  61. Xserver, doc, misc, utils and user).  A few README files, a MANIFEST,
  62. Xand a Makefile.SH.
  63. X
  64. X
  65. X    Your first step is to run configure.  Either type Configure
  66. Xor sh Configure, your choice.   It will go through and ask you some
  67. Xquestions about your system, and the host that GB will run on and the
  68. Xport and such.  The only questions you really gotta watch out for
  69. Xand make sure are right are:
  70. X
  71. X    the hostname and domaniname
  72. X    the port
  73. X    and where the datafiles are to be kept.
  74. X
  75. X    Out of all of them the datafiles is the most important.  The default
  76. Xshould be fine in most cases.  (it will take your current directory).
  77. X
  78. X    After you answer all the questions, it will extract the Makefiles,
  79. Xand perform a few symbolic links.  (the links are for the utilites 
  80. Xprograms, which share some of the server modules.)
  81. X
  82. X    After all the Makefiles are extracted and the links are made you
  83. Xshould inspect the hdrs/files.h and hdrs/config.h files to make sure
  84. Xthe look ok.  If you dont know what they are supposed to look like,
  85. Xassume they are ok!  *wink*
  86. X
  87. X
  88. X    Well... now for the moment of truth...
  89. X
  90. X    From the top level directory (where this file resides), type
  91. X
  92. X    make all
  93. X
  94. X    You should see it changing into the various directorys, and do
  95. Xthe compiles.  After it is done...  you should type...
  96. X
  97. X
  98. X    make install
  99. X
  100. X
  101. X    This will take all the binaries, (GB, enrol, makeuniv) and the
  102. Xsupport files, (planet.list, welcome.txt, ship.dat) and place the
  103. Xwhole deal in the bin directory.
  104. X
  105. X    THATS IT!!  Just cd to bin, and start things up...
  106. X
  107. X    (You know, makeuniv, then enrol, then GB).
  108. X
  109. X
  110. X    If you need to debug the user files (via dbx or gbx or whatever),
  111. Xuse the make target GBX.  This will not link with a library, and instead
  112. Xwill link with all the .o files in user.  (The list of the .o files, is
  113. Xmaintained in ./user/OBJECTS.  I know there must be another way of maintaining
  114. Xthis list, but I have not found it)
  115. X
  116. X    If you have _any_ problems, please drop me a line at
  117. X        deragon@jethro.nyu.edu
  118. X
  119. X    and let me know what went wrong.
  120. X
  121. X
  122. X    Thanks...
  123. X
  124. X    John Paul Deragon
  125. X    deragon@jethro.nyu.edu
  126. X    Thu Dec 10 23:28:29 EST 1992
  127. X    1.2 17:03:57
  128. END_OF_FILE
  129. if test 2607 -ne `wc -c <'README'`; then
  130.     echo shar: \"'README'\" unpacked with wrong size!
  131. fi
  132. # end of 'README'
  133. fi
  134. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  135.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  136. else
  137. echo shar: Extracting \"'MANIFEST'\" \(3989 characters\)
  138. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  139. X   File Name        Archive #    Description
  140. X-----------------------------------------------------------
  141. X Configure                  4    
  142. X MANIFEST                   1    This shipping list
  143. X Makefile.SH               20    
  144. X README                     1    
  145. X buildfiles.sh              8    
  146. X doc                        1    
  147. X doc/CHANGES               19    
  148. X doc/CLIENT_PROTOCOL       18    
  149. X doc/README_OLD            19    
  150. X doc/VERSION                5    
  151. X doc/racegen.README        21    
  152. X doc/racegen.novice-info   20    
  153. X doc/races.doc             19    
  154. X hdrs                       1    
  155. X hdrs/GB_copyright.h       21    
  156. X hdrs/TinyMUD_copyright.h  21    
  157. X hdrs/buffers.h             1    
  158. X hdrs/config.h             18    
  159. X hdrs/config.h.SH          18    
  160. X hdrs/csp.h                16    
  161. X hdrs/doturn.h             21    
  162. X hdrs/file.h                4    
  163. X hdrs/files.h              21    
  164. X hdrs/files.h.SH           20    
  165. X hdrs/game_info.h          21    
  166. X hdrs/interface.h           6    
  167. X hdrs/power.h              21    
  168. X hdrs/proto.h               7    
  169. X hdrs/racegen.h            18    
  170. X hdrs/races.h              19    
  171. X hdrs/shipdata.h           16    
  172. X hdrs/ships.h              16    
  173. X hdrs/tweakables.h         17    
  174. X hdrs/vars.h               16    
  175. X misc                       1    
  176. X misc/Makefile.SH          21    
  177. X misc/daemon.txt           12    
  178. X misc/exam.dat             11    
  179. X misc/help.txt             20    
  180. X misc/planet.list          19    
  181. X misc/ship.dat             21    
  182. X misc/star.list            20    
  183. X misc/welcome.txt           4    
  184. X server                     1    
  185. X server/GB_server.c         3    
  186. X server/Makefile.SH        19    
  187. X server/access.c            3    
  188. X server/client.c           20    
  189. X server/doplanet.c          7    
  190. X server/dosector.c         19    
  191. X server/doship.c           10    
  192. X server/doturn.c           10    
  193. X server/files.c            21    
  194. X server/files_rw.c         21    
  195. X server/files_shl.c        13    
  196. X server/get4args.c         21    
  197. X server/getplace.c         17    
  198. X server/lists.c            20    
  199. X server/log.c              20    
  200. X server/max.c              20    
  201. X server/misc.c             20    
  202. X server/moveplanet.c       21    
  203. X server/moveship.c          5    
  204. X server/perm.c              2    
  205. X server/rand.c             21    
  206. X server/shlmisc.c           9    
  207. X user                       1    
  208. X user/Makefile.SH          15    
  209. X user/OBJECTS              21    
  210. X user/SOURCES              21    
  211. X user/analysis.c           13    
  212. X user/autoreport.c         21    
  213. X user/autoshoot.c          20    
  214. X user/build.c1             15    
  215. X user/build.c2              2    
  216. X user/capital.c            21    
  217. X user/capture.c            14    
  218. X user/chan.c               20    
  219. X user/cs.c                 16    
  220. X user/declare.c            16    
  221. X user/dissolve.c           19    
  222. X user/dock.c               12    
  223. X user/enslave.c            19    
  224. X user/examine.c            20    
  225. X user/explore.c            14    
  226. X user/fire.c               11    
  227. X user/fuel.c               17    
  228. X user/guardian.c           21    
  229. X user/help.c               21    
  230. X user/land.c               13    
  231. X user/launch.c             17    
  232. X user/load.c                5    
  233. X user/map.c                18    
  234. X user/mobiliz.c            10    
  235. X user/move.c                9    
  236. X user/name.c                6    
  237. X user/orbit.c              14    
  238. X user/order.c               8    
  239. X user/power.c              11    
  240. X user/prof.c               14    
  241. X user/relation.c           21    
  242. X user/rst.c                12    
  243. X user/sche.c               21    
  244. X user/scrap.c              15    
  245. X user/shootblast.c          8    
  246. X user/survey.c             12    
  247. X user/tech.c               21    
  248. X user/tele.c               18    
  249. X user/togg.c               19    
  250. X user/toxi.c               21    
  251. X user/vict.c               20    
  252. X user/zoom.c               21    
  253. X utils                      1    
  254. X utils/GB_racegen.c        17    
  255. X utils/Makefile.SH         20    
  256. X utils/Makelist.c          14    
  257. X utils/README_EXSHIP       20    
  258. X utils/enrol.c             13    
  259. X utils/enroll.c            18    
  260. X utils/exship.c            17    
  261. X utils/makeplanet.c         6    
  262. X utils/makestar.c          15    
  263. X utils/makeuniv.c          15    
  264. X utils/psmap.c             18    
  265. X utils/racegen.c            1    
  266. END_OF_FILE
  267. if test 3989 -ne `wc -c <'MANIFEST'`; then
  268.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  269. fi
  270. # end of 'MANIFEST'
  271. fi
  272. if test ! -d 'doc' ; then
  273.     echo shar: Creating directory \"'doc'\"
  274.     mkdir 'doc'
  275. fi
  276. if test ! -d 'hdrs' ; then
  277.     echo shar: Creating directory \"'hdrs'\"
  278.     mkdir 'hdrs'
  279. fi
  280. if test -f 'hdrs/buffers.h' -a "${1}" != "-c" ; then 
  281.   echo shar: Will not clobber existing file \"'hdrs/buffers.h'\"
  282. else
  283. echo shar: Extracting \"'hdrs/buffers.h'\" \(133 characters\)
  284. sed "s/^X//" >'hdrs/buffers.h' <<'END_OF_FILE'
  285. XEXTERN char buf[2047];
  286. XEXTERN char long_buf[1024], short_buf[256];
  287. XEXTERN char telegram_buf[AUTO_TELEG_SIZE];
  288. XEXTERN char temp[128];
  289. END_OF_FILE
  290. if test 133 -ne `wc -c <'hdrs/buffers.h'`; then
  291.     echo shar: \"'hdrs/buffers.h'\" unpacked with wrong size!
  292. fi
  293. # end of 'hdrs/buffers.h'
  294. fi
  295. if test ! -d 'misc' ; then
  296.     echo shar: Creating directory \"'misc'\"
  297.     mkdir 'misc'
  298. fi
  299. if test ! -d 'server' ; then
  300.     echo shar: Creating directory \"'server'\"
  301.     mkdir 'server'
  302. fi
  303. if test ! -d 'user' ; then
  304.     echo shar: Creating directory \"'user'\"
  305.     mkdir 'user'
  306. fi
  307. if test ! -d 'utils' ; then
  308.     echo shar: Creating directory \"'utils'\"
  309.     mkdir 'utils'
  310. fi
  311. if test -f 'utils/racegen.c' -a "${1}" != "-c" ; then 
  312.   echo shar: Will not clobber existing file \"'utils/racegen.c'\"
  313. else
  314. echo shar: Extracting \"'utils/racegen.c'\" \(39848 characters\)
  315. sed "s/^X//" >'utils/racegen.c' <<'END_OF_FILE'
  316. X/* racegen - a Galactic Bloodshed race creation program.
  317. X * Copyright (c) Leonard Dickens 1991   (leonard@cs.umd.edu)
  318. X *
  319. X * Permission to copy, distribute, and/or alter is granted as long as the copy-
  320. X * right notice and these terms are left unchanged in all derivatives/copies.
  321. X * 
  322. X * Anybody who does alter this program, please take credit!
  323. X */
  324. X
  325. X#include <varargs.h>
  326. X
  327. X/* Slightly hacked version: altered to use varargs by Tom Boutell. */
  328. X
  329. X/*
  330. X * History:
  331. X * 09-13-91 1.0.0 LD Started work
  332. X * 09-14-91 1.0.0 LD Finished except for tweaking cost parameters.
  333. X * 09-15-91 1.0.0 LD Added linear parameterizations for all attributes.
  334. X *   Added exponential portions to most of the attributes.  Structured 
  335. X *   attributes to allow easy expansion.
  336. X * 09-15-91 1.1.0 LD Added load and save (non-verbose), and print-to-file.
  337. X * 09-16-91 1.2.0 LD Added sector cost-covariances.
  338. X * 09-16-91 1.2.1 LD Added attribute cost-covariances.  Tweaked n_sector costs.
  339. X * 09-17-91       LD Posted the program.  Let's see what the net digs up.
  340. X * 09-18-91 1.2.2 LD Tweaked help to not display plated as a sector option.
  341. X *   Made gas races unable to have any other sector compat.  Made default
  342. X *   IQ be only 125.  Made max birthrate be 1.0.
  343. X * 09-19-91 1.2.3 LD More tweaks to get attribute costs like I want them.
  344. X * 09-20-91 1.2.4 LD Added new #defines and prints for more game-dependent
  345. X *   information for the players' edification.
  346. X * 09-20-91 1.3.0 LD Added all morph attributes separately; removed race costs.
  347. X * 09-25-91 1.4.0 LD Added ENROLL variant code.
  348. X * 09-25-91       LD Posted the program again.  
  349. X * 09-30-91 1.4.1 LD Yeck, this is more complicated than I thought.  Sigh.
  350. X *   Added an address field to the race structure.  Separated critique info
  351. X *   out from modify to allow it to be called from enroll.  Added "last"
  352. X *   race in order to always have a valid race to fall back on.  Added
  353. X *   rejection field to x structure for enroll to use.
  354. X * 09-31-91 1.4.2 LD Added cost extra cost for non-typical sectors.  This
  355. X *   if in essense just a planet_type-compat covariance.
  356. X * 10-01-91 1.4.3 LD Separated out modify-print loop in order to allow
  357. X *   enroll to recursively edit.
  358. X * 10-03-91 1.4.4 LD Mods to compile with old GB enroll.  Changed "IQ" to
  359. X *   something else...A_IQ.  Changed OTHER to OTHER_STUFF.  Changed order
  360. X *   of sector defines to match DES_ defines in tweakables.h
  361. X * 10-03-91 1.5.0 LD File breakup to promote separate compilation.
  362. X * 10-04-91 1.5.1 LD Added Dialogue command to centralize simple exchanges.
  363. X *   this is really just a CS major nicety; it is not needed.
  364. X * 10-06-91 1.5.2 LD Fixed bug in critique that squelched jovian compat.
  365. X * 10-07-91 1.5.3 LD Fixed iq/iq_limit load covariance problem.
  366. X * 12-15-92 1.5.3 JPD Added 1.5.3 to GB+ distribution.  Added racegen.c to
  367. X *   utils directory, racegen.h to hdrs directory, and docs to docs direc.
  368. X * 
  369. X *
  370. X * Thanks to:
  371. X * Clay Luther for the original, (perl) racegen.  I made sure to look at it
  372. X *   before starting this, and in got much of the linear aspects of my
  373. X *   attribute cost functions from his program.  Also, the 125 IQ is Clay's.
  374. X * Keesh, for the numbers, too.  At least, Clay thanks him for them, so I
  375. X *   think I should too.
  376. X * Paul A Daniels for pointing out that help displayed plated as a possible
  377. X *   argument for modify.
  378. X * jtop@cs.kun.nl for the race with gas and other compats too.  My blind spot.
  379. X * Doug Ingram for suggesting more game-dependent info be included.
  380. X *
  381. X * Version: (sccs) 1.4 05:32:31
  382. X */
  383. X#include <math.h>
  384. X#include <signal.h>
  385. X#include <stdio.h>
  386. X#include <string.h>
  387. X
  388. X
  389. X
  390. X/**************
  391. X * Definitions for data types and such used in the program.
  392. X */
  393. X#include "racegen.h"
  394. X
  395. X
  396. Xattribute attr[N_ATTRIBUTES] = {
  397. X  {ADVENT, "Adventurism",
  398. X     0.0, 0.0, 0.0, 300.0, 0.0,
  399. X     0.05, 0.4, 0.99,
  400. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  401. X     0},
  402. X  {ABSORB, "Absorb",
  403. X     0.0, 0.0, 0.0, 150.0, 0.0,
  404. X     0.00, 0.00, 1.00,
  405. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  406. X     2},
  407. X  {BIRTH, "Birthrate", 
  408. X     0.0, 0.0, 0.0, 500.0, 0.0,
  409. X     0.2, 0.6, 1.0, 
  410. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  411. X     0},
  412. X  {COL_IQ, "Collective IQ",
  413. X     0.0, 0.0, 0.0, -350.5, 0.0,
  414. X     0.00, 0.00, 1.00,
  415. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  416. X     2},
  417. X  {FERT, "Fertilize", 
  418. X     200.0, 1.0, 1.0, 300.0, 0.0,
  419. X     0.0, 0.0, 1.0, 
  420. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  421. X     0},
  422. X  {A_IQ, "IQ", 
  423. X     100.0, 0.03, 140, 6, 0.0,
  424. X     50, 125, 220,
  425. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  426. X     1},
  427. X  {FIGHT, "Fight", 
  428. X     10.0, 0.4, 6.0, 65.0, 0.0,
  429. X     1, 4, 20, 
  430. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  431. X     1},
  432. X  {PODS, "Pods",
  433. X     0.0, 0.0, 0.0, 250.0, 0.0,
  434. X     0.00, 0.00, 1.00,
  435. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  436. X     2},
  437. X  {MASS, "Mass", 
  438. X     100.0, 1.0, 3.1, -100.0, 0.0,
  439. X     0.1, 1.0, 3.0, 
  440. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  441. X     0},
  442. X  {SEXES, "Sexes", 
  443. X     2.2, -0.5, 9.0, -3.0, 0.0, 
  444. X     1, 2, 53, 
  445. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  446. X     1},
  447. X  {METAB, "Metabolism", 
  448. X     300.0, 0.8, 1.3, 700.0, 0.0,
  449. X     0.1, 0.8, 4.0, 
  450. X     {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  451. X     0}
  452. X  } ;
  453. X
  454. Xconst char *planet_print_name[N_HOME_PLANET_TYPES] = {
  455. X"Earth", "Forest", "Desert", "Water", "Airless", "Iceball", "Jovian"} ;
  456. Xconst int planet_cost[N_HOME_PLANET_TYPES] = {
  457. X75, 50, 50, 50, -25, -25, 700} ;
  458. X
  459. Xconst char *race_print_name[N_RACE_TYPES] = {"Normal", "Metamorph"} ;
  460. Xconst int race_cost[N_RACE_TYPES] = {0, 0} ;
  461. X
  462. Xconst char *priv_print_name[N_PRIV_TYPES] = {"God", "Guest", "Normal"} ;
  463. X
  464. Xconst char *sector_print_name[N_SECTOR_TYPES] = {
  465. X"Water", "Land", "Mountain", "Gas", "Ice", "Forest", "Desert", "Plated"} ;
  466. X
  467. Xconst double compat_cov[N_SECTOR_TYPES][N_SECTOR_TYPES] = {
  468. X/*  .       *        ^       ~       #       )       -      o  */
  469. X  {0.0,    },
  470. X  { .001,  0.0      },
  471. X  { .002,  -.0005,  0.0,    },
  472. X  {999,    999,     999,    0.0,    },
  473. X  { .001,  0.0,     -.002,  999,    0.0,    },
  474. X  {0.0,    -.001,   0.0,    999,     .001,  0.0,    },
  475. X  { .003,  -.0005,  0.0,    999,    0.0,     .001,  0.0},
  476. X  {0.0,    0.0,     0.0,    999,    0.0,    0.0,    0.0,   0.0}
  477. X  } ;
  478. X
  479. Xconst double planet_compat_cov[N_HOME_PLANET_TYPES][N_SECTOR_TYPES] = {
  480. X         /*  .      *      ^      ~      #      )      -      o  */
  481. X/* @ */  { 1.00,  1.00,  1.50, 99.00,  1.01,  1.01,  1.50,  1.01},
  482. X/* ) */  { 1.01,  1.01,  1.50, 99.00,  1.01,  1.00,  3.00,  1.01},
  483. X/* - */  { 3.00,  1.01,  1.50, 99.00,  1.01,  3.00,  1.00,  1.01},
  484. X/* . */  { 1.00,  1.01,  1.50, 99.00,  1.01,  1.01,  3.00,  1.01},
  485. X/* O */  { 3.00,  1.00,  1.50, 99.00,  2.00,  3.00,  1.01,  1.01},
  486. X/* # */  { 3.00,  2.00,  1.00, 99.00,  1.00,  3.00,  2.00,  1.01},
  487. X/* ~ */  {99.00, 99.00, 99.00,  1.00, 99.00, 99.00, 99.00, 99.00}
  488. X     } ;
  489. X
  490. X
  491. X/**************
  492. X * Global variables for this program.
  493. X */
  494. Xstruct x race, cost, last ;
  495. X
  496. Xint npoints = STARTING_POINTS ;
  497. Xint last_npoints = STARTING_POINTS ;
  498. Xint altered = 0 ;       /* 1 iff race has been altered since last saved */
  499. Xint changed = 1 ;       /* 1 iff race has been changed since last printed */
  500. Xint please_quit = 0 ;   /* 1 iff you want to exit ASAP. */
  501. X
  502. X
  503. X
  504. X/**************
  505. X * Price function for racegen.  Finds the cost of `race', and returns it.
  506. X * As a side effect the costs for all the individual fields of `race' get
  507. X * stuffed into `cost' for later printing.
  508. X */
  509. Xint cost_of_race()
  510. X{
  511. X  int i, j, sum = 0 ;
  512. X
  513. X#define ROUND(f) ((int) (0.5 + (f)))
  514. X  for (i=FIRST_ATTRIBUTE; i<=LAST_ATTRIBUTE; i++)
  515. X    cost.attr[i] = (exp(attr[i].e_fudge * (race.attr[i] - attr[i].e_hinge)) 
  516. X            * attr[i].e_factor + race.attr[i] * attr[i].l_factor) ; 
  517. X#ifdef COVARIANCES
  518. X  for (i=FIRST_ATTRIBUTE; i<=LAST_ATTRIBUTE; i++)
  519. X    for (j=FIRST_ATTRIBUTE; j<=LAST_ATTRIBUTE; j++)
  520. X      if (attr[i].cov[j] != 0.0)
  521. X    cost.attr[i] *= (1.0 + attr[i].cov[j] * race.attr[j]) ;
  522. X#endif
  523. X  for (i=FIRST_ATTRIBUTE; i<=LAST_ATTRIBUTE; i++)
  524. X    sum += (cost.attr[i] = ROUND(cost.attr[i] + attr[i].l_fudge)) ;
  525. X          
  526. X  sum += (cost.home_planet_type = planet_cost[race.home_planet_type]) ;
  527. X  sum += (cost.race_type = race_cost[race.race_type]) ;
  528. X  race.n_sector_types = 0 ;
  529. X  for (i=FIRST_SECTOR_TYPE; i<=LAST_SECTOR_TYPE; i++) {
  530. X    if (race.compat[i] != 0.0)
  531. X      race.n_sector_types += 1 ;
  532. X    /* Get the base costs: */
  533. X    cost.compat[i] = race.compat[i]*0.5 + 10.8*log(1.0+race.compat[i]) ;
  534. X    }
  535. X#ifdef COVARIANCES
  536. X  for (i=FIRST_SECTOR_TYPE; i<=LAST_SECTOR_TYPE; i++)
  537. X    for (j=i+1; j<=LAST_SECTOR_TYPE; j++)
  538. X      if (compat_cov[j][i] != 0.0) {
  539. X    cost.compat[i] *= (1.0 + compat_cov[j][i] * race.compat[j]) ;
  540. X    cost.compat[j] *= (1.0 + compat_cov[j][i] * race.compat[i]) ;
  541. X    }
  542. X  for (i=FIRST_SECTOR_TYPE; i<=LAST_SECTOR_TYPE; i++)
  543. X    if (planet_compat_cov[race.home_planet_type][i] > 1.01)
  544. X      cost.compat[i] *= planet_compat_cov[race.home_planet_type][i] ;
  545. X#endif
  546. X  for (i=FIRST_SECTOR_TYPE; i<=LAST_SECTOR_TYPE; i++)
  547. X    sum += (cost.compat[i] = ROUND(cost.compat[i])) ;
  548. X  sum += (cost.n_sector_types = n_sector_types_cost[race.n_sector_types]) ;
  549. X  return sum ;
  550. X  }
  551. X
  552. X
  553. Xvoid metamorph()
  554. X{
  555. X  /* Adventurousness is not correlated with Max IQ. */
  556. X  attr[ADVENT].cov[A_IQ]    =  0.00 ;
  557. X  /* A high birthrate is easier if few sexes, high metab, and low mass.*/
  558. X  /** Morphs are not born, they hatch.  THus the mass limitation is smaller:**/
  559. X  attr[BIRTH].cov[MASS]   =  0.10 / ATTR_RANGE(MASS) ;
  560. X  attr[BIRTH].cov[SEXES]  =  0.90 / ATTR_RANGE(SEXES) ;
  561. X  attr[BIRTH].cov[METAB]  = -0.20 / ATTR_RANGE(METAB) ;
  562. X  /* Natural fertilization is ultimately associated with metabolic activity */ 
  563. X  /** Morphs are naturally adept at fertilization. **/
  564. X  attr[FERT].cov[METAB]   = -0.60 / ATTR_RANGE(METAB) ;
  565. X  /* Fighting is easier for independent, high-mass, high-metab races:   */
  566. X  attr[FIGHT].cov[ADVENT] = -0.05 / ATTR_RANGE(ADVENT) ;
  567. X  attr[FIGHT].cov[MASS]   = -0.20 / ATTR_RANGE(MASS) ;
  568. X  attr[FIGHT].cov[METAB]  = -0.05 / ATTR_RANGE(METAB) ;
  569. X  /* A high metabolism is hard to support if you have high mass: */
  570. X  /** Due to general squishiness, this effect is not as strong for mesos. **/
  571. X  attr[METAB].cov[MASS]   =  0.05 / ATTR_RANGE(MASS) ;
  572. X  /* However, a large IQ is easier with high mass; (lot of brain space): */
  573. X  /** IQ represents max IQ, thus, no go. **/
  574. X  attr[A_IQ].cov[MASS]      =  0.00 ;
  575. X  /* IQ is cheaper by virtue of collective intelligence: */
  576. X  attr[A_IQ].cov[COL_IQ]    =  -0.4 / ATTR_RANGE(COL_IQ) ;
  577. X
  578. X  strcpy(attr[A_IQ].print_name, "IQ Limit") ;
  579. X  }
  580. X
  581. Xvoid normal()
  582. X{
  583. X  /* Adventurousness is more likely with people smart enough to do it. */
  584. X  attr[ADVENT].cov[A_IQ]  = -0.10 / ATTR_RANGE(A_IQ) ;
  585. X  /* A high birthrate is easier if few sexes, high metab, and low mass.*/
  586. X  attr[BIRTH].cov[MASS]   =  0.40 / ATTR_RANGE(MASS) ;
  587. X  attr[BIRTH].cov[SEXES]  =  0.90 / ATTR_RANGE(SEXES) ;
  588. X  attr[BIRTH].cov[METAB]  = -0.20 / ATTR_RANGE(METAB) ;
  589. X  /* Natural fertilization is ultimately associated with metabolic activity */ 
  590. X  attr[FERT].cov[METAB]   = -0.20 / ATTR_RANGE(METAB) ;
  591. X  /* Fighting is easier for independent, high-mass, high-metab races:   */
  592. X  attr[FIGHT].cov[ADVENT] = -0.05 / ATTR_RANGE(ADVENT) ;
  593. X  attr[FIGHT].cov[MASS]   = -0.20 / ATTR_RANGE(MASS) ;
  594. X  attr[FIGHT].cov[METAB]  = -0.05 / ATTR_RANGE(METAB) ;
  595. X  /* A high metabolism is hard to support if you have high mass: */
  596. X  attr[METAB].cov[MASS]   =  0.15 / ATTR_RANGE(MASS) ;
  597. X  /* However, a large IQ is easier with high mass; (lot of brain space): */
  598. X  attr[A_IQ].cov[MASS]    = -0.10 / ATTR_RANGE(MASS) ;
  599. X  /* IQ is cheaper by virtue of collective intelligence: */
  600. X  attr[A_IQ].cov[COL_IQ]    =  -0.4 / ATTR_RANGE(COL_IQ) ;
  601. X
  602. X  strcpy(attr[A_IQ].print_name, "IQ") ;
  603. X  }
  604. X
  605. X
  606. Xvoid fix_up_iq()
  607. X{
  608. X  if (race.attr[COL_IQ] == 1.0)
  609. X    strcpy(attr[A_IQ].print_name, "IQ Limit") ;
  610. X  else
  611. X    strcpy(attr[A_IQ].print_name, "IQ") ;
  612. X  }
  613. X
  614. X
  615. X
  616. X/**************
  617. X * VERY IMPORTANT FUNCTION: this function is a representation function
  618. X * for the race datatype.  That is, it will return a positive integer iff 
  619. X * the race is NOT valid.  It is thus useful both when modifying a race and
  620. X * when loading a race.  The file f should be NULL if you do not want to
  621. X * print out descriptions of the errors; otherwise, error message(s) will be 
  622. X * printed to that file.  
  623. X */
  624. Xint critique_to_file(f, rigorous_checking, is_player_race)
  625. X     FILE *f ;
  626. X     int rigorous_checking ;
  627. X     int is_player_race ;
  628. X{
  629. X#ifdef TRADITIONAL_RACES
  630. X  static char *tr_caveat = " in traditional GB" ;
  631. X#endif
  632. X  int i, nerrors = 0 ;
  633. X
  634. X#define FPRINTF if (f != NULL) fprintf
  635. X  
  636. X  /*
  637. X   * Check for valid attributes: */
  638. X  for (i = FIRST_ATTRIBUTE; i<=LAST_ATTRIBUTE; i++) {
  639. X    if ((attr[i].is_integral == 2) && 
  640. X    (race.attr[i] != 0.0) && (race.attr[i] != 1.0)) {
  641. X      FPRINTF(f, "%s is boolean valued.  Use \"yes\" or \"no\".\n", 
  642. X         attr[i].print_name) ;
  643. X      nerrors += 1 ;
  644. X      }
  645. X    if (race.attr[i] < attr[i].minimum) {
  646. X      FPRINTF(f, "%s must be at least %0.2f.\n", 
  647. X         attr[i].print_name, attr[i].minimum) ;
  648. X      nerrors += 1 ;
  649. X      }
  650. X    if (race.attr[i] > attr[i].maximum) {
  651. X      FPRINTF(f, "%s may be at most %0.2f.\n", 
  652. X         attr[i].print_name, attr[i].maximum) ;
  653. X      nerrors += 1 ;
  654. X      }
  655. X    /* Warning, but no error: */
  656. X    if (attr[i].is_integral) {
  657. X      if (race.attr[i] != ((double)((int)race.attr[i])))
  658. X    FPRINTF(f, "%s is integral; truncated to %1.0f.\n", attr[i].print_name, 
  659. X           race.attr[i] = ((double)((int)race.attr[i]))) ;
  660. X    }
  661. X    else 
  662. X      if (race.attr[i] != (((double)((int)(100.0*race.attr[i])))/100.0))
  663. X    FPRINTF(f, "%s truncated to next lowest hundredth (%1.2f).\n",
  664. X           attr[i].print_name, 
  665. X           race.attr[i] = (((double)((int)(100.0*race.attr[i])))/100.0)) ;
  666. X    }
  667. X
  668. X
  669. X  /* 
  670. X   * Check for valid normal race attributes: */
  671. X  if (race.race_type == R_NORMAL) {
  672. X    if (race.attr[ABSORB] != 0.0) {
  673. X      FPRINTF(f, "Normal races do not absorb their enemies in combat.\n") ;
  674. X      nerrors += 1 ;
  675. X      }
  676. X    if (race.attr[PODS] != 0.0) {
  677. X      FPRINTF(f, "Normal races do not make pods.\n") ;
  678. X      nerrors += 1 ;
  679. X      }
  680. X#ifdef TRADITIONAL_RACES
  681. X    if (race.attr[COL_IQ] != 0.0) {
  682. X      FPRINTF(f, "Normal races may not have collective iq%s.\n", tr_caveat) ;
  683. X      nerrors += 1 ;
  684. X      }
  685. X    if (race.attr[FERT] != 0.0) {
  686. X      FPRINTF(f, "Normal races do not fertilize%s.\n", tr_caveat) ;
  687. X      nerrors += 1 ;
  688. X      }
  689. X    if (race.attr[SEXES] < 2.0) {
  690. X      FPRINTF(f, "Normal races must have at least two sexes%s.\n", tr_caveat) ;
  691. X      nerrors += 1 ;
  692. X      }
  693. X#endif
  694. X    }
  695. X  
  696. X
  697. X  /* 
  698. X   * Check for valid morph race attributes: */
  699. X  if (race.race_type == R_METAMORPH) {
  700. X    if (race.attr[SEXES] > 1.0) {
  701. X      FPRINTF(f, "Metamorphs always have only one sex.\n") ;
  702. X      nerrors += 1 ;
  703. X      }
  704. X
  705. X#ifdef TRADITIONAL_RACES
  706. X    if (race.attr[A_IQ] != DEFAULT_MESO_IQ_LIMIT) {
  707. X      FPRINTF(f, "Metamorphs' IQ limit may not be changed%s.\n", tr_caveat) ;
  708. X      nerrors += 1 ;
  709. X      } 
  710. X#endif
  711. X    }
  712. X
  713. X  /*
  714. X   * Check for valid name:  */
  715. X  if (0 == strlen(race.name)) {
  716. X    FPRINTF(f, "Use a non-empty name.\n") ;
  717. X    nerrors += 1 ;
  718. X    }
  719. X
  720. X  /*
  721. X   * Check for valid privileges:  */
  722. X  if ((race.priv_type < FIRST_PRIV_TYPE) ||
  723. X      (race.priv_type > LAST_PRIV_TYPE)) {
  724. X    FPRINTF(f, "Privileges out of valid range.\n") ;
  725. X    nerrors += 1 ;
  726. X    }
  727. X  if ((race.priv_type != P_NORMAL) && is_player_race) {
  728. X    FPRINTF(f, "Players may not create %s races.\n", 
  729. X       priv_print_name[race.priv_type]) ;
  730. X    nerrors += 1 ;
  731. X    }
  732. X
  733. X  /*
  734. X   * Check for valid home planet: */
  735. X  if ((race.home_planet_type < FIRST_HOME_PLANET_TYPE) ||
  736. X      (race.home_planet_type > LAST_HOME_PLANET_TYPE)) {
  737. X    FPRINTF(f, "Home planet type out of valid range.\n") ;
  738. X    nerrors += 1 ;
  739. X    }
  740. X
  741. X  /*
  742. X   * Check for valid race: */
  743. X  if ((race.race_type < FIRST_RACE_TYPE) ||
  744. X      (race.race_type > LAST_RACE_TYPE)) {
  745. X    FPRINTF(f, "Home planet type out of valid range.\n") ;
  746. X    nerrors += 1 ;
  747. X    }
  748. X
  749. X  /*
  750. X   * Check for valid sector compats: */
  751. X  if ((race.home_planet_type != H_JOVIAN)&&(race.compat[S_PLATED] != 100.0)) {
  752. X    FPRINTF(f, "Non-jovian races must have 100%% plated compat.\n") ;
  753. X    nerrors += 1 ;
  754. X    }
  755. X  for (i = FIRST_SECTOR_TYPE+1; i<=LAST_SECTOR_TYPE; i++) {
  756. X    if (race.compat[i] < 0.0) {
  757. X      FPRINTF(f, "Sector compatibility is at minimum 0%%.\n") ;
  758. X      nerrors += 1 ;
  759. X      }
  760. X    if (race.compat[i] > 100.0) {
  761. X      FPRINTF(f, "Sector compatibility may be at most 100%%.\n") ;
  762. X      nerrors += 1 ;
  763. X      }
  764. X    if ((i == S_GAS) && (race.compat[i] != 0.0) &&
  765. X    (race.home_planet_type != H_JOVIAN)) {
  766. X      FPRINTF(f, "Non-jovian races may never have gas compatibility!\n") ;
  767. X      nerrors += 1 ;
  768. X      }
  769. X    if ((i != S_GAS) && (race.compat[i] != 0.0) &&
  770. X    (race.home_planet_type == H_JOVIAN)) {
  771. X      FPRINTF(f, "Jovian races may have no compatibility other than gas!\n") ;
  772. X      nerrors += 1 ;
  773. X      }
  774. X    /* A warning, but no error: */
  775. X    if (race.compat[i] != ((double)((int)race.compat[i])))
  776. X      FPRINTF(f, "Sector compatibilities are integral; truncated to %1.0f.\n",
  777. X         race.compat[i] = ((double)((int)race.compat[i]))) ;
  778. X    }
  779. X
  780. X
  781. X
  782. X  if (rigorous_checking) {
  783. X    /*
  784. X     * Any rejection notice is an error: */
  785. X    if (strlen(race.rejection)) {
  786. X      FPRINTF(f, "%s", race.rejection) ;
  787. X      nerrors += 1 ;
  788. X      }
  789. X    /*
  790. X     * Check for valid password: */
  791. X    if (MIN_PASSWORD_LENGTH > strlen(race.password)) {
  792. X      FPRINTF(f, "Passwords are required to be at least %d characters long.\n",
  793. X          MIN_PASSWORD_LENGTH) ;
  794. X      nerrors += 1 ;
  795. X      }
  796. X    /*
  797. X     * Check that race isn't 'superrace': */
  798. X    if (npoints < 0) {
  799. X      FPRINTF(f, "You can't have negative points left!\n");
  800. X      nerrors += 1 ;
  801. X      }
  802. X    /*
  803. X     * Check that sector compats are reasonable. */
  804. X    if ((race.home_planet_type != H_JOVIAN) && (race.n_sector_types == 1)) {
  805. X      FPRINTF(f, "Non-jovian races must be compat with at least one sector type besides plated.\n") ;
  806. X      nerrors += 1 ;
  807. X      }
  808. X    for (i=FIRST_SECTOR_TYPE; i<=LAST_SECTOR_TYPE; i++)
  809. X      if ((planet_compat_cov[race.home_planet_type][i] == 1.0) &&
  810. X      (race.compat[i] == 100.0))
  811. X    break ;
  812. X    if (i == N_SECTOR_TYPES) {
  813. X      FPRINTF(f, "You must have 100%% compat with at least one sector type that is common on\n  your home planet type.  (Marked with a '*')\n") ;
  814. X      nerrors += 1 ;
  815. X      }
  816. X    }
  817. X  if (race.status >= 0)
  818. X    race.status = (nerrors == 0) ? STATUS_BALANCED : STATUS_UNBALANCED ;
  819. X  return nerrors ;
  820. X#undef FPRINTF
  821. X  }
  822. X
  823. X
  824. Xint critique_modification()
  825. X{
  826. X  int nerrors ;
  827. X
  828. X  race.rejection[0] = '\0' ;
  829. X  nerrors = critique_to_file(stdout, 0, IS_PLAYER) ;
  830. X  if (nerrors)
  831. X    bcopy(&last, &race, sizeof(struct x)) ;
  832. X  else
  833. X    changed = altered = 1 ;
  834. X  race.status = (nerrors == 0) ? STATUS_BALANCED : STATUS_UNBALANCED ;
  835. X  return nerrors ;
  836. X  }
  837. X
  838. X
  839. X
  840. X
  841. X/**************
  842. X * Initialize the race to the init value, and set the l_fudge values
  843. X * accordingly so that the cost of this race's attributes is zero.
  844. X */
  845. Xvoid initialize()
  846. X{
  847. X  int i ;
  848. X
  849. X  bzero(&race, sizeof(race)) ;
  850. X  for (i=FIRST_ATTRIBUTE; i<=LAST_ATTRIBUTE; i++)
  851. X    race.attr[i] = attr[i].init ;
  852. X  race.race_type = R_NORMAL ;
  853. X  race.priv_type = P_NORMAL ;
  854. X  race.home_planet_type = H_EARTH ;
  855. X  race.n_sector_types = 1 ;
  856. X  race.compat[S_PLATED] = 100 ;
  857. X  strcpy(race.name, "Unknown") ;
  858. X  strcpy(race.password, "XXX") ;
  859. X  strcpy(race.address, TO) ;
  860. X  normal() ;
  861. X  bcopy(&race, &last, sizeof(struct x)) ;
  862. X  cost_of_race() ;
  863. X  for (i=FIRST_ATTRIBUTE; i<=LAST_ATTRIBUTE; i++)
  864. X    attr[i].l_fudge += -cost.attr[i] ;
  865. X  cost_of_race() ;
  866. X#ifdef ENROLL
  867. X  init_enroll() ;
  868. X#endif
  869. X  }
  870. X
  871. X
  872. X
  873. X/**************
  874. X * Now the functions that implement racegen's commands.  Rather than me
  875. X * trying to tell you about them here, just run the program and diddle
  876. X * with it to get the idea.
  877. X */
  878. Xvoid help(argc, argv)
  879. X     int argc ;
  880. X     char *argv[] ;
  881. X{
  882. X#ifdef ENROLL
  883. X  int enroll, process ;
  884. X#endif
  885. X  int i, j, helpp, load, modify, print, save, send, quit ;
  886. X
  887. X  if (argc == 1) {
  888. X#ifdef ENROLL
  889. X    enroll = process =
  890. X#endif
  891. X    helpp = load = modify = print = save = send = quit = 1 ;
  892. X printf("\n") ;
  893. X printf("To execute a command, type it at the command line.  All commands\n") ;
  894. X printf("and command arguments maybe either upper or lower case, and/or\n") ;
  895. X printf("abbreviated.  The available commands are:\n") ;
  896. X    }
  897. X  else {
  898. X#ifdef ENROLL
  899. X    enroll = process =
  900. X#endif
  901. X    helpp = load = modify = print = save = send = quit = 0 ;
  902. X    for (i=1; i<argc; i++) {
  903. X      j = strlen(argv[i]) ;
  904. X#ifdef ENROLL
  905. X      if      (! strncasecmp(argv[i], "enroll", j))
  906. X    enroll = 1 ;   else
  907. X#endif
  908. X      if      (! strncasecmp(argv[i], "help", j))
  909. X    helpp = 1 ;
  910. X      else if (! strncasecmp(argv[i], "load", j))
  911. X    load = 1 ;
  912. X      else if (! strncasecmp(argv[i], "modify", j))
  913. X    modify = 1 ;
  914. X      else if (! strncasecmp(argv[i], "print", j))
  915. X    print = 1 ;
  916. X#ifdef ENROLL
  917. X      else if (! strncasecmp(argv[i], "process", j))
  918. X    process = 1 ;
  919. X#endif
  920. X      else if (! strncasecmp(argv[i], "save", j))
  921. X    save = 1 ;
  922. X      else if (! strncasecmp(argv[i], "send", j))
  923. X    send = 1 ;
  924. X      else if (! strncasecmp(argv[i], "quit", j))
  925. X    quit = 1 ;
  926. X      else {
  927. X    printf("\n") ;
  928. X    printf("\"%s\" is not a command.\n", argv[i]) ;
  929. X    }
  930. X      }
  931. X    }
  932. X    
  933. X#ifdef ENROLL
  934. X  if (enroll) {
  935. X    printf("\n") ;
  936. X    printf("Enroll\n") ;
  937. X    printf("\t\t This command will add the current race to the game,\n") ;
  938. X    printf("\t\t after checking to make sure it has all points spent, and\n") ;
  939. X    printf("\t\t other such administrivia.\n") ;
  940. X    }
  941. X#endif
  942. X
  943. X  if (helpp) {
  944. X    printf("\n") ;
  945. X    printf("Help [command]*\n") ;
  946. X    printf("\t\t This command gives you information about racegen's\n") ;
  947. X    printf("\t\t commands.  If called with no arguments, it will print\n") ;
  948. X    printf("\t\t information about all available commands.  Otherwise it\n") ;
  949. X    printf("\t\t only prints information about the specified commands.\n") ;
  950. X    }
  951. X
  952. X  if (load) {
  953. X    printf("\n") ;
  954. X    printf("Load [filename]\n") ;
  955. X    printf("\t\t This command will load your race from the file specified\n") ;
  956. X    printf("\t\t in the optional first argument, or from the file \"%s\"\n", 
  957. X       (race.filename[0] ? race.filename : SAVETO)) ;
  958. X    printf("\t\t if no argument is given.\n") ;
  959. X    }
  960. X
  961. X  if (modify) {
  962. X    printf("\n") ;
  963. X    printf("Modify arg1 arg2\n") ;
  964. X    printf("\t\t This command allows you to change the values of your\n") ;
  965. X    printf("\t\t race's name, password, type, attributes, planet, and compats.\n") ;
  966. X    printf("\t\t The syntax is as follows:\n") ;
  967. X    printf("\t\t   <modify>     ::= modify <attr> <value>\n") ;
  968. X#ifdef ENROLL
  969. X    printf("\t\t                  | modify from <string>\n") ;
  970. X#endif
  971. X    printf("\t\t                  | modify name <string>\n") ;
  972. X    printf("\t\t                  | modify password <string>\n") ;
  973. X    printf("\t\t                  | modify planet <planettype>\n") ;
  974. X#ifdef ENROLL
  975. X    printf("\t\t                  | modify privilege <privtype>\n") ;
  976. X#endif
  977. X    printf("\t\t                  | modify race <racetype>\n") ;
  978. X    printf("\t\t                  | modify <sectortype> <value>\n") ;
  979. X
  980. X    printf("\t\t   <attribute>  ::= %s", attr[0].print_name) ;
  981. X    for (i = FIRST_ATTRIBUTE+1; i<LAST_ATTRIBUTE; i++) {
  982. X      printf(" | %s", attr[i].print_name) ;
  983. X      if ((i % 3) == 2)
  984. X    printf("\n\t\t                 ") ;
  985. X      }
  986. X    printf("\n") ;
  987. X
  988. X    printf("\t\t   <planettype> ::= %s", planet_print_name[0]) ;
  989. X    for (i = FIRST_HOME_PLANET_TYPE+1; i<=min(4,LAST_HOME_PLANET_TYPE); i++)
  990. X      printf(" | %s", planet_print_name[i]) ;
  991. X    printf("\n\t\t                 ") ;
  992. X    for (; i<=LAST_HOME_PLANET_TYPE; i++)
  993. X      printf(" | %s", planet_print_name[i]) ;
  994. X    printf("\n") ;
  995. X
  996. X    printf("\t\t   <racetype>   ::= %s", race_print_name[0]) ;
  997. X    for (i = FIRST_RACE_TYPE+1; i<=LAST_RACE_TYPE; i++)
  998. X      printf(" | %s", race_print_name[i]) ;
  999. X    printf("\n") ;
  1000. X
  1001. X    printf("\t\t   <sectortype> ::= %s", sector_print_name[1]) ;
  1002. X    for (i = FIRST_SECTOR_TYPE+2; i<=min(5,LAST_SECTOR_TYPE); i++)
  1003. X      printf(" | %s", sector_print_name[i]) ;
  1004. X    printf("\n\t\t                 ") ;
  1005. X    for (; i<=LAST_SECTOR_TYPE; i++)
  1006. X      printf(" | %s", sector_print_name[i]) ;
  1007. X    printf("\n") ;
  1008. X    }
  1009. X
  1010. X  if (print) {
  1011. X    printf("\n") ;
  1012. X    printf("Print [filename]\n") ;
  1013. X    printf("\t\t With no argument, this command prints your race to the\n") ;
  1014. X    printf("\t\t screen.  It is automatically executed after each modify.\n") ;
  1015. X    printf("\t\t Otherwise it saves a text copy of your race to the file\n") ;
  1016. X    printf("\t\t specified in the first argument.\n") ;
  1017. X    }
  1018. X
  1019. X#ifdef ENROLL
  1020. X  if (process) {
  1021. X    printf("\n") ;
  1022. X    printf("Process filename\n") ;
  1023. X    printf("\t\t This command will repeatedly load races from filename,\n") ;
  1024. X    printf("\t\t and then try to enroll them.  You can thus easily \n") ;
  1025. X    printf("\t\t enroll tens of players at once.  \n") ;
  1026. X    }
  1027. X#endif
  1028. X
  1029. X  if (save) {
  1030. X    printf("\n") ;
  1031. X    printf("Save [filename]\n") ;
  1032. X    printf("\t\t This command will save your race to the file specified in\n");
  1033. X    printf("\t\t the optional first argument, or to the file \"%s\"\n", 
  1034. X       (race.filename[0] ? race.filename : SAVETO)) ;
  1035. X    printf("\t\t if no argument is given.\n") ;
  1036. X    }
  1037. X
  1038. X  if (send) {
  1039. X    printf("\n") ;
  1040. X    printf("Send\n") ;
  1041. X    printf("\t\t This command will send your race to God, (%s).\n", TO) ;
  1042. X    printf("\t\t It will not work unless you have spent all your points.\n") ;
  1043. X    }
  1044. X
  1045. X  if (quit) {
  1046. X    printf("\n") ;
  1047. X    printf("Quit\n") ;
  1048. X    printf("\t\t This command will prompt you to save your work if you\n") ;
  1049. X    printf("\t\t haven't already, and then exit this program.\n") ;
  1050. X    }
  1051. X
  1052. X  printf("\n") ;
  1053. X  }
  1054. X
  1055. X
  1056. X/*
  1057. X * Return non-zero on failure, zero on success. */
  1058. Xint load_from_file(g)
  1059. X     FILE *g ;
  1060. X{
  1061. X  int i ;
  1062. X  char buf[80], from_address[80] ;
  1063. X
  1064. X#define FSCANF(file, format, variable) \
  1065. X  if (EOF == fscanf((file), (format), (variable))) \
  1066. X    goto premature_end_of_file
  1067. X  
  1068. X  do {
  1069. X    FSCANF(g, " %s", buf) ;
  1070. X    if (0 == strcmp(buf, "From:")) {
  1071. X      FSCANF(g, " %s", buf) ;
  1072. X      strcpy(from_address, buf) ;
  1073. X      }
  1074. X    }
  1075. X  while (strcmp(buf, START_RECORD_STRING)) ;
  1076. X
  1077. X  race.status = STATUS_BALANCED ;
  1078. X  FSCANF(g, " %s", race.address) ;
  1079. X  if (from_address[0])
  1080. X    strcpy(race.address, from_address) ;
  1081. X  FSCANF(g, " %s", race.name) ;
  1082. X  FSCANF(g, " %s", race.password) ;
  1083. X  FSCANF(g, " %d", &race.priv_type) ;
  1084. X  FSCANF(g, " %d", &race.home_planet_type) ;
  1085. X  FSCANF(g, " %d", &race.race_type) ;
  1086. X  if (race.race_type == R_NORMAL)
  1087. X    normal() ;
  1088. X  else
  1089. X    metamorph() ;
  1090. X  for (i=FIRST_ATTRIBUTE; i<=LAST_ATTRIBUTE; i++)
  1091. X    FSCANF(g, " %lf", &race.attr[i]) ;
  1092. X  fix_up_iq() ;
  1093. X  for (i=FIRST_SECTOR_TYPE;  i<=LAST_SECTOR_TYPE; i++)
  1094. X    FSCANF(g, " %lf", &race.compat[i]) ;
  1095. X  do {
  1096. X    FSCANF(g, " %s", buf) ;
  1097. X    }
  1098. X  while (strcmp(buf, END_RECORD_STRING)) ;
  1099. X  return 0 ;
  1100. X premature_end_of_file:
  1101. X  printf("Error: premature end of file.\n") ;
  1102. X  return 1 ;
  1103. X  }
  1104. X
  1105. X/*
  1106. X * Return non-zero on failure, zero on success. */
  1107. Xstatic int load_from_filename(filename)
  1108. X     char *filename ;
  1109. X{
  1110. X  int ret ;
  1111. X  FILE *f = fopen(filename, "r") ;
  1112. X
  1113. X  if (f == NULL) {
  1114. X    printf("Unable to open file \"%s\".\n", filename) ;
  1115. X    return 1 ;
  1116. X    }
  1117. X  ret = load_from_file(f) ;
  1118. X  fclose(f) ;
  1119. X  return ret ;
  1120. X  }
  1121. X
  1122. Xvoid load(argc, argv)
  1123. X     int argc ;
  1124. X     char *argv[] ;
  1125. X{
  1126. X  char c[64] ;
  1127. X  int i ;
  1128. X
  1129. X  bcopy(&race, &last, sizeof(struct x)) ;
  1130. X  if (altered) {
  1131. X    i = Dialogue("This race has been altered; load anyway?", "yes", "no", 0) ;
  1132. X    if (i == 1)
  1133. X      return ;
  1134. X    }
  1135. X  if (argc > 1)
  1136. X    strcpy(c, argv[1]) ;
  1137. X  else if (! race.filename[0])
  1138. X    strcpy(c, SAVETO) ;
  1139. X  if (load_from_filename(c)) {
  1140. X    printf("Load from file \"%s\" failed.\n", c) ;
  1141. X    bcopy(&last, &race, sizeof(struct x)) ;
  1142. X    }
  1143. X  else {
  1144. X    printf("Loaded race from file \"%s\".\n", c) ;
  1145. X    strcpy(race.filename, c) ;
  1146. X    altered = 0 ;
  1147. X    changed = 1 ;
  1148. X    }
  1149. X  }
  1150. X
  1151. Xint modify(argc, argv)
  1152. X     int argc ;
  1153. X     char *argv[] ;
  1154. X{
  1155. X  int i, j ;
  1156. X  static char *help_strings[2] = {NULL, "modify"} ;
  1157. X  double f ;
  1158. X
  1159. X  if (argc < 3) {
  1160. X    help(2, help_strings) ;
  1161. X    return -1 ;
  1162. X    }
  1163. X  j = strlen(argv[1]) ;
  1164. X
  1165. X  bcopy(&race, &last, sizeof(struct x)) ;
  1166. X
  1167. X  /*
  1168. X   * Check for attribute modification: */
  1169. X  for (i = FIRST_ATTRIBUTE; i<=LAST_ATTRIBUTE; i++)
  1170. X    if (! strncasecmp(argv[1], attr[i].print_name, j)) {
  1171. X      if (attr[i].is_integral == 2) {    /* Boolean attribute. */
  1172. X    j = strlen(argv[2]) ;
  1173. X    if (! strncasecmp(argv[2], "no", j))
  1174. X      f = 0.0 ;
  1175. X    else if (! strncasecmp(argv[2], "yes", j))
  1176. X      f = 1.0 ;
  1177. X    else
  1178. X      f = atof(argv[2]) ;
  1179. X    }
  1180. X      else
  1181. X    f = atof(argv[2]) ;
  1182. X      
  1183. X      race.attr[i] = f ;
  1184. X      fix_up_iq() ;
  1185. X      return critique_modification() ;
  1186. X      }
  1187. X
  1188. X  /*
  1189. X   * Check for name modification:  */
  1190. X  if (! strncasecmp(argv[1], "name", j)) {
  1191. X    strcpy(race.name, argv[2]) ;
  1192. X    return critique_modification() ;
  1193. X    }
  1194. X
  1195. X#ifdef ENROLL
  1196. X  /*
  1197. X   * Check for from-address modification:  */
  1198. X  if (! strncasecmp(argv[1], "from:", j)) {
  1199. X    strcpy(race.address, argv[2]) ;
  1200. X    return critique_modification() ;
  1201. X    }
  1202. X  /*
  1203. X   * Check for privilege modification:  */
  1204. X  if (! strncasecmp(argv[1], "privilege", j)) {
  1205. X    j = strlen(argv[2]) ;
  1206. X    for (i = FIRST_PRIV_TYPE; i<=LAST_PRIV_TYPE; i++)
  1207. X      if (! strncasecmp(argv[2], priv_print_name[i], j)) {
  1208. X    race.priv_type = i ;
  1209. X    return critique_modification() ;
  1210. X    }
  1211. X    race.priv_type = atof(argv[2]) ;
  1212. X    return critique_modification() ;
  1213. X    }
  1214. X#endif
  1215. X
  1216. X  /*
  1217. X   * Check for planet modification:  */
  1218. X  if (! strncasecmp(argv[1], "planet", j)) {
  1219. X    j = strlen(argv[2]) ;
  1220. X    for (i = FIRST_HOME_PLANET_TYPE; i<=LAST_HOME_PLANET_TYPE; i++)
  1221. X      if (! strncasecmp(argv[2], planet_print_name[i], j)) {
  1222. X    if (i == H_JOVIAN) {
  1223. X      bzero(race.compat, sizeof(race.compat)) ;
  1224. X      race.compat[S_GAS] = 100.0 ;
  1225. X      }
  1226. X    else if (race.home_planet_type == H_JOVIAN) {
  1227. X      race.compat[S_PLATED] = 100.0 ;
  1228. X      race.compat[S_GAS] = 0.0 ;
  1229. X      }
  1230. X    race.home_planet_type = i ;
  1231. X    return critique_modification() ;
  1232. X    }
  1233. X    printf("\"%s\" is not a valid planet type.\n", argv[2]) ;
  1234. X    return -1 ;
  1235. X    }
  1236. X
  1237. X  /*
  1238. X   * Check for password modification:  */
  1239. X  if (! strncasecmp(argv[1], "password", j)) {
  1240. X    strcpy(race.password, argv[2]) ;
  1241. X    return critique_modification() ;
  1242. X    }
  1243. X
  1244. X  /*
  1245. X   * Check for race modification:  */
  1246. X  if (! strncasecmp(argv[1], "race", j)) {
  1247. X    j = strlen(argv[2]) ;
  1248. X    for (i = FIRST_RACE_TYPE; i<=LAST_RACE_TYPE; i++)
  1249. X      if (! strncasecmp(argv[2], race_print_name[i], j)) {
  1250. X    if (i == R_METAMORPH) {
  1251. X      race.attr[ABSORB] = 1 ;
  1252. X      race.attr[PODS] = 1 ;
  1253. X      race.attr[COL_IQ] = 1 ;
  1254. X      race.attr[SEXES] = 1 ;
  1255. X      race.attr[A_IQ] = DEFAULT_MESO_IQ_LIMIT ;
  1256. X      metamorph() ;
  1257. X      }
  1258. X    else {
  1259. X      race.attr[ABSORB] = 0 ;
  1260. X      race.attr[PODS] = 0 ;
  1261. X      race.attr[COL_IQ] = 0 ;
  1262. X      race.attr[SEXES] = 2 ;
  1263. X      race.attr[A_IQ] = 125 ;
  1264. X      normal() ;
  1265. X      }
  1266. X    race.race_type = i ;
  1267. X    return critique_modification() ;
  1268. X    }
  1269. X    printf("\"%s\" is not a valid race type.\n", argv[2]) ;
  1270. X    return -1 ;
  1271. X    }
  1272. X
  1273. X
  1274. X  /*
  1275. X   * Check for sector_type modification: */
  1276. X  for (i = FIRST_SECTOR_TYPE; i<=LAST_SECTOR_TYPE; i++)
  1277. X#ifndef ENROLL
  1278. X    if (i == S_PLATED)
  1279. X      continue ;    /* Players should never need to modify this. */
  1280. X    else
  1281. X#endif
  1282. X    if (! strncasecmp(argv[1], sector_print_name[i], j)) {
  1283. X      race.compat[i] = atof(argv[2]) ;
  1284. X      return critique_modification() ;
  1285. X      }
  1286. X  
  1287. X  /*
  1288. X   * Print error */
  1289. X  printf("\n") ;
  1290. X  printf("Modify: didn't recognize the first argument \"%s\".\n", argv[1]) ;
  1291. X  printf("Type \"help modify\" for more information on modify.\n") ;
  1292. X  printf("\n") ;
  1293. X  return -1 ;
  1294. X  }
  1295. X
  1296. Xvoid print_to_file(f, verbose)
  1297. X     FILE *f ;
  1298. X     int verbose ;
  1299. X{
  1300. X#define FPRINTF if (verbose) fprintf
  1301. X  int i ;
  1302. X
  1303. X#ifdef ENROLL
  1304. X  FPRINTF(f, "From:") ;
  1305. X#endif
  1306. X  if (! verbose) {
  1307. X    fprintf(f, START_RECORD_STRING) ;
  1308. X    fprintf(f, " %s", race.address) ;
  1309. X    }
  1310. X#ifdef ENROLL
  1311. X  else
  1312. X    fprintf(f, " %s", race.address) ;
  1313. X#endif
  1314. X  FPRINTF(f, "\n") ;
  1315. X
  1316. X  FPRINTF(f, "Name:") ;
  1317. X  fprintf(f, " %16.16s", race.name) ;
  1318. X  FPRINTF(f, "\n") ;
  1319. X
  1320. X  FPRINTF(f, "Password:") ;
  1321. X  fprintf(f, " %12.12s", race.password) ;
  1322. X  FPRINTF(f, "\n") ;
  1323. X
  1324. X#ifdef ENROLL
  1325. X  FPRINTF(f, "Privileges:") ;
  1326. X  if (verbose)
  1327. X    fprintf(f, "%11.11s", priv_print_name[race.priv_type]) ;
  1328. X  else
  1329. X#endif
  1330. X  if (! verbose)
  1331. X    fprintf(f, " %d", race.priv_type) ;
  1332. X#ifdef ENROLL
  1333. X  FPRINTF(f, "\n") ;
  1334. X#endif
  1335. X
  1336. X  FPRINTF(f, "Home Planet:") ;
  1337. X  if (verbose)
  1338. X    fprintf(f, " %9.9s", planet_print_name[race.home_planet_type]) ;
  1339. X  else
  1340. X    fprintf(f, " %d", race.home_planet_type) ;
  1341. X  FPRINTF(f, "  [%4d]\n", cost.home_planet_type) ;
  1342. X
  1343. X  FPRINTF(f, "Race type:") ;
  1344. X  if (verbose)
  1345. X    fprintf(f, "%12.12s", race_print_name[race.race_type]) ;
  1346. X  else
  1347. X    fprintf(f, " %d", race.race_type) ;
  1348. X  FPRINTF(f, "  [%4d]\n", cost.race_type) ;
  1349. X  FPRINTF(f, "\n") ;
  1350. X
  1351. X  FPRINTF(f, "Attributes:\n") ;
  1352. X  for (i=FIRST_ATTRIBUTE; i<=LAST_ATTRIBUTE; i++) {
  1353. X    FPRINTF(f, "%13.13s:", attr[i].print_name) ;
  1354. X    if (verbose && (attr[i].is_integral == 2))
  1355. X      fprintf(f, (race.attr[i] > 0.0) ? "  yes   " : "   no   ") ;
  1356. X    else
  1357. X      fprintf(f, " %7.2f", race.attr[i]) ;
  1358. X    FPRINTF(f, "  [%4.0f]", cost.attr[i]) ;
  1359. X    FPRINTF(f, (i & 01) ? "\n" : "     ") ;
  1360. X    }
  1361. X  if (i & 01)
  1362. X    FPRINTF(f, "\n") ;
  1363. X  FPRINTF(f, "\n") ;
  1364. X
  1365. X  FPRINTF(f, "Sector Types:    %2d     [%4d]\n", 
  1366. X      race.n_sector_types, cost.n_sector_types) ;
  1367. X  for (i=FIRST_SECTOR_TYPE;  i<=LAST_SECTOR_TYPE; i++) {
  1368. X    FPRINTF(f, "%13.13s: ", sector_print_name[i]) ;
  1369. X    fprintf(f, " %3.0f", race.compat[i]) ;
  1370. X    FPRINTF(f, "%%   %c[%4.0f]", 
  1371. X        (planet_compat_cov[race.home_planet_type][i] == 1.0) ? '*' : ' ',
  1372. X        cost.compat[i]) ;
  1373. X    FPRINTF(f, (i & 01) ? "\n" : "     ") ;
  1374. X    }
  1375. X
  1376. X  if (! verbose)
  1377. X    fprintf(f, END_RECORD_STRING) ;
  1378. X  FPRINTF(f, "\n") ;
  1379. X  FPRINTF(f, "Points left: %d          Previous value: %d\n", 
  1380. X      npoints, last_npoints) ;
  1381. X  fprintf(f, "\n") ;
  1382. X#undef FPRINTF
  1383. X  }
  1384. X
  1385. Xstatic int print_to_filename(filename, verbose)
  1386. X     char *filename ;
  1387. X     int verbose ;
  1388. X{
  1389. X  FILE *f = fopen(filename, "w") ;
  1390. X
  1391. X  if (f == NULL) {
  1392. X    printf("Unable to open file \"%s\".\n", filename) ;
  1393. X    return 0 ;
  1394. X    }
  1395. X  print_to_file(f, verbose) ;
  1396. X  fclose(f) ;
  1397. X  return 1 ;
  1398. X  }
  1399. X
  1400. Xvoid print(argc, argv)
  1401. X     int argc ;
  1402. X     char *argv[] ;
  1403. X{
  1404. X  if (argc == 1)
  1405. X    print_to_file(stdout, 1) ;
  1406. X  else if (print_to_filename(argv[1], 1))
  1407. X    printf("Printed race to file \"%s\".\n", argv[1]) ;
  1408. X  }
  1409. X
  1410. Xvoid save(argc, argv)
  1411. X     int argc ;
  1412. X     char *argv[] ;
  1413. X{
  1414. X  if (argc > 1)
  1415. X    strcpy(race.filename, argv[1]) ;
  1416. X  else if (! race.filename[0])
  1417. X    strcpy(race.filename, SAVETO) ;
  1418. X  if (print_to_filename(race.filename, 0)) {
  1419. X    printf("Saved race to file \"%s\".\n", race.filename) ;
  1420. X    altered = 0 ;
  1421. X    }
  1422. X  }
  1423. X
  1424. Xvoid send(argc, argv)
  1425. X     int argc ;
  1426. X     char *argv[] ;
  1427. X{
  1428. X  FILE *f ;
  1429. X  char sys[64] ;
  1430. X
  1431. X  bcopy(&race, &last, sizeof(struct x)) ;
  1432. X  if (critique_to_file(stdout, 1, IS_PLAYER))
  1433. X    return ;
  1434. X
  1435. X  f = fopen(TMP, "w") ;
  1436. X  if (f == NULL) {
  1437. X    printf("Unable to open file \"%s\".\n", TMP) ;
  1438. X    return ;
  1439. X    }
  1440. X  fprintf(f, "To: %s\n", race.address) ;
  1441. X  fprintf(f, "Subject: %s Race Submission\n", GAME) ;
  1442. X  fprintf(f, "\n") ;
  1443. X  print_to_file(f, 0) ;
  1444. X  fclose(f) ;
  1445. X
  1446. X  printf("Sending to %s via %s...", TO, MAILER) ;
  1447. X  fflush(stdout) ;
  1448. X  sprintf(sys, "cat %s | %s %s", TMP, MAILER, TO) ;
  1449. X  system(sys) ;
  1450. X  printf("done.\n") ;
  1451. X  }
  1452. X
  1453. Xint Dialogue(prompt, va_alist)
  1454. X     char *prompt;
  1455. X         va_dcl 
  1456. X{
  1457. X    va_list ap;
  1458. X  char input[128] ;
  1459. X  char *carg;
  1460. X    int len, i, argc = 0 ;
  1461. X  int init = 0;
  1462. X    char *argv[16] ;
  1463. X  printf("%s", prompt) ;
  1464. X  va_start(ap);
  1465. X    while ((carg = va_arg(ap, char *))!=0) {
  1466. X    if (!init) {
  1467. X            printf(" [%s", carg) ;
  1468. X            init = 1;
  1469. X        } else {
  1470. X            printf("/%s", carg);
  1471. X        }
  1472. X    argv[argc++] = carg++ ;
  1473. X  }
  1474. X    va_end(ap);
  1475. X  if (argc)
  1476. X    printf("]") ;
  1477. X  printf("> ") ;
  1478. X  while (1) {
  1479. X    fgets(input, 128, stdin) ;
  1480. X    if (argc == 0)
  1481. X      return -1 ;
  1482. X    len = strlen(input) - 1 ;
  1483. X    
  1484. X    for (i = 0; i < argc; i++)
  1485. X      if (! strncasecmp(argv[i], input, len))
  1486. X    return i ;
  1487. X    /*
  1488. X     * The input did not match any of the valid responses: */
  1489. X    printf("Please enter ") ;
  1490. X    for (i = 0; i < argc-1; i++)
  1491. X      printf("\"%s\", ", argv[i]) ;
  1492. X    printf("or \"%s\"> ", argv[i]) ;
  1493. X    }
  1494. X  }
  1495. X
  1496. X
  1497. Xvoid quit(argc, argv)
  1498. X     int argc ;
  1499. X     char *argv[] ;
  1500. X{
  1501. X  int i ;
  1502. X
  1503. X  if (please_quit)  /* This could happen if ^c is hit while here. */
  1504. X    exit(0) ;
  1505. X  please_quit = 1 ;
  1506. X  if (altered) {
  1507. X    i = Dialogue("Save this race before quitting?", "yes", "no", "abort", 0) ;
  1508. X    if (i == 0)   
  1509. X      save(1, NULL) ;
  1510. X    else if (i == 2)
  1511. X      please_quit = 0 ;
  1512. X    }
  1513. X  }
  1514. X
  1515. X
  1516. X
  1517. Xstatic void control_c_handler()
  1518. X{
  1519. X  printf("\n") ;
  1520. X  exit(0) ;
  1521. X  }
  1522. X
  1523. X
  1524. X/**************
  1525. X * This function merely takes the space-parsed command line and executes
  1526. X * one of the commands above.
  1527. X */
  1528. Xvoid execute(argc, argv)
  1529. X     int argc ;
  1530. X     char *argv[] ;
  1531. X{
  1532. X  int i ;
  1533. X
  1534. X#if 0
  1535. X  for (i=0; i < argc; i++)
  1536. X    printf("%d: \"%s\"\n", i, argv[i]) ;
  1537. X#endif
  1538. X  if (argc == 0) {
  1539. X    printf("Type \"help\" for help.\n") ;
  1540. X    return ;
  1541. X    }
  1542. X  i = strlen(argv[0]) ;
  1543. X#ifdef ENROLL
  1544. X  if      (! strncasecmp(argv[0], "enroll", i))
  1545. X    enroll(argc, argv) ;
  1546. X  else
  1547. X#endif
  1548. X  if      (! strncasecmp(argv[0], "help", i))
  1549. X    help(argc, argv) ;
  1550. X  else if (! strncasecmp(argv[0], "load", i))
  1551. X    load(argc, argv) ;
  1552. X  else if (! strncasecmp(argv[0], "modify", i))
  1553. X    modify(argc, argv) ;
  1554. X  else if (! strncasecmp(argv[0], "print", i))
  1555. X    print(argc, argv) ;
  1556. X#ifdef ENROLL
  1557. X  else if (! strncasecmp(argv[0], "process", i))
  1558. X    process(argc, argv) ;
  1559. X#endif
  1560. X  else if (! strncasecmp(argv[0], "save", i))
  1561. X    save(argc, argv) ;
  1562. X  else if (! strncasecmp(argv[0], "send", i))
  1563. X    send(argc, argv) ;
  1564. X  else if (! strncasecmp(argv[0], "quit", i))
  1565. X    quit(argc, argv) ;
  1566. X  else {
  1567. X    printf("Unknown command \"%s\".  Type \"help\" for help.\n", argv[0]) ;
  1568. X    return ;
  1569. X    }
  1570. X  }
  1571. X
  1572. X
  1573. X
  1574. X
  1575. X/**************
  1576. X * Here is the main loop, where I print the command prompt, parse it into
  1577. X * words using spaces as the separator, and call execute.  Level is the
  1578. X * number of higher level modify print loops above this one.  It will
  1579. X * always be zero for player racegens.
  1580. X */
  1581. Xvoid modify_print_loop(level)
  1582. X     int level ;
  1583. X{
  1584. X  char buf[128], *com, *args[4] ;
  1585. X  int i ;
  1586. X
  1587. X  while (! please_quit) {
  1588. X    last_npoints = npoints ;
  1589. X    npoints = STARTING_POINTS - cost_of_race() ;
  1590. X
  1591. X    if (changed) {
  1592. X      print_to_file(stdout, 1) ;
  1593. X      changed = 0 ;
  1594. X      }
  1595. X#ifdef ENROLL
  1596. X    printf("%s [enroll/help/load/modify/print/process/save/send/quit]> ",
  1597. X       level ? "Fix" : "Command") ;
  1598. X#else
  1599. X    printf("Command [help/load/modify/print/save/send/quit]> ") ;
  1600. X#endif
  1601. X    fflush(stdout) ;
  1602. X    com = fgets(buf, 128, stdin) ;
  1603. X    buf[strlen(buf)-1] = '\0' ;
  1604. X
  1605. X    for (i=0; i<4; i++) {
  1606. X      while (*com && (*com == ' '))   
  1607. X    *com++ = '\0' ;
  1608. X      if (! *com)
  1609. X    break ;
  1610. X      args[i] = com ;
  1611. X      while (*com && (*com != ' '))   
  1612. X    com++ ;
  1613. X      }
  1614. X    execute(i, args) ;
  1615. X    }
  1616. X  printf("\n") ;
  1617. X  }
  1618. X
  1619. X
  1620. X/**************
  1621. X * Print out initial info and then call modify-print loop.
  1622. X */
  1623. Xint main(argc, argv)
  1624. X     int argc ;
  1625. X     char *argv[] ;
  1626. X{
  1627. X  signal(SIGINT, control_c_handler) ;
  1628. X  signal(SIGQUIT, control_c_handler) ;
  1629. X  initialize() ;
  1630. X  printf("\n") ;
  1631. X  printf("\n") ;
  1632. X  printf("Galactic Bloodshed Race Generator %s\n", GBVERSION) ;
  1633. X  printf("\n") ;
  1634. X  printf("Finished races will be sent to %s.\n", TO) ;
  1635. X  printf("***************************************************************\n") ;
  1636. X  printf("Game: %s, using %s\n", GAME, GB_VERSION) ;
  1637. X  printf("Address: %s\n", LOCATION) ;
  1638. X  printf("God: %s\n", MODERATOR) ;
  1639. X  printf("Starts: %s\n", STARTS) ;
  1640. X  printf("Stars: %s; Players: %s\n", STARS, PLAYERS) ;
  1641. X  printf("Any race may be refused or modified by God for any reason!\n") ;
  1642. X  printf("\n") ;
  1643. X  printf("DEADLINE: %s\n", DEADLINE) ;
  1644. X  printf("***************************************************************\n") ;
  1645. X  printf("Update schedule:\n") ;
  1646. X  printf("%s\n", UPDATE_SCH) ;
  1647. X  printf("\n") ;
  1648. X  printf("If you cannot make this update schedule, do NOT send in a race!\n") ;
  1649. X  printf("***************************************************************\n") ;
  1650. X  printf(OTHER_STUFF) ;
  1651. X  printf("\n") ;
  1652. X  Dialogue("Hit return", 0) ;
  1653. X  modify_print_loop(0) ;
  1654. X
  1655. X  return 0 ;
  1656. X  }
  1657. END_OF_FILE
  1658. if test 39848 -ne `wc -c <'utils/racegen.c'`; then
  1659.     echo shar: \"'utils/racegen.c'\" unpacked with wrong size!
  1660. fi
  1661. # end of 'utils/racegen.c'
  1662. fi
  1663. echo shar: End of archive 1 \(of 21\).
  1664. cp /dev/null ark1isdone
  1665. MISSING=""
  1666. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  1667.     if test ! -f ark${I}isdone ; then
  1668.     MISSING="${MISSING} ${I}"
  1669.     fi
  1670. done
  1671. if test "${MISSING}" = "" ; then
  1672.     echo You have unpacked all 21 archives.
  1673.     echo "Now type './buildfiles.sh'"
  1674.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1675. else
  1676.     echo You still need to unpack the following archives:
  1677.     echo "        " ${MISSING}
  1678. fi
  1679. ##  End of shell archive.
  1680. exit 0
  1681.