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

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

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



#! /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 9 (of 14)."
# Contents:  Docs/fire.doc client/GB_client.c server/Makefile
#   server/autoshoot.c server/cs.c server/explore.c server/getplace.c
#   server/scrap.c
# Wrapped by billr@saab on Fri Jun  1 11:53:41 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Docs/fire.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Docs/fire.doc'\"
else
echo shar: Extracting \"'Docs/fire.doc'\" \(6455 characters\)
sed "s/^X//" >'Docs/fire.doc' <<'END_OF_FILE'
XFIRE			Galactic Bloodshed			FIRE
X
X
XNAME
X  [1] fire -- shoot at an enemy planet or ship
X
XSYNOPSIS
X       fire <from> <to> <strength> <x,y if target is a planet> 
X
XDESCRIPTION
X
X   The fire command allows players to attack each others ships/planets
Xwith available guns. Fire attempts to use stockpiled destructive capacity 
Xfrom one place, to give damage to another.
X
X   When firing from a ship the player must designate his ship number
Xpreceded with the '#' symbol - e.g. 'fire from (ship/planet) #85'
XIf the firing/target destination is a planet the player must designate
Xthe 'path' for the planet - e.g. 'fire at (ship/planet) /Sol/Earth'.
XThe player is then prompted for the number of guns to fire with
X(the maximum available is given).
X
X   The maximum number of guns for a planet is a set amount, usually
X20, which represents the planet's defensive perimeter. The maximum
Xnumber of guns for a ship is prortional to the maximum number of guns
Xwhich the ship was originally constructed with, and the damage level
Xof the ship. As the ship accumulates more damage the number of guns
Xavailable decreases.
X
X   When a ship fires on a planet, the 'target sector' is designated.
XDamage will concentrate about the target sector, and decreases with
Xdistance from it. Note that a ship may only fire at a planet
Xif it is in orbit about it. When a ship fires at a planet, all enemy
Xships in orbit or landed on the planet with 'planetary defense on'
Xorders as well as the planet itself will retaliate against the attacking 
Xship. Therefore, it is usually a good idea to destroy the 'defending ships' 
Xbefore actually attacking the planet, unless, of course, you have a 
Xreason for it. The damage to planet sectors depends on the number
Xof guns fired, as well as the efficiencies of the sectors and terrain
Xtypes. Some sectors will mutate into other sector types. A sector can be
X'wasted', killing all inhabitants - or population will be killed.
XIt is also important to note that guns from a planet MAY NOT
Xattack itself. Toxicity of the planet can also increase from the ensuing
Xdestruction. When a sector is attacked, it may be mutated into another sector 
Xtype according to:
X			ice -> sea,
X			plated -> land,
X			sea -> land,
X			mountain -> land,
X			land -> sea or gas (depending on what kind of planet it's on),
X			gas doesn't get mutated.
X
X   Ship-to-ship combat is the 'essence' of the Galactic Bloodshed
Xcombat system. The program will compute the 'hit probability'.
XThis designates the chances that a particular gun will actually
Xhit the target ship with the potential of doing damage to it.
XWhen a player designates a 'salvo' of so many guns, each gun is
Xevaluated for hit/miss, the sum of all hits is then used to
Xdetermine the results of the salvo.
X
X   The hit probability depends on several factors
X
X  1) The technology of firing ship. The higher the technology,
X	the more accurate the firing vessels shots are.
X
X  2) The size of the target vessel. Larger targets are easier to hit.
X
X  3) The speed of the firing and target ships. It is assumed that
X	the motions of the ships can affect the chances of hitting
X	the target.
X
X  4) Whether or not 'evasive maneuvers' have been order for
X	the ship in question.
X
X   The hit probability can be found from the 'tactical' display
Xand the formula used to determine the hit probability is
X
X	probability = 100 / ( 1 + range / 50% range).
X
XWhen the range = 50% range the chances of hitting the target it
X50%. The 50% range, or 'effective radius' of a ships guns is
Xdetermined from the above factors as
X
X	50% range = ( 1 - exp (-tech / 200) ) * 500 *
X
X		body / (2 + fev) / ( 2 + fev) / (3 + fspd + tspd)
X
Xwhere
X
X		tech = the technology of the firing vessel
X			or of the race (for planet firing)
X
X		body = target size
X
X		fev = 0 or 1 for whether or not firing vessel
X				has evasive maneuvers
X
X		tev = defending ship evasive maneuvers
X
X		fspd = firing ship speed
X
X		tspd = target ship speed.
X
XNote, that a ship must actually be 'going somewhere' (plotted
Xmove in 'order') for the evasive and speed factors to be
Xtaken into effect (otherwise they are set to zero).
X
X
X   After the hit probability is determined each firing gun is
Xevaluated for hit/miss. The total number of hits is then compared
Xto the armor of the defending ship. The armor value of the ship
Xrepresents the amount of hits per salvo it can absorb without taking 
Xany structural damage at all (exception - see 'critical hits' below).
XThe structural damage to the ship is evaluated by the formula
X
X	% damage = 30 * ( hits - armor) / body.
X
XIf hits <= armor no structural damage is evaluated. Bigger ships
X(represented by body) can absorb more hits less ensuing damage
Xthan little ships. Also notice that smaller ships, although
Xharder to hit, are easier to damage *when* hit.
X
X
X
X   After evaluating for structural damage, the program then checks for
X'critical hits'. EACH hit is evaluated, whether or not any real
Xstructural damage has occured on the target vessel. The chances
Xof a critical hit depends on the size of the target ship.
XSpecifically
X
X		critical hit probability = 10 * body : 1.
X
XSmaller ships are more likely to suffer damage from critical hits
Xthan big ships. As an example, a Battleship with a size of
X45 has a 450:1 odds of taking a critical hit from each hit.
XA fighter group with a size of 10 has a 100:1 odds against such
Xa hit. Note, if you throw LOTS of fire power at an object you
Xmay get one. (You can also recall the story of David and Goliath!)
XEach critical hit is then evaluated. A random amount of damage
Xbetween 1 and 100% is assessed for each hit, in addition to the 
Xnormal structural damage.
X
X
XDefensive and Offensive Combat Options
X
X   A player may set up his own defense/response networks.
XSpecifically, in the 'order' command, a player may designate
Xhis ships to retaliate (default) if they are attacked.
XWhenever you fire at a ship, if you have done any damage to
Xhis ship, your ship will return fire immediately, thereby
Xdamaging the attacker. The retaliate option can be toggled on
Xand off, depending on the players intentions. A player may
Xalso designate his ships to defend other ships, so that is
Xyour ship is attacked and damaged, all other ships designated
Xto 'protect' the ship will fire back at the attacking vessel.
X
X   Ships may also be designated to be on 'plantary defense'
Xalert. If the planet is attacked, all ships defending will
Xretaliate against the intruder.
X
X
X
XSEE ALSO
X  tactical, mobilize, order
X
X
END_OF_FILE
if test 6455 -ne `wc -c <'Docs/fire.doc'`; then
    echo shar: \"'Docs/fire.doc'\" unpacked with wrong size!
