[comp.sources.games] v10i001: gb3 - Galactic Bloodshed, an empire-like war game [Ver. 2.0], Part01/14

billr@saab.CNA.TEK.COM (Bill Randle) (06/02/90)

Submitted-by: VANCLEEF@mps.ohio-state.edu
Posting-number: Volume 10, Issue 1
Archive-name: gb3/Part01
Supersedes: GB2: Volume 7, Issue 44-51

	[This is the latest and greatest version of Galactic Bloodshed.
	 This version has added networking support with the game
	 split into a client and a server (ala TinyMud). It will run
	 under 4.2bsd and 4.3bsd Unixes or their variants (e.g. Sun OS
	 and Ultrix); other versions are not guaranteed to work.   -br]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 14)."
# Contents:  README MANIFEST Docs README_ORIG client server
#   server/build.c server/capture.c
# Wrapped by billr@saab on Fri Jun  1 11:53:30 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2960 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X		Galactic Bloodshed 2.0
X
X   Galactic Bloodshed 1.3.1 was the first version of the game where
Xthe networking is taken advantage of. I would like to thank the
Xpeople at CMU (see TinyMUD_copyright.h) for providing such an efficient
Xinterface. I tried to exploit this to the fullest for this version.
X
X   The code is divided into two parts, GB_server
Xand GB_client. Most of the user playing the game will
Xjust need the client, since the server is run at the game site and
Xmanaged by the host there. Game documentation is in the subdirectory
XDocs.
X
X   If you wish to host a GB game, you must have GB_server, GB_docs
Xand GB_client. After unsharing all the files, you can compile and
Xlink them by doing 'make' from the top level directory.
XThe Makefile is set up for 4.3 BSD Unix, if you are running
Xon a different operating system, you may need to change the Makefile
Xto suit your system. You should also check and perhaps edit the
Xfiles server/config.h and server/files.h.
X
X   Assuming all goes well, you should have several programs in the
Xserver's directory, and one program in the client's directory (GB_client).
XIn the server's directory:
X	GB_daemon
X	GB_enroll
X	GB_server
X	makeuniv
X
X'GB_daemon' is the program which wakes up every few hours and send the
Xupdate password (specified by DAEMON_PASSWORD) to the client which
Xthen tells the server to do an update. The default update time is 4 hours, 
Xbut you can change that with 'GB_daemon <hours between updates>'. It is a 
Xgood idea to make your update times a factor of 24 hours. If you want to
Xforce an update just do 'GB_doturn' by itself.
X
XPlayers cannot enroll by themselves in this version. The game's host
Xmust do that by running 'GB_enroll' and following the instructions. It
Xis a good idea to bring the game down for this (log in as a God status
Xplayer and do '@@shutdown'). Always make player #1 (the first one
Xenrolled God status, as many game functions default to player 1).
X
XBefore starting a game you must create a universe for your users to play in.
XDo 'makeuniv' and follow the instructions.
X
XOnce you are set up you can start the program with 'GB_server <port>'. You
Xmust specify the port that you are going allow communications. Choose the 
Xnumber '2010' since the client looks it up by default.
X
XAlso, be careful about setting up your default paths correctly. Edit the
Xfiles "files.h" and Makefile.
X
XGood luck,
X
XGarrett Warren van Cleef
Xvancleef@pooh.caltech.edu
X4/11/90
X
X
XI made some changes to the server code so that it would compile and
Xexecute on a 4.2bsd Unix (Sun OS 3.5). I also added #ifdef's where
Xnecessary for non-ANSI C compilers and cleaned up the Makefiles,
Xincluding adding defines for host and port via the Makefile and
Xthe creation of a top level Makefile to compile the client and
Xserver.
X
XBecause of these changes this posting no longer matches the source
Xavailable via ftp (scam.Berkeley.EDU), I am setting the PATCHLEVEL
Xat 1.
X
XBill Randle
Xbillr@saab.CNA.TEK.COM
X6/1/90
END_OF_FILE
if test 2960 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(5603 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X Docs                       1	
X Docs/actionpoints.doc     13	
X Docs/allocate.doc         14	
X Docs/announce.doc          5	
X Docs/assault.doc          12	
X Docs/autoreport.doc       14	
X Docs/blocks.doc           12	
X Docs/build.doc             7	
X Docs/capitol.doc          13	
X Docs/capture.doc          13	
X Docs/colonies.doc         14	
X Docs/colony.doc           11	
X Docs/cs.doc               14	
X Docs/daemon.doc           14	
X Docs/declare.doc          11	
X Docs/dock.doc             14	
X Docs/enslave.doc          12	
X Docs/examine.doc          14	
X Docs/explore.doc          14	
X Docs/fire.doc              9	
X Docs/fix.doc              14	
X Docs/give.doc             14	
X Docs/god.doc              14	
X Docs/help.doc             12	
X Docs/info.doc             14	
X Docs/land.doc             13	
X Docs/launch.doc           14	
X Docs/load.doc             13	
X Docs/make.doc             14	
X Docs/makeuniv.doc         14	
X Docs/map.doc              11	
X Docs/message.doc          12	
X Docs/mobilize.doc         13	
X Docs/modify.doc           13	
X Docs/move.doc             13	
X Docs/name.doc             14	
X Docs/newfire.doc          11	
X Docs/newrepair.doc        13	
X Docs/news.doc             12	
X Docs/notes.doc            10	
X Docs/oldfire.doc          10	
X Docs/oldgoodies.doc       11	
X Docs/oldnews.doc          12	
X Docs/orbit.doc            12	
X Docs/order.doc            10	
X Docs/page.doc             14	
X Docs/power.doc            14	
X Docs/profile.doc           8	
X Docs/quit.doc             14	
X Docs/races.doc            11	
X Docs/read.doc             13	
X Docs/relation.doc         14	
X Docs/report.doc           14	
X Docs/scope.doc            13	
X Docs/scrap.doc            14	
X Docs/ship.doc             14	
X Docs/ships.doc             6	
X Docs/stock.doc            14	
X Docs/survey.doc           12	
X Docs/tactical.doc         13	
X Docs/technology.doc       13	
X Docs/telegram.doc         14	
X Docs/time.doc             14	
X Docs/toggle.doc           14	
X Docs/toxicity.doc         14	
X Docs/transfer.doc         14	
X Docs/undock.doc           14	
X Docs/vessels.doc           3	
X Docs/who.doc              14	
X Docs/zoom.doc              2	
X MANIFEST                   1	This shipping list
X Makefile                  13	
X README                     1	
X README_ORIG                1	
X client                     1	
X client/GB_client.c         9	
X client/GB_copyright.h     14	
X client/Makefile           14	
X client/TinyMUD_copyright.h 13	
X client/arrays.h           11	
X client/client.h           14	
X client/keyboard.c         11	
X client/map.c              13	
X client/orbit.c            12	
X client/patchlevel.h       14	
X client/ultrix_cpt.h       13	
X client/util.c             13	
X client/wrap.c             13	
X server                     1	
X server/GB_copyright.h     14	
X server/GB_server.c         2	
X server/Makefile            9	
X server/Makefile.old       11	
X server/TinyMUD_copyright.h 13	
X server/VN.c                7	
X server/autoreport.c       12	
X server/autoshoot.c         9	
X server/b.c                14	
X server/buffers.h          14	
X server/build.c             1	
X server/capitol.c          12	
X server/capture.c           1	
X server/config.h           14	
X server/cs.c                9	
X server/daemon.c           12	
X server/daemon.dat         14	
X server/declare.c          10	
X server/docommand.c        14	
X server/doplanet.c          3	
X server/dosector.c          8	
X server/doship.c            2	
X server/doturn.c            8	
X server/doturn.h           13	
X server/enrol.c             6	
X server/enslave.c          11	
X server/exam.dat            5	
X server/examine.c          12	
X server/explore.c           9	
X server/files.c            14	
X server/files.h            13	
X server/files_rw.c         13	
X server/files_rw_update.c  13	
X server/files_shl.c         8	
X server/fire.c              5	
X server/fix.c               6	
X server/gdb_guardian.c     14	
X server/get4args.c         14	
X server/getplace.c          9	
X server/guardian.c         14	
X server/interface.h        14	
X server/land.c              4	
X server/launch.c           10	
X server/list.c             14	
X server/load.c              4	
X server/makeplanet.c        5	
X server/makeuniv.c          8	
X server/map.c              10	
X server/max.c              12	
X server/misc.c             14	
X server/mobiliz.c          12	
X server/more.c             12	
X server/move.c              5	
X server/moveplanet.c       12	
X server/moveship.c          7	
X server/name.c              4	
X server/orbit.c             7	
X server/order.c             3	
X server/patchlevel.h       14	
X server/perm.c             13	
X server/planet.list         4	
X server/power.c            11	
X server/power.h            14	
X server/prof.c              8	
X server/races.h            12	
X server/rand.c             13	
X server/read_teleg.c       13	
X server/relation.c         12	
X server/rst.c               7	
X server/scrap.c             9	
X server/ship.dat           13	
X server/shipdata.h         11	
X server/ships.h             3	
X server/shlmisc.c          10	
X server/shootblast.c        6	
X server/sizes.c            13	
X server/survey.c            8	
X server/tech.c             12	
X server/teleg_send.c       13	
X server/telegram.c         11	
X server/toggle.c           12	
X server/toxicity.c         13	
X server/traverse.c         14	
X server/tweakables.h       10	
X server/ultrix_cpt.h       13	
X server/vars.h             10	
X server/welcome.txt        13	
X server/zoom.c             13	
END_OF_FILE
if test 5603 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test ! -d 'Docs' ; then
    echo shar: Creating directory \"'Docs'\"
    mkdir 'Docs'
fi
if test -f 'README_ORIG' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README_ORIG'\"
else
echo shar: Extracting \"'README_ORIG'\" \(6261 characters\)
sed "s/^X//" >'README_ORIG' <<'END_OF_FILE'
X
X	This is a game of interstellar exploration/conquest.  By the time I
Xrealized there really wasn't going to be much fighting going on in the game, I
Xwas so in love with the title that I just couldn't change it...
X
X	Players begin the game as members of a randomly generated race, with
Xattributes (intelligence, birth rate, size, metabolism, etc) that affect
Xdevelopment later.  Each turn, population will migrate to unpopulated areas
Xof the planet.
X
X	Currently I have the following features:
X
X	Exploration: players can build many types of ships with which to 
Xcolonize other planets.
X	Terraforming: planets have atmospheres, composed of different amounts
Xof gases.  Players can build machines to alter the atmosphere to one more
Xsuited to their race.
X	Von Neumann machines: This is a ship-type that can be built.  It
Xexists to reproduce itself using whatever resources are available, and can be
Xuseful to send to other players.  I got this idea after reading _The Forge of
XGod_.
X	Co-existance: There are several types of terrain: land, ice, ocean,
Xmountainous, and gas(gasgiant).  Each player has a type which he preferrs; if
Xone race's preference differs from another, both races can co-exist on the same
Xplanet.
X	Communication: players can communicate with each other, but only if
Xthey sacrifice valuable resources to translate another language.
X	Combat: If the above breaks down.
X
X
X	The game is not (of course) complete, but it's fixed up enough to post
XI think.  It runs pretty good on 4.3 and 4.2, but as our versions of
Xboth here are a little funky, it may require some tweaking before it runs to
Xa game keeper's satisfaction.
X
X
X
X
XBUGS:
X
X	Ships with "*" before their names (shipdata.h) don't work as yet.
Xdon't build them.
X	Probably shouldn't have used a square grid implementation for
Xplanet maps, but I wanted the simplest thing possible for that.  I'm
Xthinking of adding new planet types if I can get information on their
Xgeneration.  Any help on this point (once you have seen the game and know how
Xit is done here) would be appreciated.  Ideas of mine on this cover
Xthings such as Ringworlds, Dyson spheres, space elevators, artificial
Xhollow planets, the list goes on..
X	new command: technology.  this allows investment to influence
Xtech development, instead of just having that depend on your
Xrace's IQ..
X
X
X	New versions will be posted/added to/however this is done,
Xwhen I have the time to write same.  I've spent two years writing 
Xthis program, and I hope it is enjoyed by everyone using it.
X
X
X
XSTARTING THE GAME:
X	This was done on two seperate machines, one running 4.2 and the other
Xrunning a tweaked version of 4.3.  The current code has been tested using
X4.3 BSD Unix. Edit the Makefile to suit your needs. When it's done making, 
Xtry this:
X	makeuniv < planet.list
XIf you don't put the planet.list direction you will be asked for data
Xpertaining to the universe you wish to create.
X
X	This will set up a fair-sized game with 30 stars and 30 planets,
Xshould be good for a decent system.  GB_daemon is the program that does
Xturns.  Invoke it with "GB_daemon <update_hours>" where update_hours
Xis the number of hours between updates.  You may want to have them
Xat 1/hr at first, slower later on as things get rushed..
X	Once the game is up, you, as the diety player, must enroll
Xfirst.  (several objects in the game are owned by player 1, it would be better
Xif this were you..)  (To make yourself some resources, use the 'fix' command.) 
XOccasionally you might tweak a star or two to go nova
X(fix its stability to 100); this is especially useful for recalcitrant 
Xgame-players complaining about bugs.  Put the fear of god into them.
X
X	Please send me information on trends in the game; what tends to
Xhappen here and there.
X
X
XFIXES/ADDITIONS:
X	Ships are now stored in a list, instead of slots in planets.  This 
Xmakes a lot of things much faster, as well as more efficient, and you won't
Xrun into the barrier of 25 ships max in orbit around every planet.
X	Alterations in some algorithms make it now impossible for ships to 
Xbe in two lists at once, or in the wrong list.
X	Load used to not check for the other ship overflowing its 
Xbounds; I fixed this since you could load a whole colony onto an
Xexplorer.  You can, however, load as many resource points as you want, onto 
Xshuttles only.  this makes it possible for two shuttles to construct something
Xlarger.
X	Only shuttles, space habitats (used to be space stations), and
Xorbital assault platforms can assemble other ships.
X	There have been changes to the behavior of space habitats:
Xthey reproduce resources and also people.  Because of some new restrictions
XI've put in, the only way to really build them (at least the first one)
Xis to build two shuttles, load them with resources, launch them and dock
Xthem together and transfer all the resources of one to the other, land the
Xempty one and fill it again, and continue transferring them until the
Xshuttle has enough to build a habitat.  Hey, it's the way WE have to do
Xit..
X
X	Planets are now moved in their orbits before ships are moved;
Xthis makes them more efficient in interplanetary navigation, and ships won't
Xfollow them around anymore.
X	New ship type: toxic waste canister, which reduces your toxicity
Xof the planet you build it on-- but what do you do with all the canisters?
X	More new ships: ground and space telescopes.  ground telescopes are
Xway cheap and have a much lower tech, while space telescopes cost more
Xbut have a longer range.  range is proportional to your tech.  These
Xwere put in so people don't have to send ships out blindly.  Once you've
Xsurveyed someplace with one of these, you can then map and 'cs' to it.
X	Tactical works better, it uses planets as part of its display.
X	The bug where sector maps got randomly switched around sometimes
Xhalting the game, has been fixed.  This was a MAJOR pain, and the main problem
Xof the moment in GB.
X
X
X	Many thanks to Steven Grimm (koreth@ssyx), without whose help
Xin the early stages of the game, development would not have been possible,
Xand Evan Schaffer admin of ssyx, whose tolerance of huge CPU usages by a lowly
Xundergrad making a game is greatly appreciated.
X
X
X	Rob Chansky
X	smq@ucscb.ucsc.edu
X	smq@ssyx.ucsc.edu
X	...!ucbvax!ucscc!ssyx!smq
X	...!ucbvax!ucscc!ucscb!smq
X
END_OF_FILE
if test 6261 -ne `wc -c <'README_ORIG'`; then
    echo shar: \"'README_ORIG'\" unpacked with wrong size!
fi
# end of 'README_ORIG'
fi
if test ! -d 'client' ; then
    echo shar: Creating directory \"'client'\"
    mkdir 'client'
fi
if test ! -d 'server' ; then
    echo shar: Creating directory \"'server'\"
    mkdir 'server'
fi
if test -f 'server/build.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'server/build.c'\"
else
echo shar: Extracting \"'server/build.c'\" \(23712 characters\)
sed "s/^X//" >'server/build.c' <<'END_OF_FILE'
X/*
X * Galactic Bloodshed, copyright (c) 1989 by Robert P. Chansky, 
X * smq@ucscb.ucsc.edu, mods by people in GB_copyright.h.
X * Restrictions in GB_copyright.h
X * build -- build a ship
X */
X
X#include "GB_copyright.h"
X
X#define EXTERN extern
X#include "vars.h"
X#include "ships.h"
X#include "races.h"
X#include "shipdata.h"
X#include "buffers.h"
X#include <curses.h>
X#include <setjmp.h>
X#include <signal.h>
X
Xint build_shdata,build_pdata,build_sectdata,sh_data_file, build_racedata;
X
Xmake_mod(Playernum, APcount, argn, args, mode)
Xint Playernum;
Xint APcount;
Xint argn;
Xchar args[MAXARGS][COMMANDSIZE];
Xint mode;
X{
Xint i, value;
Xchar shipc;
Xshiptype *dirship;
Xfloat getmass();
X
Xfree(Race);
Xopenracedata(&build_racedata);
Xgetrace(build_racedata, &Race, Playernum);
Xclose_file(build_racedata);
X
X
Xif(Dir[Playernum-1].level != LEVEL_SHIP) {
X    notify(Playernum, "You have to change scope to a factory to program it.\n");
X    return;
X}
X
X     openshdata(&build_shdata);
X     if (!getship(build_shdata, &dirship, Dir[Playernum-1].shipno)) {
X		sprintf(buf,"Illegal dir value.\n");
X		notify(Playernum, buf);
X		close_file(build_shdata);
X		return;
X	}
X	close_file(build_shdata);
X	if (testship(Playernum,dirship, Dir[Playernum-1].shipno))
X		{
X			free(dirship);
X			return;
X		}
Xif(dirship->type != OTYPE_FACTORY) {
X    notify(Playernum, "That is not a factory.\n");
X    free(dirship);
X    return;
X}
X
Xif(dirship->on && argn > 1) {
X    notify(Playernum, "This factory is already online.\n");
X    free(dirship);
X    return;
X}
X
Xif(mode==0) {
Xif(argn<2) {	/* list the current settings for the factory */
Xif(!dirship->build_type) {
X	notify(Playernum, "No ship type specified.\n");
X	free(dirship);
X	return;
X	}
X
Xnotify(Playernum, "    - Current production specs -\n");
Xsprintf(buf, "  	   Ship type: %s\n", Shipnames[dirship->build_type]);
Xnotify(Playernum, buf);
Xsprintf(buf, "	       class: %s\n", dirship->class);
Xnotify(Playernum, buf);
Xsprintf(buf, "	       armor: %d\n", dirship->armor);
Xnotify(Playernum, buf);
Xsprintf(buf, "	        guns: %d\n", dirship->guns);
Xnotify(Playernum, buf);
Xsprintf(buf, "	        size: %d\n", dirship->size);
Xnotify(Playernum, buf);
Xsprintf(buf, "	        crew: %d\n", dirship->max_crew);
Xnotify(Playernum, buf);
Xsprintf(buf, "	    max fuel: %d\n", dirship->max_fuel);
Xnotify(Playernum, buf);
Xsprintf(buf, " 	   max cargo: %d\n", dirship->max_resource);
Xnotify(Playernum, buf);
Xsprintf(buf, "        max destruct: %d\n", dirship->max_destruct);
Xnotify(Playernum, buf);
Xsprintf(buf, " 	   max speed: %d\n\n", dirship->max_speed);
Xnotify(Playernum, buf);
Xsprintf(buf, "    Cost: %dr  Base Mass: %.1f\n", dirship->build_cost, dirship->base_mass);
Xnotify(Playernum, buf);
X
X    free(dirship);
X    return;
X}
X
Xshipc = args[1][0];
X
X    i=0;
X    while ((Shipltrs[i]!=shipc) && (i<NUMSTYPES)) i++;
X
Xif (i>=NUMSTYPES || (i==STYPE_POD && !Race->Thing) ) {
X	sprintf(buf, "Illegal ship letter.\n");
X	notify(Playernum, buf);
X	return;
X    } else if (Race->tech < Shipdata[i][ABIL_TECH] && !Race->God) {
X	sprintf(buf,"You don't have enough technology to build one of those.\n");
X	notify(Playernum, buf);
X	return;
X    } 
X
Xif(Shipdata[i][ABIL_BUILD] != Shipdata[OTYPE_FACTORY][ABIL_CONSTRUCT]) {
X    notify(Playernum, "This kind of ship does not require a factory to construct.\n");
X    free(dirship);
X    return;
X}
X
Xdirship->build_type = i;
Xdirship->armor = Shipdata[i][ABIL_ARMOR];
Xdirship->guns = Shipdata[i][ABIL_GUNS];
Xdirship->size = Shipdata[i][ABIL_TARGET];
Xdirship->max_crew = Shipdata[i][ABIL_MAXCREW];
Xdirship->max_resource = Shipdata[i][ABIL_CARGO];
Xdirship->max_fuel = Shipdata[i][ABIL_FUELCAP];
Xdirship->max_destruct = Shipdata[i][ABIL_DESTCAP];
Xdirship->max_speed = Shipdata[i][ABIL_SPEED];
X
Xsprintf(buf, "Factory designated to produce %ss.\n", Shipnames[i]);
Xnotify(Playernum, buf);
X
X} else if(mode==1) {
X
Xif(!dirship->build_type) {
X	notify(Playernum, "No ship design specified. Use 'make <ship type>' first.\n");
X	free(dirship);
X	return;
X}
X
Xif(argn<2) {
X    notify(Playernum, "You have to specify the characteristic you wish to modify.\n");
X    free(dirship);
X    return;
X} else if(argn<3) {
X    notify(Playernum, "You have to specify the value you want the design set to.\n");
X    free(dirship);
X    return;
X}
X	   sscanf(args[2], "%d", &value);
Xif(value < 0) {
X    notify(Playernum, "That's a ridiculous setting.\n");
X    free(dirship);
X    return;
X}
X
Xif(!strncmp(args[1], "armor", strlen(args[1]))) {
X    dirship->armor = MIN(value, 100);
X} else if(!strncmp(args[1], "guns", strlen(args[1]))) {
X    dirship->guns = MIN(value, 1000);
X} else if(!strncmp(args[1], "size", strlen(args[1]))) {
X    dirship->size = MAX(1, MIN(value, 1000));
X} else if(!strncmp(args[1], "crew", strlen(args[1]))) {
X    dirship->max_crew = MIN(value, 10000);
X} else if(!strncmp(args[1], "cargo", strlen(args[1]))) {
X    dirship->max_resource = MIN(value, 10000);
X} else if(!strncmp(args[1], "fuel", strlen(args[1]))) {
X    dirship->max_fuel = MIN(value, 10000);
X} else if(!strncmp(args[1], "destruct", strlen(args[1]))) {
X   dirship->max_destruct = MIN(value, 10000);
X} else if(!strncmp(args[1], "speed", strlen(args[1]))) {
X    dirship->max_speed = MAX(1,MIN(value, 9));
X} else {
X    notify(Playernum, "That characteristic either doesn't exist or can't be modified.\n");
X    free(dirship);
X    return;
X}
X    
X} else {
X    notify(Playernum, "Weird error.\n");
X    free(dirship);
X    return;
X}
X/* compute how much it's going to cost to build the ship */
Xdirship->build_cost = cost(dirship);
Xsprintf(buf, "The current cost of the ship is %d resources.\n",
X	dirship->build_cost);
Xnotify(Playernum, buf);
Xdirship->base_mass = getmass(dirship);
Xsprintf(buf, "The current base mass of the ship is %.1f.\n",
X	dirship->base_mass);
X
X		openshdata(&build_shdata);
X		putship(build_shdata, dirship, Dir[Playernum-1].shipno);
X		close_file(build_shdata);
Xfree(dirship);
X
X}
X
X
Xbuild(Playernum,APcount, argn,args)
Xint Playernum;
Xint APcount;
Xint argn;
Xchar args[MAXARGS][COMMANDSIZE];
X{
Xint j,i,x= -1 ,y= -1 ,shipno, mask;
Xint load_fuel,load_crew,picked=0,cost,sh,found;
Xfloat fraction;
Xchar c,shipc;
Xplanettype *planet;
Xsectortype *sect;
Xshiptype s,*s2,*dirship;
XFILE *fd;
Xchar temp[128];
Xfloat getmass();
X
Xbuild_shdata = build_pdata = build_sectdata = NEUTRAL_FD;
X
Xfree(Race);
Xopenracedata(&build_racedata);
Xgetrace(build_racedata, &Race, Playernum);
Xclose_file(build_racedata);
X
X if (Dir[Playernum-1].level==LEVEL_PLAN) {
X	if (!enufAP(Playernum,Stars[Dir[Playernum-1].snum]->AP[Playernum-1], APcount)) {
X		return;
X 	} else {
X     		openpdata(&build_pdata);
X     		getplanet(build_pdata,&planet,
X		Stars[Dir[Playernum-1].snum]->planetpos[Dir[Playernum-1].pnum]);
X		close_file(build_pdata);
X		shipc = args[1][0];
X	    }
X } else if (Dir[Playernum-1].level==LEVEL_SHIP) {
X     openshdata(&build_shdata);
X     if (!getship(build_shdata, &dirship, Dir[Playernum-1].shipno)) {
X		sprintf(buf,"Illegal dir value.\n");
X		notify(Playernum, buf);
X		close_file(build_shdata);
X		return;
X	}
X	close_file(build_shdata);
X	if (testship(Playernum,dirship, Dir[Playernum-1].shipno))
X		{
X			free(dirship);
X			return;
X		}
X
X 	if (Shipdata[dirship->type][ABIL_CONSTRUCT]==0) {
X		sprintf(buf,"This ship cannot be used to construct other ships.\n");
X		notify(Playernum, buf);
X		free(dirship);
X		return;
X	}
X
X	if(dirship->type==OTYPE_FACTORY) {
X		if(!dirship->on) {
X			notify(Playernum, "This factory is not on line.\n");
X			free(dirship);
X			return;
X			}
X
X		if(dirship->damage) {
X			notify(Playernum, "This factory cannot produce ships until the damage is zero.\n");
X			free(dirship);
X			return;
X			}
X
X		if(!dirship->popn) {
X			notify(Playernum, "This factory doesn't have any crew!\n");
X			free(dirship);
X			return;
X			}
X
X		shipc = Shipltrs[dirship->build_type];
X	} else
X		shipc = args[1][0];
X
X	if (dirship->is_docked && dirship->type != OTYPE_FACTORY) {
X		if (dirship->whatdest==LEVEL_PLAN)
X			{
X			sprintf(buf,"This ship is landed.\n");
X		notify(Playernum, buf);
X			} else {
X			sprintf(buf,"There is already a ship docked here (#%d).\n",
X					dirship->destshipno);
X		notify(Playernum, buf);
X			}
X		free(dirship);
X		return;
X	}
X
X	 /* check stars, sdata for APs */
X 	if (dirship->whatorbits==LEVEL_UNIV) {
X	 	if (!enufAP(Playernum,Sdata.AP[Playernum-1], APcount))
X			{
X			free(dirship);
X			return;
X			}
X 	} else if (dirship->whatorbits==LEVEL_STAR) {
X	 	if (!enufAP(Playernum,Stars[dirship->storbits]->AP[Playernum-1], APcount))
X			{
X			free(dirship);
X			return;
X			}
X	}
X
X/* if we are at a factory, get the planet data too */
X	if(dirship->type==OTYPE_FACTORY) {
X     		openpdata(&build_pdata);
X     		getplanet(build_pdata,&planet,
X		Stars[dirship->deststar]->planetpos[dirship->destpnum]);
X		close_file(build_pdata);
X	}
X } else {
X	sprintf(buf,"You can't build anything here.\n");
X		notify(Playernum, buf);
X	return;
X }
X
X
X
Xif(shipc=='?') {
X     if (argn==2) {
X
X       sprintf(buf, "ltr             ship  carg tg armr dstcap guns fcap tech ^crew speed cost\n");
X	notify(Playernum, buf);
X       for (i=0; i<NUMSTYPES; i++)
X	  if (Race->tech >= Shipdata[i][ABIL_TECH] || Race->God)
X	    if ((i==STYPE_POD && Race->Thing) || i!=STYPE_POD)
X	      if(Shipdata[i][ABIL_PROGRAMMED]) {
X	      sprintf(buf, " %c%18s%6d%3d%5d%7d%5d%5d%5d%5d%6d%6d\n",
X		  Shipltrs[i], Shipnames[i],
X		  Shipdata[i][ABIL_CARGO], Shipdata[i][ABIL_TARGET],
X		  Shipdata[i][ABIL_ARMOR], Shipdata[i][ABIL_DESTCAP],
X		  Shipdata[i][ABIL_GUNS], Shipdata[i][ABIL_FUELCAP], 
X		  Shipdata[i][ABIL_TECH], Shipdata[i][ABIL_MAXCREW], 
X		  Shipdata[i][ABIL_SPEED], Shipdata[i][ABIL_COST] );
X	notify(Playernum, buf);
X	}
X     } else {
X	/* description of an individual object, ala' examine */
X
X	i = 0;
X        while ((Shipltrs[i]!=args[2][0]) && (i<NUMSTYPES)) 
X		i++;
X        if (i<0 || i>=NUMSTYPES || (i==STYPE_POD && !Race->Thing)
X	    || (Race->tech < Shipdata[i][ABIL_TECH] && !Race->God) ) {
X		sprintf(buf, "You can't examine that ship type (yet).\n");
X		notify(Playernum, buf);
X	} else if(!Shipdata[i][ABIL_PROGRAMMED]) {
X	  sprintf(buf, "This type of ship has not been programmed.\n");
X	  notify(Playernum, buf);
X	} else {
X    	   if ((fd=fopen(EXAM_FL, "r"))==NULL) {
X		perror(EXAM_FL);
X		return;
X    	   } else {
X   	      /* look through ship data file */
X	sprintf(buf, "\n");
X    	      for (j=0; j<=i; j++)
X       	         while (fgetc(fd) != '~') ;
X		   /* give report */
X    	      while ((c=fgetc(fd)) != '~') {
X		sprintf(temp, "%c", c);
X		strcat(buf, temp);
X		}
X	notify(Playernum, buf);
X    	      fclose(fd) ;
X	   }
X	}
X     }
Xreturn;
X }
X
X    i=0;
X    while ((Shipltrs[i]!=shipc) && (i<NUMSTYPES)) i++;
X
X
X/* figure out if the ship can be constructed in the current scope */
Xif(Dir[Playernum-1].level==LEVEL_SHIP) {
X
Xif(dirship->type==OTYPE_FACTORY)
X	i = dirship->build_type;
X
X	if(Shipdata[i][ABIL_BUILD] != Shipdata[dirship->type][ABIL_CONSTRUCT]) {
X	switch(Shipdata[dirship->type][ABIL_CONSTRUCT]) {
X		case 0 :
X			sprintf(buf, "%s cannot construct other ships.\n",
X				Shipnames[dirship->type]);
X			break;
X		case 1 :
X			sprintf(buf, "%s may only construct : or +.\n",
X				Shipnames[dirship->type]);
X			break;
X		case 2 :
X			sprintf(buf, "%s may only construct X, H, S, O, or m.\n",
X				Shipnames[dirship->type]);
X			break;
X		case 3:
X			sprintf(buf, "%s may only construct s, D, B, I, C, d, f, e, c, t, or =.\n",
X				Shipnames[dirship->type]);
X			break;
X		}
X		notify(Playernum, buf);
X		free(dirship);
X		return;
X		}
X
X} else if(Dir[Playernum-1].level == LEVEL_PLAN) {
X	if(Shipdata[i][ABIL_BUILD] > 1) {
X		switch(Shipdata[i][ABIL_BUILD]) {
X		case 2 :
X			sprintf(buf, "%s may only be constructed by s, c, S, H, or O.\n",
X				Shipnames[i]);
X			break;
X		case 3 :
X			sprintf(buf, "%s requires a factory to build it.\n",
X				Shipnames[i]);
X			break;
X		default :
X			sprintf(buf, "Weird error in build.\n");
X			break;
X		}
X			notify(Playernum, buf);
X			return;
X	}
X} else {
X	notify(Playernum, "Illegal scope.\n");
X	return;
X	}
X
Xif (i>=NUMSTYPES || (i==STYPE_POD && !Race->Thing) ) {
X	sprintf(buf, "Illegal ship letter.\n");
X	notify(Playernum, buf);
X	return;
X    } else if (Race->tech < Shipdata[i][ABIL_TECH] && !Race->God) {
X	sprintf(buf,"You don't have enough technology to build one of those.\n");
X	notify(Playernum, buf);
X	return;
X    } 
X
X	/* check for resource availability */
X
X     if (Dir[Playernum-1].level==LEVEL_SHIP && 
X		dirship->type != OTYPE_FACTORY &&
X		dirship->resource < Shipdata[i][ABIL_COST]) {
X	sprintf(buf,"Not enough resources on this ship (you need %d).\n", Shipdata[i][ABIL_COST]);
X	notify(Playernum, buf);
X	free(dirship);
X	return;
X     
X     } else if(Dir[Playernum-1].level==LEVEL_SHIP &&
X		dirship->type == OTYPE_FACTORY &&
X		planet[Playernum-1].info->resource < dirship->build_cost) {
X	sprintf(buf,"Not enough resources (%d) available.\n", dirship->build_cost);
X	notify(Playernum, buf);
X	free(dirship);
X	return;
X	}
X
X	/* find sector to build on (if planet) */
X
X     if (Dir[Playernum-1].level==LEVEL_PLAN || (Dir[Playernum-1].level==LEVEL_SHIP
X			&& dirship->type==OTYPE_FACTORY)) {
X
Xif(Dir[Playernum-1].level==LEVEL_PLAN) {
X	   sscanf(args[argn-1], "%d,%d", &x, &y);
X
Xif(x < 0 || x > planet->Maxx-1 || y < 0 || y > planet->Maxy-1) {
X    notify(Playernum, "Illegal sector.\n");
X    return;
X}
X} else {
X/* get factory coordinates */
X	x = (int)dirship->xpos;
X	y = (int)dirship->ypos;
X	}
X
X	   opensectdata(&build_sectdata);
X	   getsector(build_sectdata, &sect, planet->sectormappos+(y*planet->Maxx+x)*sizeof(sectortype));
X	close_file(build_sectdata);
X
X
X	 if (Dir[Playernum-1].level==LEVEL_PLAN &&
X		planet->info[Playernum-1].resource < Shipdata[i][ABIL_COST]) {
X		sprintf(buf, "not enough resources in stock (need %d).\n", 
X				Shipdata[i][ABIL_COST]);
X		notify(Playernum, buf);
X		return;
X	 } else if(Dir[Playernum-1].level==LEVEL_SHIP &&
X			planet->info[Playernum-1].resource < dirship->build_cost) {
X		sprintf(buf, "Not enough resources in stock (need %d).\n", 
X				dirship->build_cost);
X		notify(Playernum, buf);
X		free(dirship);
X		return;
X		}
X
X	   if (i == OTYPE_REPAIR) {
X	       if(!sect->is_wasted) {
X		   notify(Playernum, "You can only build on wasted sectors.\n");
X		   return;
X	       }
X
X	       sect->is_wasted = 0;
X		sect->fert = MIN(100, sect->fert+20);
X		opensectdata(&build_sectdata);
X	   	putsector(build_sectdata, sect, planet->sectormappos
X				+(y*planet->Maxx+x)*sizeof(sectortype) );
X		close_file(build_sectdata);
X
X		planet->info[Playernum-1].resource -= 
X		  Shipdata[OTYPE_REPAIR][ABIL_COST];
X		sprintf(buf, "Sector %d,%d repaired.\n", x,y);
X		notify(Playernum, buf);
X
X		openpdata(&build_pdata);
X		putplanet(build_pdata,planet,Stars[Dir[Playernum-1].snum]->planetpos[Dir[Playernum-1].pnum]);
X		close_file(build_pdata);
X
X		free(planet);
X		return;
X	} else if (sect->owner != Playernum) {
X		sprintf(buf, "You don't own that sector.\n");
X		notify(Playernum, buf);
X		return;
X	   }
X	   load_crew = 0;
X	   load_fuel = 0;
X	 if(Race->autoload) {
X	if(Dir[Playernum-1].level==LEVEL_PLAN) {
X	   load_crew = MIN(Shipdata[i][ABIL_MAXCREW], sect->popn);
X	   load_fuel = MIN(Shipdata[i][ABIL_FUELCAP], planet->info[Playernum-1].fuel);
X	} else {
X	   load_crew = MIN(dirship->max_crew, sect->popn);
X	   load_fuel = MIN(dirship->max_fuel, planet->info[Playernum-1].fuel);
X	}
X
X	   sect->popn -= load_crew;
X	   if (!sect->popn)
X		sect->owner = 0;
X
X	   planet->info[Playernum-1].fuel -= load_fuel;
X	 }
X
X    } else {
X      load_crew = 0;
X      load_fuel = 0;
X      if(Race->autoload) {
X	   load_crew = MIN(Shipdata[i][ABIL_MAXCREW], dirship->popn);
X	   dirship->popn -= load_crew;
X	   dirship->mass -= load_crew * Race->mass;
X	   load_fuel = MIN(Shipdata[i][ABIL_FUELCAP], dirship->fuel);
X	   dirship->fuel -= load_fuel;
X	   dirship->fuel -= load_fuel * MASS_FUEL;
X	 }
X    }
X
X
X 	Bzero(s);
X
X	s.type = i;
X	if (Dir[Playernum-1].level==LEVEL_PLAN) {
X		s.xpos = (float)x;
X		s.ypos = (float)y;
X	} else {
X		s.xpos = dirship->xpos + (float)(!(dirship->type==OTYPE_FACTORY));
X		s.ypos = dirship->ypos;
X	}
X
X	if(Shipdata[i][ABIL_SPEED])
X		s.speed = 1;
X	else
X		s.speed = 0;
X
X	s.owner = Playernum;
X
X	s.tech = Race->tech;
Xif(Dir[Playernum-1].level==LEVEL_SHIP && dirship->type==OTYPE_FACTORY) {
X	s.armor = dirship->armor;
X	s.guns = dirship->guns;
X	s.size = dirship->size;
X	s.max_crew = dirship->max_crew;
X	s.max_resource = dirship->max_resource;
X	s.max_destruct = dirship->max_destruct;
X	s.max_fuel = dirship->max_fuel;
X	s.max_speed = dirship->max_speed;
X	s.build_cost = dirship->build_cost;
X	s.build_type = dirship->build_type;
X	s.base_mass = dirship->base_mass;
X	sprintf(s.class, "%s", dirship->class);
X			/* docked on the planet */
X		s.whatorbits = LEVEL_PLAN;
X		s.whatdest = LEVEL_PLAN;
X		s.deststar = dirship->deststar;
X		s.destpnum = dirship->destpnum;
X		s.storbits = dirship->storbits;
X		s.pnumorbits = dirship->pnumorbits;
X	} else {
X	s.armor = Shipdata[i][ABIL_ARMOR];
X	s.guns = Shipdata[i][ABIL_GUNS];
X	s.size = Shipdata[i][ABIL_TARGET];
X	s.max_crew = Shipdata[i][ABIL_MAXCREW];
X	s.max_resource = Shipdata[i][ABIL_CARGO];
X	s.max_fuel = Shipdata[i][ABIL_FUELCAP];
X	s.max_speed = Shipdata[i][ABIL_SPEED];
X
X	if(i!=OTYPE_FACTORY)
X		s.build_type = i;
X	else
X		s.build_type = 0;
X
X	s.build_cost = Shipdata[i][ABIL_COST];
X	s.base_mass = getmass(&s);
X	sprintf(s.class, "Standard");
X
X	if (Dir[Playernum-1].level==LEVEL_SHIP) {
X		s.whatdest = LEVEL_SHIP;
X		s.destshipno = Dir[Playernum-1].shipno;
X		s.whatorbits = dirship->whatorbits;
X	} else {
X			/* docked on the planet */
X		s.whatorbits = LEVEL_PLAN;
X		s.whatdest = LEVEL_PLAN;
X		s.deststar = Dir[Playernum-1].snum;
X		s.destpnum = Dir[Playernum-1].pnum;
X	}
X	s.storbits = Dir[Playernum-1].snum;
X	s.pnumorbits = Dir[Playernum-1].pnum;
X}
X
X	s.fuel = load_fuel;
X	s.popn = load_crew;
X	s.destruct = s.resource = 0;
X
X	s.mass = s.base_mass + load_crew*Race->mass + load_fuel*MASS_FUEL;
X	s.is_alive = 1;
X 	s.active = 1;
X
X	if(s.guns)
X	 	s.protect.self = 1;
X	else
X		s.protect.self = 0;
X
X	s.hyper_drive.on = 0;
X	s.hyper_drive.ready = 0;
X	s.hyper_drive.charge = 0;
X
X	s.is_docked = 1;
X
X	s.rad = 0;
X	s.damage = Shipdata[s.type][ABIL_DAMAGE];
X
X	s.object.number = 0;
X	s.object.number2 = 0;
X	s.object.number3 = 0;
X	s.object.number4 = 0;
X
X	if (has_switch(&s))
X		s.on = 0;
X
X	switch (s.type) {
X
X	    case OTYPE_VN:
X		s.object.number = 1;	/* one of them */
X		s.object.number2 = 1;	/* we have an assignment */
X		s.on = 1;
X		break;
X	    case STYPE_MINE:
X		s.object.number = 100;	/* trigger radius */
X		sprintf(buf, "Mine disarmed.\nTrigger radius set to 100.\n");
X		notify(Playernum, buf);
X		break;
X	    case OTYPE_TRANSDEV:
X		sprintf(buf, "Receive OFF.  Change with order.\n");
X		notify(Playernum, buf);
X		break;
X	    case OTYPE_AP:
X		sprintf(buf, "Processor OFF.\n");
X		notify(Playernum, buf);
X		break;
X	    case OTYPE_TOXWC:
X		sprintf(buf, "Toxin concentration of the planet was %d,",
X				planet->conditions[TOXIC]);
X		notify(Playernum, buf);
X		if (planet->conditions[TOXIC] > TOXMAX) {
X			planet->conditions[TOXIC] -= TOXMAX;
X			s.object.number = TOXMAX;
X		} else {
X			s.object.number = planet->conditions[TOXIC];
X			planet->conditions[TOXIC] = 0;
X		}
X		sprintf(buf, " now %d.\n",planet->conditions[TOXIC]);
X		notify(Playernum, buf);
X		break;
X	    case OTYPE_STELE:
X	    case OTYPE_GTELE:
X		sprintf(buf, "Telescope range is %.2f.\n", tele_range(s.type,s.tech));
X		notify(Playernum, buf);
X		break;
X	    default:
X		break;
X	}
X
X
X		/* deduct resource cost */
X
X	if (Dir[Playernum-1].level==LEVEL_PLAN || (Dir[Playernum-1].level==LEVEL_SHIP &&
X			dirship->type==OTYPE_FACTORY))
X		planet->info[Playernum-1].resource -= s.build_cost;
X	else
X		dirship->resource -= s.build_cost;
X
X	sprintf(buf, "Ship built at a cost of %d resources.\n", s.build_cost);
X	notify(Playernum, buf);
X
X		/* check for dead ships in the data files */
X
X	 /* erase any '0' entries in the dead ship file, which shouldn't be there */
X	while ( (shipno = getdeadship()) == 0){ };
X
X	if ( shipno == -1) {
X			/* otherwise recycle topmost dead ship in data file. */
X			/* no dead ships to recycle */
X	    openshdata(&build_shdata);
X	    shipno = Numships(build_shdata) + 1;
X	    close_file(build_shdata);
X	}
X
X	sprintf(buf, "%s #%d is %s %.0f,%.0f.\n", Shipnames[s.type], shipno,
X		(Dir[Playernum-1].level==LEVEL_SHIP && dirship->type != OTYPE_FACTORY)
X				 ? "at" : "on sector", s.xpos,s.ypos);
X		notify(Playernum, buf);
X
X		/* insert ship into planet's orbit */
X	if (Dir[Playernum-1].level==LEVEL_PLAN || (Dir[Playernum-1].level==LEVEL_SHIP
X		&& dirship->type==OTYPE_FACTORY)) {
X		 /* built on planet */
X		 /* next ship on list */
X		s.nextship = planet->ships;
X		planet->ships = shipno;
X		openpdata(&build_pdata);
X		putplanet(build_pdata,planet,
X			Stars[Dir[Playernum-1].snum]->planetpos[Dir[Playernum-1].pnum]);
X		close_file(build_pdata);
X	        free(planet);
X
X		  /* write sector to disk */
X	opensectdata(&build_sectdata);
X	   	putsector(build_sectdata, sect, planet->sectormappos+(y*planet->Maxx+x)*sizeof(sectortype) );
X	close_file(build_sectdata);
X
X	   	free(sect);
X
X	} else {	/* was built on a ship -- insert after that ship */
X
X		s.nextship = dirship->nextship;
X		dirship->nextship = shipno;
X
X		dirship->is_docked = 1;
X		dirship->whatdest = LEVEL_SHIP;
X		dirship->destshipno = shipno;
X
X		openshdata(&build_shdata);
X		putship(build_shdata, dirship, Dir[Playernum-1].shipno);
X		close_file(build_shdata);
X
X	    }
Xif(Shipdata[s.type][ABIL_DAMAGE]) {
X  sprintf(buf, "Warning: This ship is constructed with a %d%% damage level.\n",
X	    Shipdata[s.type][ABIL_DAMAGE]);
X    notify(Playernum, buf);
X
Xif(s.max_resource)
X    notify(Playernum, "It will need resources to make fully operational.\n");
Xelse
X    notify(Playernum, "This ship does not need resources to repair.\n");
X}
X
X
Xopenshdata(&build_shdata);
Xputship(build_shdata,&s,shipno);
Xclose_file(build_shdata);
X
X    if (Dir[Playernum-1].level==LEVEL_SHIP && dirship->whatorbits==LEVEL_UNIV)
X	    deductAPs(Playernum, APcount, 0, 1);
X    else 
X	    deductAPs(Playernum, APcount, Dir[Playernum-1].snum, 0);
X
Xif(Dir[Playernum-1].level==LEVEL_SHIP) free(dirship);
X
Xif(Race->autoload) {
X    sprintf(buf, "Loaded with %d crew and %d fuel.\n", load_crew,load_fuel);
X     notify(Playernum, buf);
X	}
X}
X
Xfloat getmass(s)
Xshiptype *s;
X{
Xfloat base_mass;
Xbase_mass = MAX(1.0, (float)s->armor + (float)s->size/10.0 + (float)s->guns/10.0);
Xreturn(base_mass);
X}
X
Xint cost(s)
Xshiptype *s;
X{
Xint i;
Xfloat advantage, disadvantage, factor;
X
Xadvantage = 0.;
Xdisadvantage = 0.;
X
Xi=s->build_type;
X/* compute how much it costs to build this ship */
X/* armor */
Xfactor = (((float)s->armor + 1.0)/((float)Shipdata[i][ABIL_ARMOR]+1.0)) - 1.0;
Xif(factor >= 0.0)
X	advantage += factor;
Xelse
X	disadvantage -= factor;
X
X/* guns */
Xfactor = (((float)s->guns + 1.0)/((float)Shipdata[i][ABIL_GUNS]+1.0)) - 1.0;
Xif(factor >= 0.0)
X	advantage += factor;
Xelse
X	disadvantage -= factor;
X
X/* size */
Xfactor = (((float)s->size + 1.0)/((float)Shipdata[i][ABIL_TARGET]+1.0)) - 1.0;
Xif(factor >= 0.0)
X	advantage += factor;
Xelse
X	disadvantage -= factor;
X
X/* crew */
Xfactor = (((float)s->max_crew + 1.0)/((float)Shipdata[i][ABIL_MAXCREW]+1.0)) - 1.0;
Xif(factor >= 0.0)
X	advantage += factor;
Xelse
X	disadvantage -= factor;
X
X/* cargo capacity */
Xfactor = (((float)s->max_resource + 1.0)/((float)Shipdata[i][ABIL_CARGO]+1.0)) - 1.0;
Xif(factor >= 0.0)
X	advantage += factor;
Xelse
X	disadvantage -= factor;
X
X/* fuel capacity */
Xfactor = (((float)s->max_fuel + 1.0)/((float)Shipdata[i][ABIL_FUELCAP]+1.0)) - 1.0;
Xif(factor >= 0.0)
X	advantage += factor;
Xelse
X	disadvantage -= factor;
X
X/* destruct capacity */
Xfactor = (((float)s->max_destruct + 1.0)/((float)Shipdata[i][ABIL_DESTCAP]+1.0)) - 1.0;
Xif(factor >= 0.0)
X	advantage += factor;
Xelse
X	disadvantage -= factor;
X
Xfactor = (((float)s->max_speed + 1.0)/((float)Shipdata[i][ABIL_SPEED]+1.0)) - 1.0;
Xif(factor >= 0.0)
X	advantage += factor;
Xelse
X	disadvantage -= factor;
X
Xfactor = (1.+advantage)/(1.+disadvantage);
X
Xreturn ((int)(factor * (float)Shipdata[i][ABIL_COST]));
X
X}
X
X
X
END_OF_FILE
if test 23712 -ne `wc -c <'server/build.c'`; then
    echo shar: \"'server/build.c'\" unpacked with wrong size!
fi
# end of 'server/build.c'
fi
if test -f 'server/capture.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'server/capture.c'\"
else
echo shar: Extracting \"'server/capture.c'\" \(7318 characters\)
sed "s/^X//" >'server/capture.c' <<'END_OF_FILE'
X/*
X** Galactic Bloodshed, copyright (c) 1989 by Robert P. Chansky, 
X** smq@ucscb.ucsc.edu, mods by people in GB_copyright.h.
X** Restrictions in GB_copyright.h.
X**
X**  capture.c -- capture a ship on the ground
X**
X*/
X
X#include "GB_copyright.h"
X#define EXTERN extern
X#include "vars.h"
X#include "ships.h"
X#include "races.h"
X#include "buffers.h"
X#include <signal.h>
X#include <math.h>
X#include <signal.h>
X
Xint capture_sectdata,capture_shdata,capture_pdata, capture_racedata;
X
Xextern int Defensedata[];
X
X
Xcapture(Playernum,APcount, argn,args)
Xint Playernum;
Xint APcount;
Xint argn;
Xchar args[MAXARGS][COMMANDSIZE];
X{
Xshiptype *ship;
Xplanettype *p;
Xsectortype *sect;
Xracetype *alien;
Xboolean Land=0,Dock=0,cont,planetmod=0,sectmod=0;
Xint boarders,olddpopn,oldapopn,oldowner,shipdam,booby,pris,
X	numdest=0,shipno,x= -1,y= -1,i,mask, casualties, casualties2;
Xfloat astrength,dstrength;
X
Xcapture_sectdata = capture_shdata = capture_pdata = NEUTRAL_FD;
X
Xsscanf(args[1]+(args[1][0]=='#'), "%d",&shipno);
X
X  openshdata(&capture_shdata);
X  if (!getship(capture_shdata, &ship, shipno)) {
X	sprintf(buf,"Ship doesn't exist.\n");
X	notify(Playernum, buf);
Xclose(capture_shdata);
X	return;
X  }
Xclose(capture_shdata);
X
X  if (!ship->is_alive || !(ship->is_docked && ship->whatdest==LEVEL_PLAN) ) {
X	sprintf(buf,"%s #%d is not landed on a planet.\n",
X		Shipnames[ship->type], shipno);
X	notify(Playernum, buf);
X	return;
X  }
X
X  if (ship->owner==Playernum) {
X	sprintf(buf,"That's your own ship.\n");
X	notify(Playernum, buf);
X	return;
X  }
X
X
X  if (!enufAP(Playernum,Stars[ship->storbits]->AP[Playernum-1], APcount))
X	return;
X
X
Xfree(Race);
Xopenracedata(&capture_racedata);
Xgetrace(capture_racedata, &Race, Playernum);
Xclose_file(capture_racedata);
X
Xx = (int)ship->xpos;
Xy = (int)ship->ypos;
X
X     openpdata(&capture_pdata);
X     getplanet(capture_pdata, &p, Stars[ship->storbits]->planetpos[ship->pnumorbits]);
X     close_file(capture_pdata);
X
X
X     opensectdata(&capture_sectdata);
X     getsector(capture_sectdata,&sect,
X	p->sectormappos+(y*p->Maxx+x)*sizeof(sectortype));
X
X     if (sect->owner!=Playernum) {
X	sprintf(buf,"You don't own the sector where the ship is landed.\n");
X	notify(Playernum, buf);
X	return;
X     }
X
X	openracedata(&capture_racedata);
X     getrace(capture_racedata, &alien, ship->owner);
X	close_file(capture_racedata);
X
X	boarders = atoi(args[2]);
X
X		if (boarders > MIN(sect->popn, Max_crew(ship)) || boarders <= 0) {
X			sprintf(buf,"Illegal number of boarders (max can be %d).\n",
X				MIN(sect->popn, Max_crew(ship)));
X			notify(Playernum, buf);
X			return;
X		}
X
X
X     if (isset(Race->allied, ship->owner))
X	{
X	sprintf(buf,"Boarding the ship of your ally, %s\n", alien->name);
X	notify(Playernum, buf);
X	}
X
X     oldapopn = boarders;
X     olddpopn = ship->popn;
X     oldowner = ship->owner;
X	shipdam = 0;
X	casualties = 0;
X	casualties2 = 0;
X
X	if(olddpopn || !Max_crew(ship)) {
X
X     sprintf(buf,"Attack strength: %.2f     Defense strength: %f\n",
X		   astrength = 0.1 * boarders * log10(Race->fighters
X			* (Race->tech + 1.0) * (Race->likes[sect->des] + 1.0)
X			* (sect->is_wasted ? 0 : Defensedata[sect->des] + 10)),
X
X		    dstrength = 0.1* ship->popn * log10(alien->fighters
X			* (alien->tech + 1.0) * 
X	 		(Armor(ship)+1) + 10)
X	     * .01 * (100 - ship->damage));
X
X	notify(Playernum, buf);
X 
X	sect->popn -= boarders;
X	booby = 0;
X
Xif(astrength > 0.0) {
X     	casualties = MIN(boarders, int_rand(0, (int)((float)boarders * dstrength / astrength)));
X	if(casualties > boarders) casualties = boarders; /* shouldnt happen, but it does sometimes !*/
X	boarders -= casualties;
X	}
X
Xif(dstrength > 0.0) {
X	casualties2 = MIN(olddpopn, int_rand(0, (int)((float)olddpopn * astrength / dstrength)));
X	if(casualties2 > olddpopn) casualties2 = olddpopn;
X	/* ditto */
X
X	ship->popn -= casualties2;
X	ship->mass -= casualties2 * alien->mass;
X			/* (their mass) */
X
X     shipdam = int_rand(0,round_rand(25. * astrength/dstrength));
X		 /* check for boobytrapping */
X	ship->damage = MIN(100, ship->damage+shipdam);
X
X	if(ship->damage >= 100)
X		{
X			ship->popn = 0;
X			kill_ship(ship);
X			}			
X	}
X}
X
X		   if ((ship->popn == 0)  && ship->is_alive) {
X				/* we got 'em */
X			ship->owner = Playernum;
X			ship->popn = boarders;
X			ship->mass += boarders * Race->mass;	/* our mass */
X		   } else {		/* retreat */
X			sect->popn += boarders;
X		   }
X
X	if(sect->popn == 0)
X		sect->owner = 0;
X
X		sprintf(buf,"BULLETIN from %s/%s!!\n",
X			Stars[ship->storbits]->name,Stars[ship->storbits]->pnames[ship->pnumorbits]);
X		notify(oldowner, telegram_buf);
X		sprintf(buf,"You are being attacked by%s Player #%d (%s)!!!\n",
X			(isset(alien->allied,Playernum) ? " your ally" :
X				(isset(alien->atwar,Playernum) ? " your enemy" : " neutral")),
X				Playernum,Race->name);
X		notify(oldowner, buf);
X		sprintf(buf,"%s #%d ASSAULTED at sector %d,%d [owner %d] !\n",
X			Shipnames[ship->type], shipno, x, y, sect->owner);
X		notify(oldowner, buf);
X		sprintf(buf,"Your damage: %d%% (now %d%%)\n", shipdam, ship->damage);
X		notify(oldowner, buf);
X		sprintf(buf,"Damage inflicted:  Them: %d%% (now %d%%)\n", shipdam,ship->damage);
X		notify(Playernum, buf);
X	if(!ship->is_alive) {
X  		sprintf(buf,"              YOUR SHIP WAS DESTROYED!!!\n");
X		notify(oldowner, buf);
X  		sprintf(buf,"              Their ship DESTROYED!!!\n");
X		notify(Playernum, buf);
X	}
X
X			if (ship->owner==Playernum) {
X				sprintf(buf,"%s CAPTURED!\n",Shipnames[ship->type]);
X					notify(oldowner, buf);
X				sprintf(buf,"VICTORY! The ship is yours!\n");
X					notify(Playernum, buf);
X				if (astrength/dstrength > 5.0) {
X				   pris=astrength/dstrength;
X				   pris=MIN(pris,olddpopn);
X				   if (Race->captured_prisoners[oldowner-1]<100)
X				     Race->captured_prisoners[oldowner-1]++;
X				   sprintf(buf,"1 prisoner captured!\n");
X					notify(Playernum, buf);
X				   sprintf(buf,"1 prisoner captured!\n");
X					notify(oldowner, buf);
X				if (boarders)
X					{
X				  sprintf(buf,"%d boarders move in.\n", boarders);
X				  	notify(Playernum, buf);
X					}
X				}
X			} else if(ship->popn) {
X				sprintf(buf,"You fought them off!\n");
X					notify(oldowner, buf);
X				sprintf(buf,"The boarding was repulsed; try again.\n");
X					notify(Playernum, buf);
X			}
X
X		if (ship->is_alive) {
X			if (sect->popn + boarders == 0) {
X				sprintf(buf,"You killed all the aliens in this sector!\n");
X					notify(oldowner, buf);
X			} else sprintf(buf," ");
X			if (boarders==0) {
X				sprintf(buf,"Oh no! They killed your party to the last man!\n");
X					notify(Playernum, buf);
X			}
X		} else {
X			sprintf(buf,"Your ship was weakened too much!\n");
X					notify(oldowner, buf);
X			sprintf(buf,"The assault weakened their ship too much!\n");
X					notify(Playernum, buf);
X		}
X		sprintf(buf,"Casualties: Yours: %d, Theirs: %d\n", casualties2, casualties);
X				notify(oldowner, buf);
X		sprintf(buf,"Casualties: Yours: %d, Theirs: %d\n", casualties, casualties2);
X				notify(Playernum, buf);
X	
X     openshdata(&capture_shdata);
X     putship(capture_shdata, ship, shipno);
X     close_file(capture_shdata);
X
X     putsector(capture_sectdata,sect,p->sectormappos+(y*p->Maxx+x)*sizeof(sectortype));
X     close_file(capture_sectdata);
X
X     deductAPs(Playernum, APcount, ship->storbits, 0);
X
Xopenracedata(&capture_racedata);
X    putrace(capture_racedata, Race);
Xclose_file(capture_racedata);
X
X
X     free(ship);
X     free(sect);
X     free(alien);
X
X}
X
END_OF_FILE
if test 7318 -ne `wc -c <'server/capture.c'`; then
    echo shar: \"'server/capture.c'\" unpacked with wrong size!
fi
# end of 'server/capture.c'
fi
echo shar: End of archive 1 \(of 14\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 14 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0