fi
# end of 'Docs/fire.doc'
fi
if test -f 'client/GB_client.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'client/GB_client.c'\"
else
echo shar: Extracting \"'client/GB_client.c'\" \(6113 characters\)
sed "s/^X//" >'client/GB_client.c' <<'END_OF_FILE'
X/************************************************************************/
X/* TinyTalk: the real good stuff (network connections, main loop).	 */
X/* */
X/* Version 1.0 [ 1/24/90] : Initial implementation by ABR.		 */
X/* 1.1 [ 1/25/90] : Changed for systems without FD_SET.	 */
X/* 1.2 [ 1/26/90] : Added "quiet" and "nologin" control.	 */
X/* 1.3 [ 1/27/90] : Increased max number of 'quiet' lines.	 */
X/* */
X/************************************************************************/
X
X/* particular routines chosen for GB interface by Garrett van Cleef */
X/* modifications for the GB interfacing copyright 1990 Garrett W. van Cleef */
X
X#include "TinyMUD_copyright.h"
X
X#include <sys/types.h>
X#include <sys/time.h>
X#include <sys/socket.h>
X#include <netdb.h>
X#include <netinet/in.h>
X#include <fcntl.h>
X#include <sys/errno.h>
X#include <stdio.h>
X#include <curses.h>
X#include "client.h"
X
Xint             errno;
X
X/* For BSD 4.2 systems. */
X#ifndef FD_ZERO
X#define OLD_BSD_FDSETS
X#include "ultrix_cpt.h"
X#endif
X/* End of BSD 4.2 systems. */
X
X#define REFRESH_TIME 500000	/* Microseconds */
X
X#ifndef GB_HOST
X#define GB_HOST "pooh.caltech.edu"	/* change these for the host system */
X#endif
X
X#ifndef GB_PORT
X#define GB_PORT "2010"
X#endif
X
Xextern char		*index(), *malloc();
Xextern struct hostent	*gethostbyname();
Xextern unsigned long 	 inet_addr();
X
Xstatic int      current_socket;
Xstatic int      connected;	/* Are we connected? */
Xhugestr         current_output;	/* Queued as messages arrive. */
Xstatic int      need_refresh;	/* Does input line need refresh? */
Xstatic int      done;		/* Are we all done? */
X
Xmain()
X{
X	initscr();		/* set up screen for graphics */
X	init_keyboard();
X	client();
X}
X
X
Xclient()
X{
X	int             count;
X	fd_set          readers, exceptions;
X	struct timeval  refresh_timeout;
X	struct timeval *tv;
X	smallstr        host, port;
X
X	printf("           Galactic Bloodshed Client ver %s\n",VERS);
X
X
X	sprintf(host, "%s", GB_HOST);
X	sprintf(port, "%s", GB_PORT);
X
X	connected = FALSE;
X
X	connect_to(host, port);
X
X	*current_output = '\0';	/* No output yet. */
X
X	done = FALSE;
X
X	need_refresh = 0;	/* No keyboard typing yet. */
X
X	do {			/* main loop */
X		FD_ZERO(&readers);
X		FD_ZERO(&exceptions);
X		FD_SET(0, &readers);	/* Check standard input. */
X		FD_SET(current_socket, &readers);	/* Check socket. */
X
X		if (need_refresh) {
X			refresh_timeout.tv_sec = 0;
X			refresh_timeout.tv_usec = REFRESH_TIME;
X			tv = &refresh_timeout;
X		} else
X			tv = NULL;
X
X		count = select(current_socket + 1, &readers, NULL, &exceptions,
X		    tv);
X		if (count == -1) {
X			if (errno != EINTR)	/* Control-Z will do this. */
X				perror("select");
X		} else if (count == 0) {
X			do_refresh();
X		} else {
X			/* always check this, even after a command is issued */
X			if (FD_ISSET(current_socket, &readers)) {
X				handle_socket_input();
X			} else if (FD_ISSET(0, &readers)) {
X				/* look for conferencing */
X				if (need_refresh)
X					do_refresh();
X				handle_keyboard_input();
X			}
X		}
X
X	} while (!done);
X
X	disconnect();
X	cleanup_keyboard();
X}
X
Xconnect_to(host, port)		/* Try to make a connection. */
X	smallstr        host, port;
X{
X	struct in_addr  host_address;
X	struct sockaddr_in socket_address;
X	int             err;
X
X	/* register int current_socket; */
X
X	get_host_address(host, &host_address);
X
X	socket_address.sin_family = AF_INET;
X	socket_address.sin_port = htons(atoi(port));
X	bcopy(&host_address, &socket_address.sin_addr, sizeof(struct in_addr));
X
X	current_socket = socket(AF_INET, SOCK_STREAM, 0);
X	if (current_socket < 0) {
X		perror("Couldn't open socket");
X		die("Exiting.\n");
X	}
X	err = connect(current_socket, &socket_address, 
X	    sizeof(struct sockaddr_in));
X	if (err < 0) {
X		perror("Couldn't connect to socket");
X		die("Exiting.\n");
X	}
X	fcntl(current_socket, F_SETFL, FNDELAY);	/* Do we need this? */
X
X	connected = TRUE;
X	return;
X}
X
Xget_host_address(name, addr)	/* Get a host address. */
X	char           *name;
X	struct in_addr *addr;
X{
X	struct hostent *temp;
X	if (*name == '\0')
X		die("No host address specified.\n");
X
X	temp = gethostbyname(name);
X
X	if (temp == NULL)
X		die("Couldn't find host %s.\n", name);
X
X	bcopy(temp->h_addr, addr, sizeof(struct in_addr));
X}
X
X
Xdisconnect()
X{				/* Disconnect from current world. */
X	if (connected)
X		close(current_socket);
X
X	connected = FALSE;
X}
X
Xint 
Xtransmit(s, l)			/* Send a message over the socket. */
X	char           *s;
X	int             l;
X{
X	int             err;
X
X	err = send(current_socket, s, l, 0);
X	if (err == -1)
X		perror("send failed");
X
X	return err;
X}
X
Xint 
Xreceive(s)
X	char           *s;
X{
X	int             count;
X
X	count = recv(current_socket, s, MAXSTRLEN-1, 0);
X	if (count == -1) {
X		if (errno == EWOULDBLOCK)
X			*s = '\0';
X		else {
X			perror("recv failed");
X		}
X	} else
X		s[count] = '\0';
X
X	if (count <= 0)		/* Don't ask me. */
X		done = TRUE;
X
X	return count;
X}
X
X
Xclear_refresh_pending()
X{
X	need_refresh = 0;
X}
X
Xset_refresh_pending()
X{
X	need_refresh = 1;
X}
X
Xhandle_socket_input()
X{
X	string          blob;
X	hugestr         bigblob;
X	char           *place;
X
X	receive(blob);
X	strcat(current_output, blob);	/* Concatenate this bunch of input. */
X
X	if (current_output[0] != '#' && current_output[0] != '$') {
X		/* text data coming in */
X
X		place = index(current_output, '\n');	/* Output any whole
X							 * lines.  */
X		if (place != NULL) {
X			erase_keyboard_input();	/* Clear current line. */
X			while (place != NULL) {
X				*place = NULL;
X				print_with_wrap(current_output);
X				strcpy(bigblob, place + 1);
X					/* Rest of buffer. */
X				strcpy(current_output, bigblob);
X					/* Copy it back to buffer. */
X				place = index(current_output, '\n');
X			}
X		}
X		if (strlen(current_output) > 0) {
X			printf("%s", current_output);
X		}
X		if (strlen(current_output) > MAXSTRLEN) {
X			/* Too long, flush it. */
X			erase_keyboard_input();	/* Clear current line. */
X			print_with_wrap(current_output);
X		}
X	} else {		/* map data coming in */
X		if (current_output[0] == '#') {	/* orbit map */
X			plot_orbit(current_output);
X		} else if (current_output[0] == '$') {	/* planet map */
X			plot_surface(current_output);
X		}
X	}
X	*current_output = '\0';	/* Flush the buffer. */
X}
END_OF_FILE
if test 6113 -ne `wc -c <'client/GB_client.c'`; then
    echo shar: \"'client/GB_client.c'\" unpacked with wrong size!
fi
# end of 'client/GB_client.c'
fi
if test -f 'server/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'server/Makefile'\"
else
echo shar: Extracting \"'server/Makefile'\" \(4891 characters\)
sed "s/^X//" >'server/Makefile' <<'END_OF_FILE'
X# Galactic Bloodshed (Robert Chansky, smq@b)
X# Makefile	(modified by billr@saab.cna.tek.com)
X
X# (the -pipe -g are for development.)
X# $UV, if used, is generally defined in the top level makefile. It's set
X# to -DBSD4_2 for BSD 4.2 derived systems (e.g. SunOS 3.X) that don't
X# have tm_zone as a member of the "tm" struct (see <time.h>).
X# $(HP) comes from top level makefile for host and port info.
XCFLAGS = -O $(UV) $(HP)
X#CFLAGS = -g $(HP)
X#CFLAGS = -pipe -g 
X
X# objects for shell
XSHOBJS =  getplace.o	\
X	read_teleg.o	\
X	teleg_send.o	\
X	autoreport.o	\
X	order.o		\
X	shootblast.o	\
X	explore.o	\
X	relation.o	\
X	mobiliz.o	\
X	shlmisc.o	\
X	enslave.o	\
X	capitol.o	\
X	toggle.o	\
X	survey.o	\
X	files.o		\
X	zoom.o		\
X	perm.o		\
X	prof.o		\
X	GB_server.o	\
X	name.o		\
X	fire.o		\
X	land.o		\
X	tech.o		\
X	map.o		\
X	max.o		\
X	move.o		\
X	capture.o	\
X	cs.o		\
X	rst.o		\
X	misc.o		\
X	rand.o		\
X	load.o		\
X	scrap.o		\
X	build.o		\
X	orbit.o		\
X	power.o		\
X	launch.o	\
X	declare.o	\
X	examine.o	\
X	toxicity.o	\
X	get4args.o	\
X	files_rw.o	\
X	files_shl.o 	\
X	moveplanet.o	\
X	autoshoot.o	\
X	doplanet.o	\
X	doturn.o	\
X	VN.o		\
X	doship.o	\
X	dosector.o	\
X	moveship.o
X
X
X# depend on vars.h and races.h
XVROBJS = getplace.o	\
X	autoreport.o	\
X	order.o		\
X	mobiliz.o	\
X	shlmisc.o	\
X	capitol.o	\
X	toggle.o	\
X	enrol.o		\
X	max.o		\
X	move.o		\
X	capture.o	\
X	zoom.o		\
X	toxicity.o	\
X	doplanet.o	\
X	shootblast.o	\
X	autoshoot.o	\
X	moveship.o	\
X	explore.o	\
X	relation.o	\
X	dosector.o	\
X	declare.o	\
X	survey.o	\
X	prof.o		\
X	perm.o		\
X	rst.o		\
X	GB_server.o	\
X	VN.o		\
X	cs.o		\
X	max.o		\
X	map.o		\
X	scrap.o		\
X	name.o		\
X	fire.o		\
X	power.o		\
X	doturn.o	\
X	doship.o	\
X	makeuniv.o	\
X	makeplanet.o
X
X
X# depend on ships.h and vars.h
XSHIPOBJS = autoreport.o	\
X	order.o		\
X	shootblast.o	\
X	makeplanet.o	\
X	enrol.o		\
X	examine.o	\
X	capitol.o	\
X	enslave.o	\
X	relation.o	\
X	capital.o	\
X	survey.o	\
X	launch.o	\
X	build.o		\
X	enrol.o		\
X	fire.o		\
X	land.o		\
X	map.o		\
X	max.o		\
X	move.o		\
X	capture.o	\
X	cs.o		\
X	VN.o		\
X	rst.o		\
X	load.o		\
X	name.o		\
X	prof.o		\
X	scrap.o		\
X	orbit.o		\
X	doturn.o	\
X	doship.o	\
X	doplanet.o	\
X	moveship.o	\
X	autoshoot.o	\
X	moveplanet.o	\
X	files_shl.o
X
X# depend on files.h
XFOBJS =	files_shl.o 	\
X	files_rw.o	\
X	makeuniv.o	\
X	shlmisc.o 	\
X	doturn.o 	\
X	enrol.o 	\
X	files.o		\
X	GB.o 		\
X	build.o		\
X	power.o 	\
X	daemon.o	\
X	examine.o
X
X
X# dont depend on anything
XNOOBJS = get4args.o	\
X	misc.o		\
X	rand.o		\
X	daemon.o	\
X	files_rw.o
X
X# objects for enrol
XEOBJS = enrol.o		\
X	files_shl.o	\
X	files_rw.o	\
X	files.o		\
X	max.o		\
X	perm.o		\
X	rand.o		\
X	shlmisc.o
X
X# objects for fix
XFIXOBJS = fix.o		\
X	files_shl.o	\
X	files_rw.o	\
X	getplace.o	\
X	shlmisc.o	\
X	files.o
X
Xall: GB_server GB_enroll mor GB_daemon makeuniv fix trav
X
X# the shell 
XGB_server : ${SHOBJS}
X	cc -o GB_server ${SHOBJS}  -lcurses -ltermcap -lm
X
X${VROBJS}: races.h vars.h
X${SHIPOBJS}: vars.h ships.h
X${FOBJS}: files.h
Xbuild.o : vars.h ships.h races.h shipdata.h
Xpower.o files_shl.o : power.h
Xdoturn.o doship.o doplanet.o moveship.o moveplanet.o : doturn.h
Xmoveship.o : vars.h ships.h shipdata.h
Xdoturn.o doplanet.o doship.o : power.h
X
X#fix it program
Xfix : ${FIXOBJS}
X	cc -o fix ${FIXOBJS} -lcurses -ltermcap -lm
X
X#sizes : vars.h ships.h races.h
X#	 sizes.c
X
X# make data files program
Xmakeuniv : makeuniv.o makeplanet.o rand.o perm.o
X	cc -o makeuniv makeuniv.o makeplanet.o rand.o perm.o files.o -lm
Xmakeuniv.o : power.h
X
X
X# the daemon (actually it calls the update)
XGB_daemon : daemon.o
X	cc -o GB_daemon daemon.o
X
X# the enrollment program
XGB_enroll : ${EOBJS}
X	cc -o GB_enroll ${EOBJS} -lcurses -ltermcap -lm
Xenrol.o : vars.h ships.h shipdata.h races.h
X
X# more clone
Xmor : more.c
X	cc -g -o mor more.c
X
X#trav
Xtrav : traverse.o files_rw.o files_shl.o files.o
X	cc -o trav traverse.o files_rw.o files_shl.o files.o
X
Xchmod:
X	chmod ag+xs GB
X	chmod g+rwx Data Data/* Data/Tele/*
X	chmod a+rx Docs Docs/*
X	chmod g+r *.dat*
X	chmod a+x mor
X#	chmod ga+rwx Data Data/* Data/Tele/*
X
Xstart:
X	/bin/rm -f Data/spitup
X	GB_daemon 4 > /dev/null
X
Xclean:
X	/bin/rm -rf GB_server GB_enroll makeuniv GB_daemon mor fix \
X		trav *.o core a.out
X
Xclear:
X	/bin/rm -rf *.o core a.out
X
X
X# shar it up for transport.
Xshar:
X	/bin/cp Docs/*.doc* .
X#	-uncompress enroll.dat.Z *.doc*
X	shar README Makefile *.script *.doc *.h *.c planet.list *.dat > GB.shar
X#	-compress enroll.dat
X#	compress GB.shar
X	/bin/rm -f *.doc
X
X# shar up the docs.
Xshardocs:
X	uncompress Docs/*.doc*
X	shar README *.doc* > GBdocs.shar
X	compress Docs/*.doc*
X
X# make the game ftpable by netters.
Xpublic:
X	/bin/cp Docs/* .
X	uncompress enroll.dat.Z 
X	shar -c README Makefile *.doc *.h *.c planet.list *.dat > /tmp/GB.shar
X	compress enroll.dat
X	compress /tmp/GB.shar
X	/bin/cp /tmp/GB.shar.Z /usr/ftp/pub/games
X	/bin/rm -f /tmp/GB.shar.Z
X	chmod a+r /usr/ftp/pub/games/GB.shar.Z
X	/bin/rm -f *.doc
X
X# install the game for public use.
Xinstall:
X	make
X	mkdir Docs
X	mv *.doc Docs
X	compress Docs/* enroll.dat
X	makeuniv < planet.list
X	make chmod
X
END_OF_FILE
if test 4891 -ne `wc -c <'server/Makefile'`; then
    echo shar: \"'server/Makefile'\" unpacked with wrong size!
fi
# end of 'server/Makefile'
fi
if test -f 'server/autoshoot.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'server/autoshoot.c'\"
else
echo shar: Extracting \"'server/autoshoot.c'\" \(6147 characters\)
sed "s/^X//" >'server/autoshoot.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.c, enroll.dat.
X * Restrictions in GB.c.
X * autoshoot() -- shoot <-> retaliate routine
X * Bombard() -- ship bombards planet
X */
X
X#define EXTERN extern
X#include "vars.h"
X#include "ships.h"
X#include "races.h"
X#include "doturn.h"
X#include "buffers.h"
X
Xint fire_toshdata;
Xint bomb_shdata, bomb_sectdata;
X
X/* ship #shipno bombards planet, then alert whom it may concern.
X */
XBombard(ship, shipno, planet, r)
Xshiptype *ship;
Xint shipno;
Xplanettype *planet;
Xracetype *r;
X{
Xshiptype *s;
Xint x,y,x2= -1,y2,oldown,numdest=0,numdest2=0,found=0;
Xint i, stren, stren0, stren1, stren2, sh, numretal=0;
Xint ok;
Xfloat dist,tech;
Xboolean whocares;
X
X  /* for telegramming */
X  bzero((char *)Nuked, sizeof(Nuked));
X
X/* check to see if PDNs are present */
Xok = 1;
Xsh = planet->ships;
Xopenshdata(&bomb_shdata);
Xwhile(sh && ok) {
Xgetship(bomb_shdata, &s, sh);
Xok = !(s->is_alive && s->type==OTYPE_PLANDEF && s->owner != ship->owner);
Xsh = s->nextship;
Xfree(s);
X}
Xclose_file(bomb_shdata);
Xif(!ok) {
X    sprintf(buf, "Bombardment of %s cancelled, PDNs are present.\n",
X	    prin_ship_orbits(ship));
X    if(!notify(ship->owner, buf))
X	push_message(TELEG_PLAYER_AUTO, ship->owner, buf);
X    return;
X}
X
Xopensectdata(&bomb_sectdata);
X  getsmap(bomb_sectdata, Smap, planet);
X  close_file(bomb_sectdata);
X
X /* look for someone to bombard-check for war */
X  Getxysect(planet,0,0,1);	/* reset */
X  while (!found && Getxysect(planet,&x,&y,0)) {
X	if (Sector(*planet,x,y).owner && Sector(*planet,x,y).owner!=ship->owner
X	    && !Sector(*planet,x,y).is_wasted) {
X	  if (isset(r->atwar, Sector(*planet,x,y).owner) ||
X		  (ship->type==OTYPE_BERS && 
X	          Sector(*planet,x,y).owner==ship->object.number))
X		found=1;
X	  else
X		x2=x,y2=y;
X	}
X  }
X  if (x2 != -1) {
X	x = x2;		/* no one we're at war with; bomb someone else. */
X	y = y2;
X	found = 1;
X  }
X
X  if (found) {
X	placetype from,to;
X	int str;
X    str = MIN(Shipdata[ship->type][ABIL_GUNS]*(100-ship->damage)/100., ship->destruct);
X	/* save owner of destroyed sector */
X    if (str) {
X	bzero(Nuked, sizeof(Nuked));
X    	oldown = Sector(*planet,x,y).owner;
X    	ship->destruct -= str;
X    	ship->mass -= str * MASS_DESTRUCT;
X    	from.level = LEVEL_SHIP;
X    	from.shipptr = ship;
X    	from.shipno = shipno;
X    	to.level = LEVEL_PLAN;
X    	to.snum = ship->storbits;
X    	to.pnum = ship->pnumorbits;
X    	numdest = shoot(ship->owner, from, &to, ship->owner, (planettype *)NULL,
X		   planet, x,y, str, &dist, ship->tech, telegram_buf,0);
X	/* (0=dont get smap) */
X	if(numdest < 0) numdest = 0;
X
X      	/* tell the bombarding player about it.. */
X    	sprintf(telegram_buf,"REPORT from ship #%d\n\n",shipno);
X     	sprintf(buf,"%s #%d %s reports bombing of planet /%s/%s,\n",
X 			Shipnames[ship->type], shipno, ship->name,
X			Stars[ship->storbits]->name,
X			Stars[ship->storbits]->pnames[ship->pnumorbits]);
X	str_cat(telegram_buf, buf);
X    	sprintf(buf,"sector %d,%d (owner %d).  %d sectors destroyed.\n",
X			x, y, oldown, numdest);
X	str_cat(telegram_buf, buf);
X	notify(ship->owner, telegram_buf); 
X
X     /* notify other player. */
X    	sprintf(telegram_buf,"ALERT from planet /%s/%s\n\n",
X			Stars[ship->storbits]->name,
X			Stars[ship->storbits]->pnames[ship->pnumorbits]);
X     	sprintf(buf,"%s #%d %s Bombarded sector %d,%d; %d sectors destroyed.\n"
X 		,Shipnames[ship->type], shipno, ship->name, x, y, numdest);
X	str_cat(telegram_buf, buf);
X	for (i=1; i<=Num_races; i++)
X	   if (Nuked[i-1] && i != ship->owner)
X		notify(i, telegram_buf);
X
X
X/* enemy planet retaliates along with defending forces */
X
X
X	stren = 0;
X	tech = 0.0;
X	for (i=1; i<= Num_races; i++)
X	  if (i!=ship->owner && planet->info[i-1].numsectsowned) {
X		stren0 = 0;
X		stren1 = 0;
X		stren2 = 0;
X		/* go through linked list of ships orbiting the planet */
X		/* only add ships ordered to defend planet */
X		/* averaging the tech */
X		sh = planet->ships;
X
X		while (sh) {
X
X		  to.shipptr = ships[sh];
X		  if (to.shipptr->owner==i && to.shipptr->protect.planet) {
X
X		    stren0 = MIN(to.shipptr->destruct,
X			Shipdata[to.shipptr->type][ABIL_GUNS]*(100-to.shipptr->damage)/100.);
X		    tech += to.shipptr->tech;
X		    numretal++;
X		    stren1 += stren0;
X		    to.shipptr->destruct -= stren0;
X		    to.shipptr->mass -= stren0 * MASS_DESTRUCT;
X		  }
X		  sh = to.shipptr->nextship;
X		}
X/* add planet defense strength */
X
X		stren2 = planet->info[i-1].destruct;
X		if(stren2 > PLAN_FIRE_LIM)
X			stren2 = PLAN_FIRE_LIM;
X		planet->info[i-1].destruct -= stren2;
X
X		if (stren2>0)
X			numretal++;
X
X		tech = 100.;
X		stren += stren1;
X		stren += stren2;
X      	/* tell the involved players about it.. */
X
X
X/* execute attack */
X
X    	numdest2 = shoot(1, to, &from, i, planet, (planettype *)NULL,x,y,stren,
X		&dist, tech/numretal, telegram_buf, 0);	/* (0=dont get smap) */
X
X    	sprintf(telegram_buf,"REPORT: Ship #%d Bombardment.\n\n",shipno);
X		if(stren1) {
X	sprintf(buf,"Defending ships return fire, total strength %d \n",stren1);
X		str_cat(telegram_buf, buf);
X      }
X	sprintf(buf,"Planet returns fire with strength %d \n",stren2);
X		str_cat(telegram_buf, buf);
X	sprintf(buf,"%d percent damage to Ship #%d \n",numdest,shipno);
X		str_cat(telegram_buf, buf);
X
X	for (i=1; i<=Num_races; i++)
X	  if (Nuked[i-1])
X    		notify(oldown, telegram_buf);
X
X      }
X
X    } else {
X		/* no weapons! */
X	if (!ship->notified) {
X		ship->notified = 1;
X		sprintf(telegram_buf, 
X 		  "Bulletin\n\n %s #%d %s has no weapons to bombard with.\n",
X 		   Shipnames[ship->type],shipno,ship->name);
X		notify(ship->owner, telegram_buf);
X	}
X    }
X
X	opensectdata(&bomb_sectdata);
X    putsmap(bomb_sectdata, Smap, planet);
X    close_file(bomb_sectdata);
X
X  } else {
X	 /* there were no sectors worth bombing. */
X    if (!ship->notified) {
X	ship->notified = 1;
X     	sprintf(telegram_buf,"Report from %s #%d %s\n\n",
X		Shipnames[ship->type], shipno,ship->name);
X    	sprintf(buf,"Planet /%s/%s has been saturation bombed.\n",
X		Stars[ship->storbits]->name,
X		Stars[ship->storbits]->pnames[ship->pnumorbits]);
X	str_cat(telegram_buf, buf);   
X	notify(ship->owner, telegram_buf); 
X    }
X  }
X  return numdest;
X
X}
END_OF_FILE
if test 6147 -ne `wc -c <'server/autoshoot.c'`; then
    echo shar: \"'server/autoshoot.c'\" unpacked with wrong size!
fi
# end of 'server/autoshoot.c'
fi
if test -f 'server/cs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'server/cs.c'\"
else
echo shar: Extracting \"'server/cs.c'\" \(6679 characters\)
sed "s/^X//" >'server/cs.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 *  cs.c -- change scope (directory)
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"
Xint cs_racedata;
X
Xcenter(Playernum, APcount, argn, args)
Xint Playernum;
Xint APcount;
Xint argn;
Xchar args[MAXARGS][COMMANDSIZE];
X{
Xplacetype where;
X
X  where = Getplace(Playernum,args[1],0);	/* do not ignore the fact that you've not
X					explored the place */
X  if (where.err) {
X	sprintf(buf,"cs: bad scope.\n");
X		notify(Playernum, buf);
X	return;
X  }
X
XDir[Playernum-1].lastx[1] = Stars[where.snum]->xpos;
XDir[Playernum-1].lasty[1] = Stars[where.snum]->ypos;
X
X}
X
Xcs(Playernum, APcount, argn,args)
Xint Playernum;
Xint APcount;
Xint argn;
Xchar args[MAXARGS][COMMANDSIZE];
X{
X placetype where;
X planettype *planet;
X shiptype *s;
X int cs_shdata,cs_pdata;
X
Xfree(Race);
Xopenracedata(&cs_racedata);
Xgetrace(cs_racedata, &Race, Playernum); 
Xclose_file(cs_racedata);
X
Xif (argn==1) {
X	/* chdir to def scope */
X  Dir[Playernum-1].level = Race->deflevel;
X  if ((Dir[Playernum-1].snum = Race->defsystem) >= Sdata.numstars)
X	Dir[Playernum-1].snum = Sdata.numstars-1;
X  if ((Dir[Playernum-1].pnum = Race->defplanetnum) >= Stars[Dir[Playernum-1].snum]->numplanets)
X	Dir[Playernum-1].pnum = Stars[Dir[Playernum-1].snum]->numplanets-1;
X  Dir[Playernum-1].shipno = 0;
X  Dir[Playernum-1].lastx[0] = Dir[Playernum-1].lasty[0] = 0.0;
X  Dir[Playernum-1].lastx[1] = Stars[Dir[Playernum-1].snum]->xpos;
X Dir[Playernum-1].lasty[1] = Stars[Dir[Playernum-1].snum]->ypos;
X
X		sprintf(Dir[Playernum-1].prompt,"  ( [%02d] %s / %s )\n ",
X			Stars[Dir[Playernum-1].snum]->AP[Playernum-1],
X			Stars[Dir[Playernum-1].snum]->name,
X			Stars[Dir[Playernum-1].snum]->pnames[Dir[Playernum-1].pnum]);
X
X    return;
X } else if (argn==2) {
X	/* chdir to specified scope */
X
X  where = Getplace(Playernum,args[1],0);	/* do not ignore the fact that you've not
X					explored the place */
X  if (where.err) {
X	sprintf(buf,"cs: bad scope.\n");
X		notify(Playernum, buf);
X	Dir[Playernum-1].lastx[0] = Dir[Playernum-1].lasty[0] = 0.0;
X	return;
X  }
X
X	/* fix lastx, lasty coordinates */
X
X  switch (Dir[Playernum-1].level) {
X
X	case LEVEL_UNIV:
X		Dir[Playernum-1].lastx[0] = Dir[Playernum-1].lasty[0] = 0.0;
X		break;
X
X	case LEVEL_STAR:
X		if (where.level==LEVEL_UNIV) {
X			Dir[Playernum-1].lastx[1] = Stars[Dir[Playernum-1].snum]->xpos;
X			Dir[Playernum-1].lasty[1] = Stars[Dir[Playernum-1].snum]->ypos;
X		} else
X			Dir[Playernum-1].lastx[0] = Dir[Playernum-1].lasty[0] = 0.0;
X		break;
X
X	case LEVEL_PLAN:
X		openpdata(&cs_pdata);
X		getplanet(cs_pdata,&planet,Stars[Dir[Playernum-1].snum]->planetpos[Dir[Playernum-1].pnum]);
X		close_file(cs_pdata);
X		if (where.level==LEVEL_STAR && where.snum==Dir[Playernum-1].snum) {
X			Dir[Playernum-1].lastx[0] = planet->xpos;
X			Dir[Playernum-1].lasty[0] = planet->ypos;
X		} else if (where.level==LEVEL_UNIV) {
X			Dir[Playernum-1].lastx[1] = Stars[Dir[Playernum-1].snum]->xpos + planet->xpos;
X			Dir[Playernum-1].lasty[1] = Stars[Dir[Playernum-1].snum]->ypos + planet->ypos;
X		} else
X			Dir[Playernum-1].lastx[0] = Dir[Playernum-1].lasty[0] = 0.0;
X		free(planet);
X		break;
X	case LEVEL_SHIP:
X		openshdata(&cs_shdata);
X		getship(cs_shdata, &s, Dir[Playernum-1].shipno);
X		close_file(cs_shdata);
X		if (!s->is_docked) {
X		 switch (where.level) {
X		   case LEVEL_UNIV:
X			Dir[Playernum-1].lastx[1] = s->xpos;
X			Dir[Playernum-1].lasty[1] = s->ypos;
X			break;
X		   case LEVEL_STAR:
X			if (s->whatorbits>=LEVEL_STAR && s->storbits==where.snum) {
X				/* we are going UP from the ship.. change last*/
X				Dir[Playernum-1].lastx[0] = s->xpos - Stars[s->storbits]->xpos;
X				Dir[Playernum-1].lasty[0] = s->ypos - Stars[s->storbits]->ypos;
X			} else
X				Dir[Playernum-1].lastx[0] = Dir[Playernum-1].lasty[0] = 0.0;
X			break;
X		   case LEVEL_PLAN:
X			if (s->whatorbits==LEVEL_PLAN && s->storbits==where.snum
X				   && s->pnumorbits==where.pnum) {
X				/* same */
X				openpdata(&cs_pdata);
X				getplanet(cs_pdata,&planet,Stars[s->storbits]->planetpos[s->pnumorbits]);
X				close_file(cs_pdata);
X				Dir[Playernum-1].lastx[0] = s->xpos - Stars[s->storbits]->xpos - planet->xpos;
X				Dir[Playernum-1].lasty[0] = s->ypos - Stars[s->storbits]->ypos - planet->ypos;
X				free(planet);
X			} else
X				Dir[Playernum-1].lastx[0] = Dir[Playernum-1].lasty[0] = 0.0;
X			break;
X		   case LEVEL_SHIP:
X			Dir[Playernum-1].lastx[0] = Dir[Playernum-1].lasty[0] = 0.0;
X			break;
X		   default:
X			break;
X		 }
X		} else
X			Dir[Playernum-1].lastx[0] = Dir[Playernum-1].lasty[0] = 0.0;
X		free(s);
X		break;
X	default:
X		break;
X  }
X
X  Dir[Playernum-1].level = where.level;
X  Dir[Playernum-1].snum = where.snum;
X  Dir[Playernum-1].pnum = where.pnum;
X  Dir[Playernum-1].shipno = where.shipno;
X
X   /* fix prompt */
X      switch (Dir[Playernum-1].level) {
X    	case LEVEL_UNIV:
X		sprintf(Dir[Playernum-1].prompt," ( [%02d] / )\n ",Sdata.AP[Playernum-1]);
X		break;
X    	case LEVEL_STAR:
X  		sprintf(Dir[Playernum-1].prompt,"  ( [%02d] %s )\n",
X			Stars[Dir[Playernum-1].snum]->AP[Playernum-1],
X			Stars[Dir[Playernum-1].snum]->name);
X		break;
X	case LEVEL_SHIP:
X		switch (where.shipptr->whatorbits) { 	/* what orbits around */
X		    case LEVEL_UNIV:
X			sprintf(Dir[Playernum-1].prompt," ( [%02d] / #%d )\n ",
X				Stars[Dir[Playernum-1].snum]->AP[Playernum-1],
X				where.shipno);
X			break;
X    		    case LEVEL_STAR:
X  			sprintf(Dir[Playernum-1].prompt,"  ( [%02d] %s / #%d )\n ",
X				Stars[Dir[Playernum-1].snum]->AP[Playernum-1],
X				Stars[Dir[Playernum-1].snum]->name,
X				where.shipno);
X			break;
X		    case LEVEL_PLAN:
X			sprintf(Dir[Playernum-1].prompt,"  ( [%02d] %s / %s / #%d )\n ",
X				Stars[Dir[Playernum-1].snum]->AP[Playernum-1],
X				Stars[Dir[Playernum-1].snum]->name,
X				Stars[Dir[Playernum-1].snum]->pnames[Dir[Playernum-1].pnum],
X				where.shipno);
X			break;
X		}
X		free(where.shipptr);
X		break;
X	case LEVEL_PLAN:
X		sprintf(Dir[Playernum-1].prompt,"  ( [%02d] %s / %s )\n ",
X			Stars[Dir[Playernum-1].snum]->AP[Playernum-1],
X			Stars[Dir[Playernum-1].snum]->name,
X			Stars[Dir[Playernum-1].snum]->pnames[Dir[Playernum-1].pnum]);
X		break;
X	default: break;
X      }
X
X } else if (argn==3 && args[1][1]=='d') {
X	/* make new def scope */
X  where = Getplace(Playernum,args[2],0);
X  if (!where.err) {
X	Race->deflevel = where.level;
X	Race->defsystem = where.snum;
X	Race->defplanetnum = where.pnum;
Xopenracedata(&cs_racedata);
X    putrace(cs_racedata, Race);
Xclose_file(cs_racedata);
X
X	sprintf(buf,"New home system is %s\n",Dispplace(Playernum, &where));
X  } else {
X	sprintf(buf,"cs: bad home system.\n");
X	return;
X  }
X }
X}
END_OF_FILE
if test 6679 -ne `wc -c <'server/cs.c'`; then
    echo shar: \"'server/cs.c'\" unpacked with wrong size!
fi
# end of 'server/cs.c'
fi
if test -f 'server/explore.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'server/explore.c'\"
else
echo shar: Extracting \"'server/explore.c'\" \(6315 characters\)
sed "s/^X//" >'server/explore.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 * explore.c -- display systems/worlds explored 
X *  (this command written by Dan Corrin, dan@geomech.engrg.uwo.ca)
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"
Xextern float compatibility(); /* gvc modification */
Xint explore_racedata;
X
Xcolonies(Playernum,APcount, argn, args)
Xint Playernum;
Xint APcount, argn;
Xchar *args[];
X{
Xint star,i,j;
Xplanettype *pl;
Xint inhab = 0;
Xint stardata,pdata;
Xchar str[200];
X
X Num_races = Numraces();
X
Xfree(Race);
Xopenracedata(&explore_racedata);
Xgetrace(explore_racedata, &Race, Playernum);
Xclose_file(explore_racedata);
X
X openstardata(&stardata);
X getsdata(stardata,&Sdata);
X openpdata(&pdata);
X sprintf(buf,"             ========== Colonization Report ==========\n\n");
X	notify(Playernum, buf); 
Xsprintf(buf,"       Planet        res  des fuel tox sects tech  mob       Type       Aliens\n");
X	notify(Playernum, buf);
X for (star=0; star<Sdata.numstars; star++) {
X    getstar(stardata, &(Stars[star]), star);
X    if (isset(Stars[star]->explored,Playernum)) {
X        for (i=0; i<Stars[star]->numplanets; i++) {
X           getplanet(pdata,&pl,Stars[star]->planetpos[i]);
X
X           if (pl->info[Playernum-1].explored 
X	       && pl->info[Playernum-1].numsectsowned)  {
X                inhab = 0;
X
X		sprintf(str,"%s/%s%s", Stars[star]->name,
X			Stars[star]->pnames[i],
X			(pl->info[Playernum-1].autorep ? "*" : ""));
X
X		sprintf(buf,"%19s%5d%5d%5d %3d%% %4d %3d  %2d(%2d)",
X		       str,pl->info[Playernum-1].resource,
X		       pl->info[Playernum-1].destruct,
X		       pl->info[Playernum-1].fuel,pl->conditions[TOXIC],
X		       pl->info[Playernum-1].numsectsowned,
X		       pl->info[Playernum-1].tech_invest,
X		       pl->info[Playernum-1].comread,
X		       pl->info[Playernum-1].mob_set);
X			notify(Playernum, buf);
X
X                switch(pl->type) {
X                        case TYPE_EARTH:        sprintf(buf," Class M "); break;
X                        case TYPE_ASTEROID:     sprintf(buf," Asteroid"); break;
X                        case TYPE_AIRLESS:      sprintf(buf," Airless "); break;
X                        case TYPE_ICEBALL:      sprintf(buf," Iceball "); break;
X                        case TYPE_GASGIANT:     sprintf(buf," Jovian  "); break;
X			case TYPE_WATER:        sprintf(buf," Water   "); break;
X			default: 
X				sprintf(buf, "Unknown");
X				break;
X                }
X		notify(Playernum, buf);
X                sprintf(buf,"%3.0f%% ",compatibility(pl,Race));
X		notify(Playernum, buf);
X                for (j=1; j<=Num_races; j++) 
X			if (j!=Playernum && pl->info[j-1].numsectsowned>0)
X				{
X				sprintf(buf,"%d ",j);
X					notify(Playernum, buf);
X				}
X	notify(Playernum, "\n");
X           } 
X	   free(pl);
X        }
X    }
X }
X close_file(stardata);
X close_file(pdata);
X}
X
X
Xexploration(Playernum,APcount, argn,args)
Xint Playernum;
Xint APcount, argn;
Xchar args[MAXARGS][COMMANDSIZE];
X{
Xint star,starq,i,j;
Xplanettype *pl;
Xplacetype where;
Xint inhab = 0;
Xint stardata,pdata;
X
X Num_races = Numraces();
X
X	starq = 0;
X
Xif(argn==2) {
X	where = Getplace(Playernum,args[1],0);
X	if(where.err) {
X		sprintf(buf, "explore: bad scope.\n");
X			notify(Playernum, buf);
X		return;
X		}
X	starq = where.snum;
X	}
X
Xfree(Race);
Xopenracedata(&explore_racedata);
Xgetrace(explore_racedata, &Race, Playernum);
Xclose_file(explore_racedata);
X
X openstardata(&stardata);
X getsdata(stardata,&Sdata);
X openpdata(&pdata);
X sprintf(buf,"         ========== Exploration Report ==========\n");
X			notify(Playernum, buf);
X sprintf(buf," Global action points : [%2d]\n",Sdata.AP[Playernum-1]);
X 			notify(Playernum, buf);
Xsprintf(buf," Star  (stability)[AP]   #  Planet [Attributes] Type (Compatibility)\n");
X			notify(Playernum, buf);
X for (star=0; star<Sdata.numstars; star++)
X 	if((starq ==0) || (starq  && starq == star)) {
X    getstar(stardata, &(Stars[star]), star);
X    if (isset(Stars[star]->explored,Playernum)) {
X        for (i=0; i<Stars[star]->numplanets; i++) {
X           getplanet(pdata,&pl,Stars[star]->planetpos[i]);
X           if (i == 0)
X                if (Race->tech >= TECH_SEE_STABILITY){
X                    sprintf(buf,"\n%13s (%2d)[%2d]",Stars[star]->name,Stars[star]->stability,Stars[star]->AP[Playernum-1]);
X			notify(Playernum, buf);
X	} else {
X                    sprintf(buf,"\n%13s (??)[%2d]",Stars[star]->name,Stars[star]->stability,Stars[star]->AP[Playernum-1]);
X		notify(Playernum, buf);
X	} else {
X                sprintf(buf,"\t\t      ");
X		notify(Playernum, buf);
X		}
X           sprintf(buf,"  #%d. %-15s [ ",i+1,Stars[star]->pnames[i]);
X		notify(Playernum, buf);
X           if (pl->info[Playernum-1].explored)  {
X                sprintf(buf,"Expl ");
X		notify(Playernum, buf);
X                if (pl->info[Playernum-1].autorep) {
X		sprintf(buf,"Report ");
X		notify(Playernum, buf);
X			}
X                if (pl->info[Playernum-1].numsectsowned) {
X		sprintf(buf,"Inhab ");
X		notify(Playernum, buf);
X			}
X		if (pl->slaved_to) {
X		sprintf(buf,"SLAVED ");
X		notify(Playernum, buf);
X			}
X                inhab = 0;
X                for (j=1; j<=Num_races; j++) 
X			if (j!=Playernum && pl->info[j-1].numsectsowned) {
X				sprintf(buf,"%d ",j);
X				notify(Playernum, buf);
X				}
X                if (pl->conditions[TOXIC] > 70) {
X				sprintf(buf,"TOXIC ");
X				notify(Playernum, buf);
X				}
X                switch(pl->type) {
X                        case TYPE_EARTH:        sprintf(buf,"] Class M"); break;
X                        case TYPE_ASTEROID:     sprintf(buf,"] Asteroid"); break;
X                        case TYPE_AIRLESS:      sprintf(buf,"] Airless"); break;
X                        case TYPE_ICEBALL:      sprintf(buf,"] Iceball"); break;
X                        case TYPE_GASGIANT:     sprintf(buf,"] Jovian"); break;
X			case TYPE_WATER:        sprintf(buf,"] Water"); break;
X			default:				sprintf(buf,"] Unknown");break;
X                }
X			notify(Playernum, buf);
X                sprintf(buf," (%.2f%%)\n",compatibility(pl,Race));
X			notify(Playernum, buf);
X           } else {
X		sprintf(buf,"No Data ]\n");
X		notify(Playernum, buf);
X		}
X	   free(pl);
X        }
X    }
X }
X close_file(stardata);
X close_file(pdata);
X}
X
END_OF_FILE
if test 6315 -ne `wc -c <'server/explore.c'`; then
    echo shar: \"'server/explore.c'\" unpacked with wrong size!
fi
# end of 'server/explore.c'
fi
if test -f 'server/getplace.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'server/getplace.c'\"
else
echo shar: Extracting \"'server/getplace.c'\" \(6728 characters\)
sed "s/^X//" >'server/getplace.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 *  Getplace -- returns directory level from string and current Dir
X *  Dispplace -- returns string from directory level
X *  testship(ship) -- tests various things for the ship.
X */
X
X#include "GB_copyright.h"
X#define EXTERN extern
X#include "vars.h"
X#include "races.h"
X#include "ships.h"
X#include "buffers.h"
X#include <ctype.h>
Xint getplace_racedata;
X
Xchar Disps[PLACENAMESIZE];
X
Xplacetype Getplace2();
X
Xplacetype Getplace(Playernum,string, ignoreexpl)
Xint Playernum;
Xchar *string;
Xint ignoreexpl;
X{
X boolean error;
X int getplace_shdata;
X placetype where;	/* return value */
X
X Bzero(where);
X
Xfree(Race);
Xopenracedata(&getplace_racedata);
Xgetrace(getplace_racedata, &Race, Playernum);
Xclose_file(getplace_racedata);
X
Xwhere.err = 0;
X
X switch (*string) {
X	  case '/':
X		   where.level=LEVEL_UNIV;	/* scope = root (universe) */
X		   where.snum=0;
X		   where.pnum= where.shipno=0;
X		   return(Getplace2(Playernum, string+1,&where,ignoreexpl,Race->God));
X	 case '#':
X		   sscanf(++string,"%hd",&where.shipno);
X		   openshdata(&getplace_shdata);
X		   if (!getship(getplace_shdata,&where.shipptr,where.shipno)) {
X			close_file(getplace_shdata);
X			DontOwnErr(Playernum,where.shipno);
X			where.err = 1;
X			return where;
X		   }
X		   close_file(getplace_shdata);
X		   if ( (where.shipptr->owner==Playernum || ignoreexpl || Race->God)
X				&& (where.shipptr->is_alive || Race->God)) {
X/*			   if (!where.shipptr->is_alive)
X				printf("Ship is dead.\n"); */
X			   where.level = LEVEL_SHIP;
X			   where.snum = where.shipptr->storbits;
X			   where.pnum = where.shipptr->pnumorbits;
X			/* where.shipno already taken care of */
X			   while (isdigit(*string)) 
X				string++;
X			   if (*string=='/')
X				 return Getplace2(Playernum, string+1,&where, ignoreexpl,Race->God);
X			   else
X				 return where;
X		   } else {
X			where.err = 1;
X			if (where.shipptr->is_alive)
X				DontOwnErr(Playernum,where.shipno);
X
X			return where;
X		   }
X
X	 case '-':
X			/* no destination */
X		   where.level = LEVEL_UNIV;
X		   return where;
X
X	default:
X			/* copy current scope to scope */
X		   where.level = Dir[Playernum-1].level;
X		   where.snum = Dir[Playernum-1].snum;
X		   where.pnum = Dir[Playernum-1].pnum;
X		   if (where.level==LEVEL_SHIP) {
X			   where.shipno = Dir[Playernum-1].shipno;
X			   openshdata(&getplace_shdata);
X			   getship(getplace_shdata,&(where.shipptr),where.shipno);
X			   close_file(getplace_shdata);
X		   }
X		   if (*string==CHAR_CURR_SCOPE)
X			return where;
X		   else 
X			return Getplace2(Playernum, string,&where, ignoreexpl,Race->God);
X }
X
X}
X
X
X
Xplacetype Getplace2(Playernum, string,where, ignoreexpl,God)
Xint Playernum;
Xchar *string;
Xplacetype *where;
Xint ignoreexpl;
Xint God;
X{
Xchar substr[NAMESIZE];
Xplanettype *p;
Xshiptype *s;
Xregister int i,l;
Xint shdata,tick;
Xint getplace2_pdata;
X
X/* printf("getplace2:looking for '%s'\n",string); */
X
X if (where->err || *string=='\0' || *string=='\n')
X	return(*where);		/* base cases */
X
X else if (*string=='.') {
X    if (where->level==LEVEL_UNIV) {
X	sprintf(buf,"Can't go higher.\n");
X		notify(Playernum, buf);
X	where->err=1;
X	return(*where);
X    } else {
X	if (where->level==LEVEL_SHIP)
X		where->level = where->shipptr->whatorbits;
X	else 
X		where->level--;
X	while (*string=='.') string++;
X	while (*string=='/') string++;
X	return(Getplace2(Playernum, string,where,ignoreexpl,God));
X    }
X } else {
X		/* is a char string, name of something */
X    /*printf("before scanf str=`%s`\n",string);*/
X    sscanf(string,"%[^/ \n]",substr);
X    /*printf("after scanf sub=`%s`\n",substr);*/
X
X    do {
X       /*if (isupper(*string) )
X		(*string) = tolower(*string);*/
X       string++;
X    } while (*string!='/' && *string!='\n' && *string!='\0');
X
X    l=strlen(substr);
X    if (where->level==LEVEL_UNIV) {
X	for (i=0; i<Sdata.numstars; i++)
X	   if (!strncmp(substr,Stars[i]->name,l)) {
X		 where->level=LEVEL_STAR;
X		 where->snum = i;
X		 if (ignoreexpl || isset(Stars[where->snum]->explored, Playernum) || God) {
X			 tick = (*string=='/');
X			 return(Getplace2(Playernum, string+tick, where, ignoreexpl, God));
X		 }
X		 sprintf(buf,"You have not explored %s yet.\n",
X						Stars[where->snum]->name);
X			notify(Playernum, buf);
X		 where->err = 1;
X		 return(*where);
X	   }
X	if (i>=Sdata.numstars) {
X		sprintf(buf,"No such star %s.\n",substr);
X			notify(Playernum, buf);
X		where->err=1;
X		return(*where);
X	}
X    } else if (where->level==LEVEL_STAR) {
X	for (i=0; i<Stars[where->snum]->numplanets; i++)
X	   if (!strncmp(substr,Stars[where->snum]->pnames[i],l)) {
X		 where->level=LEVEL_PLAN;
X		 where->pnum = i;
X		 openpdata(&getplace2_pdata);
X		 getplanet(getplace2_pdata, &p, Stars[where->snum]->planetpos[i]);
X		 close_file(getplace2_pdata);
X		 if (ignoreexpl || p->info[Playernum-1].explored || God) {
X			 free(p);
X			 tick = (*string=='/');
X			 return(Getplace2(Playernum, string+tick,where,ignoreexpl, God));
X		 }
X		 sprintf(buf,"You have not explored %s yet.\n",Stars[where->snum]->pnames[i]);
X			notify(Playernum, buf);
X		 where->err = 1;
X		 free(p);
X		 return(*where);
X	   }
X	if (i >= Stars[where->snum]->numplanets) {
X		sprintf(buf,"No such planet %s.\n",substr);
X			notify(Playernum, buf);
X		where->err=1;
X		return(*where);
X	}
X    } else if (where->level==LEVEL_PLAN) {
X	sprintf(buf,"Can't descend to %s.\n",substr);
X			notify(Playernum, buf);
X	where->err=1;
X	return(*where);
X    }
X }
X}
X
X
X
Xchar *Dispplace(Playernum, where)
Xplacetype *where;
X{
X
X switch (where->level) {
X      case LEVEL_STAR:
X	     sprintf(Disps,"/%s",Stars[where->snum]->name);
X	     return(Disps);
X      case LEVEL_PLAN:
X	     sprintf(Disps,"/%s/%s",Stars[where->snum]->name, Stars[where->snum]->pnames[where->pnum]);
X	     return(Disps);
X      case LEVEL_SHIP:
X	     sprintf(Disps,"#%d",where->shipno);
X	     return(Disps);
X      case LEVEL_UNIV:
X	     return("-");
X      default:
X	     sprintf(buf,"illegal Dispplace val = %d\n",where->level);
X			notify(Playernum, buf);
X	     where->err = 1;
X	     return("/");
X	     break;
X }
X}
X
X
X
Xint testship(Playernum,s,n)
Xint Playernum;
Xreg shiptype *s;
Xreg int n;
X{
Xreg int r;
X
Xr=0;
X
X if (!s->is_alive) {
X	sprintf(buf,"%s #%d has been destroyed.\n", Shipnames[s->type], n);
X			notify(Playernum, buf);
X	r = 1;
X } else if (s->owner != Playernum) {
X	DontOwnErr(Playernum,n);
X	r = 1;
X } else {
X   if (!s->active) {
X	sprintf(buf,"%s #%d is irradiated %d %% and inactive.\n",Shipnames[s->type], n,s->rad);
X			notify(Playernum, buf);
X	r = 1;
X   } 
X   if (!s->popn && Max_crew(s)) {
X	sprintf(buf,"%s #%d %s has no crew and is not a robotic ship.\n", 
X		Shipnames[s->type], n, s->name );
X			notify(Playernum, buf);
X	r = 1;
X   }
X }
X return r;
X}
END_OF_FILE
if test 6728 -ne `wc -c <'server/getplace.c'`; then
    echo shar: \"'server/getplace.c'\" unpacked with wrong size!
fi
# end of 'server/getplace.c'
fi
if test -f 'server/scrap.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'server/scrap.c'\"
else
echo shar: Extracting \"'server/scrap.c'\" \(6768 characters\)
sed "s/^X//" >'server/scrap.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 * scrap.c -- turn a ship to junk
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
Xint scrap_shdata, scrap_pdata,scrap_sectdata, scrap_racedata;
X
Xscrap(Playernum,APcount, argn,args)
Xint Playernum;
Xint APcount;
Xint argn;
Xchar args[MAXARGS][COMMANDSIZE];
X{
Xplanettype *planet;
Xsectortype *sect;
Xshiptype *s,*s2;
Xint i,mask,shipno,scrapval=0,destval=0,crewval=0;
Xfloat fuelval=0.0;
X
Xscrap_shdata = scrap_pdata = NEUTRAL_FD;
X
X 	sscanf(args[1] + (*args[1]=='#'),"%d", &shipno);
X
X openshdata(&scrap_shdata);
X if (!getship(scrap_shdata,&s,shipno)) {
X     close_file(scrap_shdata);
X	return;
X }
Xclose_file(scrap_shdata);
X
X if (s->owner!=Playernum || !s->is_alive) {
X	DontOwnErr(Playernum,shipno);
X	free(s);
X	return;
X }
X
X/* if(s->type==OTYPE_GOV) {
X	sprintf(buf,"You can't scrap this kind of ship! **CHEATER!!!**\n");
X		notify(Playernum, buf);
X	return;
X	} */
X
X if (s->whatorbits==LEVEL_UNIV) {
X 	if (!enufAP(Playernum,Sdata.AP[Playernum-1], APcount))
X		return;
X } else
X 	if (!enufAP(Playernum,Stars[s->storbits]->AP[Playernum-1], APcount)) {
X		return;
X		}
X
Xfree(Race);
Xopenracedata(&scrap_racedata);
Xgetrace(scrap_racedata, &Race, Playernum);
Xclose_file(scrap_racedata);
X
X if (s->whatorbits==LEVEL_PLAN && s->type==OTYPE_TOXWC) {
X	sprintf(buf,"WARNING: This will release %d toxin points back into the atmosphere!!\n", s->object.number);
X		notify(Playernum, buf);
X	}
X
X if ( !s->is_docked) {
X	sprintf(buf,"%s #%d is not landed or docked.\nNo resources can be reclaimed.\n",Shipnames[s->type], shipno);
X		notify(Playernum, buf);
X }
X
X if (s->whatorbits==LEVEL_PLAN) {		/* wc's release poison */
X 	openpdata(&scrap_pdata);
X 	getplanet(scrap_pdata, &planet, Stars[s->storbits]->planetpos[s->pnumorbits]);
X	close_file(scrap_pdata);
X	
X        opensectdata(&scrap_sectdata);
X        getsector(scrap_sectdata, &sect, planet->sectormappos
X		 +((int)s->ypos*planet->Maxx+(int)s->xpos)*sizeof(sectortype));
X	close_file(scrap_sectdata);
X    }
X
X
X if (s->is_docked && s->whatdest==LEVEL_SHIP) {
X     openshdata(&scrap_shdata);
X     if (!getship(scrap_shdata, &s2, (int)s->destshipno)) {
X	    close_file(scrap_shdata);
X		return;
X		}
X	close_file(scrap_shdata);
X	if ( !(s2->is_docked && s2->destshipno == shipno) ) {
X		sprintf(buf,"Warning, other ship not docked..\n");
X			notify(Playernum, buf);
X		return;
X	}
X } else
X	s2 = (shiptype *)NULL;
X
X scrapval = Cost(s) * .50 + s->resource;
X
X if (s->is_docked) {
X
X	 sprintf(buf,"%s #%d:original cost: %d\n",
X		Shipnames[s->type], shipno, Cost(s));
X			notify(Playernum, buf);
X	 sprintf(buf,"         scrap value%s: %d rp's.\n",
X		s->resource ? "(with stockpile) " : "", scrapval);
X			notify(Playernum, buf);
X
X	 if (s2!=NULL && s->resource+scrapval > Max_resource(s2) && s->type!=STYPE_SHUTTLE) {
X		scrapval = Max_resource(s2) - s->resource;
X		sprintf(buf,"(There is only room for %d resources.)\n",scrapval);
X			notify(Playernum, buf);
X	 }
X
X	 if (s->fuel) {
X	   sprintf(buf,"Fuel recovery: %.0f.\n", s->fuel);
X			notify(Playernum, buf);
X	   fuelval = s->fuel;
X	   if (s2!=NULL && s->fuel+fuelval > Max_fuel(s2)) {
X		fuelval = Max_fuel(s2) - s->fuel;
X		sprintf(buf,"(There is only room for %.2f fuel.)\n",fuelval);
X			notify(Playernum, buf);
X	   }
X	 } else
X	   fuelval = 0.0;
X
X	 if (s->destruct) {
X	   sprintf(buf,"Weapons recovery: %d.\n", s->destruct);
X			notify(Playernum, buf);
X	   destval = s->destruct;
X	   if (s2!=NULL && s->destruct+destval > Max_destruct(s2)) {
X		destval = Max_destruct(s2) - s->destruct;
X		sprintf(buf,"(There is only room for %d destruct.)\n",destval);
X			notify(Playernum, buf);
X	   }
X	 } else
X	   destval = 0;
X
X	 if (s->popn) {
X	   if (sect->owner>0 && sect->owner!=Playernum) {
X		sprintf(buf,"You don't own this sector; no crew can be recovered.\n");
X			notify(Playernum, buf);
X	   } else {
X	      sprintf(buf,"Population recovery: %d.\n", s->popn);
X			notify(Playernum, buf);
X	      crewval = s->popn;
X	      if (s2!=NULL && s->popn+crewval > Max_crew(s2)) {
X		crewval = Max_destruct(s) - s->popn;
X		sprintf(buf,"(There is only room for %d crew.)\n",crewval);
X			notify(Playernum, buf);
X	      }
X	   }
X	 } else
X	   crewval = 0;
X
X}
X
X
X
X if (s->whatorbits==LEVEL_UNIV)
X 	deductAPs(Playernum,APcount, 0, 1);
X else
X 	deductAPs(Playernum,APcount, s->storbits, 0);
X
X kill_ship(s);
Xopenshdata(&scrap_shdata);
Xputship(scrap_shdata, s, shipno);
Xclose_file(scrap_shdata);
X if (s->is_docked && s->whatdest==LEVEL_SHIP) {
X     fuelval = MIN(fuelval, 1.*Max_fuel(s2) - s2->fuel);
X     destval = MIN(destval, Max_destruct(s2) - s2->destruct);
X     scrapval = MIN(scrapval, Max_resource(s2) - s2->resource);
X     crewval = MIN(crewval, Max_crew(s2) - s2->popn);
X     s2->fuel += fuelval;
X	s2->destruct += destval;
X	s2->resource += scrapval;
X	s2->popn += crewval;
X	s2->mass += fuelval*MASS_FUEL + destval*MASS_DESTRUCT + scrapval*MASS_RESOURCE + crewval*Race->mass;
X     s2->is_docked = 0; /* undock the surviving ship */
X     s2->whatdest = LEVEL_UNIV;
X     s2->destshipno = 0;
X     openshdata(&scrap_shdata);
X	putship(scrap_shdata, s2, s->destshipno);
X	close_file(scrap_shdata);
X    }
X
X
X
X if (s->whatorbits==LEVEL_PLAN) {
X
X     /* distribute poison over planet even if orbiting */
X   if (s->type==OTYPE_TOXWC) {
X	if (planet->conditions[TOXIC] > 100 - s->object.number)
X		planet->conditions[TOXIC] = 100;
X	else
X		planet->conditions[TOXIC] += s->object.number;
X
X	sprintf(buf,"Planetary toxin concentration is now %d.\n", 
X		planet->conditions[TOXIC]);
X		notify(Playernum, buf);
X   }
X
X   if (s->is_docked && s->whatdest==LEVEL_PLAN) {
X
X       if (sect->owner==Playernum) {
X		sect->popn += s->popn;
X       } else if (sect->owner == 0) {
X		sect->owner = Playernum;
X		sect->popn = s->popn;
X		planet->info[Playernum-1].numsectsowned++;
X		sprintf(buf,"Sector %.0f,%.0f Colonized.\n",s->xpos,s->ypos);
X		notify(Playernum, buf);
X       }
X       opensectdata(&scrap_sectdata);
X       putsector(scrap_sectdata, sect, planet->sectormappos
X		 +((int)s->ypos*planet->Maxx+(int)s->xpos)*sizeof(sectortype));
X       close_file(scrap_sectdata);
X
X 	planet->info[Playernum-1].resource += scrapval;
X 	planet->popn += crewval;
X 	planet->info[Playernum-1].destruct += destval;
X 	planet->info[Playernum-1].fuel += (int)fuelval;
X   }
X   openpdata(&scrap_pdata);
X   putplanet(scrap_pdata, planet, Stars[s->storbits]->planetpos[s->pnumorbits]);
X   close_file(scrap_pdata);
X
X }
X
X
X   if (s->is_docked && s->whatdest==LEVEL_PLAN) {
X	sprintf(buf,"\nScrapped.\n");
X		notify(Playernum, buf);
X   } else {
X	sprintf(buf,"\nDestroyed.\n");
X		notify(Playernum, buf);
X		}
X
X free(s);
X if (s2!=NULL) free(s2);
X
X}
X
X
END_OF_FILE
if test 6768 -ne `wc -c <'server/scrap.c'`; then
    echo shar: \"'server/scrap.c'\" unpacked with wrong size!
fi
# end of 'server/scrap.c'
fi
echo shar: End of archive 9 \(of 14\).
cp /dev/null ark9isdone
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