[comp.sources.games] v06i054: GB - Galactic Bloodshed, an empire-like war game, Part03/07

games@tekred.CNA.TEK.COM (04/27/89)

Submitted-by: Robert Chansky <smq@ssyx.ucsc.edu>
Posting-number: Volume 6, Issue 54
Archive-name: GB/Part03



#! /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 3 (of 7)."
# Contents:  GB.6 dosector.c files_shl.c land.c load.c moveship.c
#   survey.c
# Wrapped by billr@saab on Wed Apr 26 14:41:33 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'GB.6' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'GB.6'\"
else
echo shar: Extracting \"'GB.6'\" \(8685 characters\)
sed "s/^X//" >'GB.6' <<'END_OF_FILE'
X.TH GB 6 "8 Jan 1989"
X.SH NAME
XGB - Galactic Bloodshed
X.SH SYNOPSIS
XGB
X.br
Xmakeuniv
X.SH DESCRIPTION
X.LP
XThis game was originally inspired by the Unix wargame Empire.  In Empire
Xconquest is represented by the amount of territory a player occupies as
Xwell as the resources and workforces he posesses.  Galactic Bloodshed is
Xmuch the same in these respects, as are many other games.
X.LP
XBut, where Empire takes place on one world, Galactic Bloodshed employs
Xmany seperate worlds for players to explore and exploit.  In this way the
Xgame is more versatile than Empire, and there are many more avenues to
Xexplore in game development.  Finance, 
Xcooperation and war (of course),
Xdevelopment of technology,
Xand randomizing factors will all be important areas of the game.
X.LP
XWhile free trade would ordinarily be difficult in a simulation
Xconstrained by the mechanics of interstellar travel, Galactic Bloodshed
Xwill circumvent this by introducing various 'shortcuts' to travel.  Among
Xthese are FTL vehicles, instantaneous transport devices, and a smaller-than-
Xscale travel distance for starships.  Another factor to stimulate free
Xtrade is the economic leverage inherent in the disparate races and
Xcultures that arise from evolution (or creation, whichever you happen to
Xbelieve [more on this later]).  Thus goods such as priceless art
Xtreasures, examples of fiction, technological discoveries, new strains of
Xfood animals, etc.(the list is endless) can all be carried in a starship
Xof limited capacity.  
XCommunication is possible between races via long-distance radio
X(telegrams).  Opportunities for profit can be utilized by any player.
X.LP
XWhile the game is designed primarily to be peaceful in intent (the name is
Xsarcastic), it is necessary that there also be an alternative to friendly
Xcompetition.  Thus war and conflict are born.  In addition to trade
Xcargoes a ship can also carry destructive capacity.  this can represent
Xanything from nuclear weaponry to propaganda, and when unloaded it can be
Xdevastating to its intended target.  Ships, planets, and people all can be
Xmobilized to preserve their culture's manifest destiny while curbing another's
Xexpansionist imperialism.
X.LP
XThe above so far is assuming that each culture in the game develops along
Xthe lines that our own seems to be.
XThis view is a narrow one considering the disparity of even the
Xone known planet we have to model.
XThe technologically dominant European culture of Earth arose merely by chance, 
Xand it is equally possible that another, differently motivated culture
Xcould have come about in its place -- a culture that, perhaps, uses the
Xprinciples of magic, mind power, or prayer to influence its environment in the 
Xsame way that machines and such are used today.  We have only theoretical
Xexperience with such methods, but they are nevertheless applicable to the
Xworkings of the game.  Instead of developing newer and better machines
Xthese cultures may explore the possibilities of more complicated and
Xpowerful spells, a greater unity of the mind and the body, or a
Xtranscendant understanding of God.  Lasers and nuclear weapons clash with 
Xthe concentrated might of a racial mind, while
Xthe magic spells of another culture might vy with the power of a god.
X.LP
XIt is possible for any game to become unbalanced, as one player becomes
Xmore experienced in the game and forces the others to extinction.  This
Xcan easily happen with Galactic Bloodshed as well.  Randomizing factors
Xare necessary to keep the game balanced, without reducing
Xplayability as well.  I introduce Berserkers, wandering death machines 
Xattempting to
Xdestroy all life, as one such option.  These devices can be randomly
Xcreated anywhere (or alternatively built at a central base which could
Xserve as a quest to destroy for the players) to deal crippling blows at
Ximportant supply routes.  They can be directed anywhere, or programmed to
Xmove randomly or towards the most advantaged player.  But this is not the
Xonly option; many factors can contribute to keeping players on their toes.
XSomeone may invent a supernova device (effectively ending the game...) and
Xuse it on your system;  a viral plague may break out;  A gamma-ray laser
Xaimed at one of your planets may render its population nearly sterile;  Rival
Xsupernatural beings may choose your territory in which to 'duke it out';
Xyour scientists may invent a self-reproducing machine which immediately
Xproceeds to convert all the resources of your system into copies of itself.
XAny number of things may happen.
X.SH "COMMAND SUMMARY"
X.na
X.nf
X () or none -required arguments. []-optional arguments.
X xlow:xhi,ylow:yhi-means a range of sectors from xlow to xhi, and ylow to
X	yhi.  also legal: x,y xlow:xhi,y x,ylow:yhi
X path : a scope path; separated by '/'. ex: /sol/Earth means system sol, planet
X	 Earth; ../Mars means the scope above you, planet (or star for that 
X	 matter) Mars.  these may be abbreviated.  Substitute ':' for the
X	 current scope you are in for any command. 'path' can be substituted 
X	 with '#(shipno)' for many commands.
X
X
Xsurvey [xlow:xhi,ylow:yhi] -- look at survey on range of sectors or planet
X		or star.
X
Xbuild -- build a ship/object.
X
Xscrap -- turn a ship/object into scrap.
X
Xcs ([:]|[/]|[..]|[planetname]|[starname]|[/] etc.) -- change scope (..=up one;
X			':'=current scope; <name> down to planet or star.)
X
Xdeclare -- state relations (alliance, neutrality, war) to other players.
X
Xfire [ ( [#shipnum]|[path] ) ( [#shipnum2]|[path2] ) ] -- fire from 
X		ship #[shipnum] or planet [path], at ship #[shipnum2]
X		or planet [path2].
X
Xload [ (#shipnum) (commodity) (amt) ] -- load/unload amount of commodity from 
X			ship.
X
Xlaunch [#shipnum] -- take off a ship.
X
Xland [#shipnum] -- land a ship.
X
Xmobilize xlow:xhi,ylow:yhi [invest] -- build up military readiness in 
X		sectors, using [invest] resources.
X
Xmap [path] -- look at sector map.
X
Xname -- rename an object
X
Xnavigate [#shipnumber] [path] -- order ship to move.
X	navigate #shipno path -- move that ship to path
X	navigate path -- order all ships in scope to path
X	navigate  -- navigate all ships in scope to path (prompted)
X
Xorbit [path] -- graphic representation of ship and planet positions
X
Xzoom (amount) | (numerator/denominator) -- zoom in/out for orbit display
X
Xorder [ #shipnum ] -- send orders to ships
X
Xprofile -- racial profile
X
Xstock [#shipnumber] -- ship report
X
Xread -- read telegram messages
X
Xreport [#shipnumber] -- navigational ship report
X
Xtelegram [ playername | player# ] -- send a message to another player
X
Xquit -- quit
X
X? -- help
X.ad
X.fi
X.LP
XProgress on Galactic Bloodshed so far has been fairly steady; and I hope to 
Xhave a working multi-player copy
Xof the game (ver 0.9) up by the beginning of the summer.
X.SH AUTHOR
XRobert Paul Chansky
X.SH "SEE ALSO"
XIndividual helpfiles for each command.
X.SH BUGS
X.LP
XNone serious that I know of, however there are a few things that need 
Xto be fixed up in the near future:
X.PP
XMines are pretty recently put in, they might have problems.
X.PP 0
XI know I should have used a linked list instead of the slots in
Xthe planet/star data, but that part was written at a time when I didn't
Xknow any better, I was going through psychological trauma, one of my
Xkeyboard's keys stuck and I had to implement something that didn't use
Xthat key, take your pick.
X.PP 0
XThe stuff with "bombard" only telegrams the users that it was
Xdone, but it doesn't actually do anything besides that.
X.PP 0
XIt says in the docs that you can dock ships together, but you can't.  
Xthe best you can do is land.  When this is fixed the mirrors (and some of the 
Xlarger ships) will not be able to be built on a planet.
X.PP 0
XMirrors face the wrong way.
X.PP 0
XSome of the stuff with zoom doesn't work; ships sometimes get
X.PP 0
Xmisplaced.
X.PP 0
XThere may be weird things doing with the Von Neumann machines
Xand how they behave.
X.PP 0
XLikewise with spore pods.
X.PP 0
XLikewise with ground combat; not enough testing.
X.PP 0
XPlease disregard all that stuff in the overview about berserkers (my 
Xdesigns with the VN's cover most of that), magic, religion, etc.
XThat was all written back in my boundless youthful enthusiasm.
X.PP 0
XShips with "*" before their names (shipdata.h) don't work as yet.
Xdon't build them.
X.PP 0
XProbably 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 point cover
Xthings such as Ringworlds, Dyson spheres, space elevators, artificial
Xhollow planets, the list goes on..
END_OF_FILE
if test 8685 -ne `wc -c <'GB.6'`; then
    echo shar: \"'GB.6'\" unpacked with wrong size!
fi
# end of 'GB.6'
fi
if test -f 'dosector.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dosector.c'\"
else
echo shar: Extracting \"'dosector.c'\" \(6835 characters\)
sed "s/^X//" >'dosector.c' <<'END_OF_FILE'
X/*
X * Galactic Bloodshed (Robert Chansky, smq@b)
X *  dosector.c 
X *  dosector() -- do spread, produce, stuff like that, on a sector.
X *  explore()  -- mark sector and surrounding sectors as having been explored.
X */ 
X
X#include "vars.h"
X#include "races.h"
X#include "ships.h"
X#include "doturn.h"
X#include <math.h>
Xextern int tot_resdep,tot_eff,tot_res,tot_fuel,tot_destruct,
X	tot_captured,tot_mob;
Xextern float avg_mob[MAXPLAYERS];
Xextern char sects_gained[MAXPLAYERS], sects_lost[MAXPLAYERS];
Xextern bool Claims;
X
X		/* produce stuff in sector */
Xproduce(planet,s)
Xreg planettype *planet;
Xreg sectortype *s;
X{
Xreg float factor;
Xreg int eff;
Xreg struct plinfo *pinf;
Xreg int new;
X
X	 factor = logscale(s->popn)*s->resource * races[s->owner]->metabolism;
X
X	 pinf = &planet->info[s->owner-1];
X
X	 if (planet->type==TYPE_GASGIANT)
X		tot_fuel = pinf->fuel = 1000000;
X	 else {
X		pinf->fuel+=(new = round_rand(logscale(s->eff)*factor*FUEL_PRODUCTION) );
X		tot_fuel += new;
X	 }
X
X	 pinf->resource += (new = round_rand( logscale(s->eff)*factor*RESOURCE_PRODUCTION ) );
X	 tot_res += new;
X
X		/* increase mobilization to planetary quota */
X	 if (s->mobilization < pinf->mob_set)
X		if (pinf->resource) {
X			s->mobilization++;
X			pinf->resource -= round_rand(MOB_COST);
X			tot_mob++;
X	 	}
X
X
X	 pinf->destruct += (new = round_rand( logscale(s->eff)*factor*(s->mobilization/100.0)*DEST_PRODUCTION ) );
X	 tot_destruct += new;
X	   /* deplete resources for making weapons */
X	 tot_resdep += (new = (s->resource<=1) ? 0 : round_rand((1.1-logscale(s->eff))*factor*RESOURCE_DEPLETION) );
X	 s->resource -= new;
X
X	  /* add mobilization to get average mobilization */
X	 avg_mob[s->owner] += s->mobilization;
X
X	  /* do efficiency */
X	 if (s->eff<100) {
X	   if (!s->eff) {
X		tot_eff += s->eff = 1;
X	   } else {
X	     tot_eff += eff = round_rand(races[s->owner]->metabolism*s->popn*(0.95-logscale(s->eff))*EFF_PROD);
X		if (s->eff+eff >= 100) {
X			s->eff=100;	/* dont go past 100%*/
X			tot_eff -= s->eff+eff-100;
X			s->des = DES_PLATED;
X		} else 
X			s->eff += eff;
X	   }
X	}
X
X	  /* add population to sector */
X	 if (s->popn >= races[s->owner]->number_sexes)
X	    /*if (s->popn < maxsupport(s) )*/
X	       s->popn += round_rand((float)s->popn*races[s->owner]->birthrate * Compat[s->owner]/100.0 * (50.0-planet->conditions[TOXIC])/50.0 );
X	    /*else 
X	       s->popn += round_rand((float)s->popn*races[s->owner]->overbirthrate * Compat[s->owner]/100.0 * (50.0-planet->conditions[TOXIC])/50.0 );*/
X	 else
X		s->popn -= round_rand(s->popn * .01);
X	
X}
X
X
X/*
X * spread population to surrounding sects. 
X *
X *	the way people move depends on the population of the planet unless 
X *	NO_SLIDING_SCALE_AUTOMOVE is set (again for reasons of computer 
X *	power).  Otherwise, the populace will automatically migrate to all 
X *	available surrounding areas if the planetary population is less than
X *	POPN_MOVE_SCALE_1, to either north-south or east-west areas if the
X *	population is less than POPN_MOVE_SCALE_2, and to only one adjacent
X *	random sector if it is greater.
X */
X
X
Xspread(pl,s,x,y)
Xreg planettype *pl;
Xreg sectortype *s;
Xreg int x,y;
X{
Xreg int peep;
X
X   /* peep == number of people who want to move */
X/*printf("spreading from %d,%d -- ",x,y);*/
Xif (peep = round_rand((float)s->popn * races[s->owner]->nonhomebodies) ) {
X	/*printf(" peeple=%d\n",peep);*/
X
X#if NO_SLIDING_SCALE_AUTOMOVE
X if (pl->popn < POPN_MOVE_SCALE_1) {
X#endif
X	Migrate2(pl,x+1,y,s,peep/4);
X	Migrate2(pl,x-1,y,s,peep/4);
X	Migrate2(pl,x,y+1,s,peep/4);
X	Migrate2(pl,x,y-1,s,peep/4);
X#if NO_SLIDING_SCALE_AUTOMOVE
X }
X else if (pl->popn < POPN_MOVE_SCALE_2) {
X   x2 = int_rand(-1,1);
X   y2 = (!x2) ? rposneg() : 0;	 /* 1/3 chance of migrating n-s*/
X	Migrate2(pl,x+x2,y+y2,s,peep/2);   
X	Migrate2(pl,x-x2,y-y2,s,peep/2);
X			/* migrate to destination, from source */
X } else {
X	Migrate2(pl, x + rposneg(), y + rposneg(), s, peep);
X }
X
X#endif
X}
X}
X
X
X
XMigrate2(planet,xd,yd,ps,people)
Xplanettype *planet;
Xreg int xd,yd;
Xsectortype *ps;
Xreg int people;
X{
Xreg sectortype *pd;
X
X	/* attempt to migrate beyond screen */
X if ((yd>=planet->Maxy) || (yd<0) || !people ) 
X	return;	
X
X if (xd<0) 
X	xd=planet->Maxx-1;
X else if (xd>=planet->Maxx) 
X	xd=0;
X	/* check for planetary compatibility */
X if (float_rand()*100.0 > Compat[ps->owner]) {
X	/*printf("%d,%d incomp -- returning\n",xd,yd);*/
X	return;
X }
X
X pd = &Smap[yd*planet->Maxx+xd];
X
X if ((ps->owner==pd->owner) || (pd->des!=DES_SEA && !pd->is_wasted)) {
X
X 	if (!pd->owner) {
X		printf("claiming %d,%d (%d), %d people\n",xd,yd,ps->owner,people);
X        	pd->popn += people;
X        	ps->popn -= people;	/* move people */
X		pd->owner = ps->owner;
X		tot_captured++;
X		planet->info[pd->owner-1].numsectsowned++;
X		Claims = 1;
X 	} else if (pd->owner==ps->owner) {
X        	pd->popn += people;
X        	ps->popn -= people;
X	} else if (isset(races[ps->owner]->atwar, pd->owner) || races[ps->owner]->Thing) {
X			/* we are at war with them; do land combat */
X		reg float dfac;
X
X		ps->popn -= round_rand(((float)ps->popn * pd->mobilization * 
X			planet->info[pd->owner-1].comread + races[pd->owner]->fighters*10)/200.0);
X		dfac = ( (float)pd->popn * ps->mobilization * 
X			planet->info[ps->owner-1].comread + races[pd->owner]->fighters*10)/200.0;
X		printf(" att %d lost %g people of %d.\n",ps->owner,
X			((float)ps->popn * pd->mobilization * 
X			planet->info[pd->owner-1].comread + races[pd->owner]->fighters*10)/200.0, pd->popn);
X		if (pd->popn - dfac <= 0.0) {
X			    /* the invasion was successful */
X			if (races[ps->owner]->Thing) {
X				 /* mesos absorb the bodies of enemies */
X				pd->popn += MIN(people, ps->popn);
X				ps->popn -= MIN(people, ps->popn);
X			} else {
X				pd->popn = MIN(people, ps->popn);
X				ps->popn -= MIN(people, ps->popn);
X			}
X			sects_lost[pd->owner]++;
X			sects_gained[ps->owner]++;
X			pd->owner = ps->owner;
X			pd->eff *= 0.5;
X			pd->mobilization *= 0.25;
X			tot_captured++;
X			printf(" sec %d,%d CAPTURED",xd,yd);
X		} else 
X		   pd->popn -= round_rand(dfac);
X			
X		printf(" def %d lost %g people of %d,",pd->owner,
X			((float)pd->popn * ps->mobilization * 
X			planet->info[ps->owner-1].comread + races[pd->owner]->fighters*10)/200.0, pd->popn);
X 	}
X   }
X}
X
X
X/* mark sectors on the planet as having been "explored." for sea exploration
X	on earthtype planets.  */
X
Xexplore(planet, s, x, y, p)
Xreg planettype *planet;
Xreg sectortype *s;
Xreg int x,y,p;
X{
Xreg int d;
X
X	/* explore sectors surrounding sectors currently explored. */
X if (Sectinfo[x][y].explored[p]) {
X
X    Sectinfo[mod(x-1,planet->Maxx,d)][y].explored[p] = 1;
X    Sectinfo[mod(x+1,planet->Maxx,d)][y].explored[p] = 1;
X    if (y==0) {
X	Sectinfo[x][1].explored[p] = 1;
X    } else if (y==planet->Maxy-1) {
X	Sectinfo[x][y-1].explored[p] = 1;
X    } else {
X	Sectinfo[x][y-1].explored[p] = Sectinfo[x][y+1].explored[p] = 1;
X    }
X 
X } else if (s->owner==p)
X	Sectinfo[x][y].explored[p] = 1;
X
X}
END_OF_FILE
if test 6835 -ne `wc -c <'dosector.c'`; then
    echo shar: \"'dosector.c'\" unpacked with wrong size!
fi
# end of 'dosector.c'
fi
if test -f 'files_shl.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'files_shl.c'\"
else
echo shar: Extracting \"'files_shl.c'\" \(8074 characters\)
sed "s/^X//" >'files_shl.c' <<'END_OF_FILE'
X/*
X * Galactic Bloodshed (Robert Chansky, smq@b)
X *  disk input/output routines & msc stuff
X *    all read routines lock the data they just accessed (the file is not
X *    closed).  write routines close and thus unlock that area.
X *
X *  openstardata(&fd),openpdata(&fd),openshdata(&fd),opensectdata(&fd)
X *     openshfdata(&fd) -- open different files, return file descriptors
X *  getsdata(fd,&Sdata) -- get root dir for univ
X *  getrace(**racetype,racenum) -- get race from disk
X *  getstar(fd,**startype,starnum) -- gets star from disk
X *  getplanet(fd,**planettype,filepos) -- gets planet from disk
X *  getsector(fd,**sectortype,filepos) -- gets 1 sect from disk
X *  getsmap(fd,*sectortype,filepos,Maxx*Maxy) -- gets sector map from disk
X *  getship(fd,**shiptype,shipnum) -- gets ship from disk
X *  putsdata(fd,&Sdata) -- put root dir for univ
X *  putrace(*racetype) -- put race to disk
X *  putstar(fd,*startype,starnum) -- put star to disk
X *  putplanet(fd,*planettype,filepos) -- put planet to disk
X *  putsector(fd,*sectortype,filepos) -- write sector to disk
X *  putsmap(fd,*sectortype,filepos,Maxx*Maxy) -- put smap to disk
X *  putship(fd,*shiptype,shipnum) -- put ship to disk
X *  int Numships(fd) -- return highest ship # from file
X *  getdeadship(fd, &filepos) -- filepos of next dead ship from shipfreedatafile
X *  destroyship(fd, shipnum) -- kill a ship
X *  int Getracenum(char *) -- return race # from login list
X *  int Numraces() -- return # of races that exist right now
X *  Putpower() -- puts Power struct to disk for power command
X */
X
X#include "vars.h"
X#include "ships.h"
X#include "races.h"
X#include "power.h"
X#include <strings.h>
X#include <sys/stat.h>
X#include <signal.h>
X#include <errno.h>
Xextern int errno;
Xint sys_nerr;
Xchar *sys_errlist[];
X
X
Xopenstardata(fd)
Xint *fd;
X{
X /*printf(" openstardata\n");*/
X if ( (*fd = open(STARDATAFL, O_RDWR, 0777)) < 0) {
X	  perror("openstardata");
X	  printf("unable to open %s\n",STARDATAFL);
X	  exit(-1);
X }
X}
X
X
Xopenshdata(fd)
Xint *fd;
X{
X if ( (*fd = open(SHIPDATAFL, O_RDWR, 0777)) < 0) {
X	  perror("openshdata");
X	  printf("unable to open %s\n",SHIPDATAFL);
X	  exit(-1);
X }
X /*printf("openshdata %d\n",*fd);*/
X}
X
X
Xopenpdata(fd)
Xint *fd;
X{
X if ( (*fd = open(PLANETDATAFL, O_RDWR, 0777)) < 0) {
X	  perror("openpdata");
X	  printf("unable to open %s\n",PLANETDATAFL);
X	  exit(-1);
X }
X /*printf("openpdata %d\n",*fd);*/
X}
X
X
Xopensectdata(fd)
Xint *fd;
X{
X /*printf(" opensectdata\n");*/
X if ( (*fd = open(SECTORDATAFL, O_RDWR, 0777)) < 0) {
X	  perror("opensectdata");
X	  printf("unable to open %s\n",SECTORDATAFL);
X	  exit(-1);
X }
X}
X
X
Xopenshfdata(fd)
Xint *fd;
X{
X /*printf("openshfdata\n");*/
X if ( (*fd = open(SHIPFREEDATAFL, O_RDWR, 0777)) < 0) {
X	  perror("openshfdata");
X	  printf("unable to open %s\n",SHIPFREEDATAFL);
X	  exit(-1);
X }
X}
X
X
X
Xgetsdata(fd,S)
Xint fd;
Xstruct data *S;
X{
X  Fileread(fd,(char *)S, sizeof(struct data), STARDATAFL, 0 );
X}
X
X
Xgetrace(r,rnum)
Xracetype **r;
Xint rnum;
X{
Xint fd;
X *r = (racetype *)malloc(sizeof(racetype));
X if ( (fd = open(RACEDATAFL, O_RDWR, 0777)) < 0) {
X	  perror("openrdata");
X	  printf("unable to open %s\n",RACEDATAFL);
X	  exit(-1);
X }
X /*printf(" getrace rnum %d posn %d.\n",rnum,(rnum-1)*sizeof(racetype) );*/
X Fileread(fd, (char *)*r, sizeof(racetype), RACEDATAFL,
X			(rnum-1)*sizeof(racetype) );
X close(fd);
X}
X
X
Xgetstar(fd,s,star)
Xint fd;
Xstartype **s;
Xint star;
X{
X *s = (startype *)malloc(sizeof(startype));
X Fileread(fd,(char *)*s, sizeof(startype), STARDATAFL, 
X	(int)(sizeof(Sdata)+star*sizeof(startype)) );
X}
X
X
Xgetplanet(fd,p,filepos)
Xint fd;
Xplanettype **p;
Xint filepos;
X{
X *p = (planettype *)malloc(sizeof(planettype));
X Fileread(fd,(char *)*p, sizeof(planettype), PLANETDATAFL, filepos );
X /*printf(" getplanet pointer=%x, smappos=%d\n",*p,(*p)->sectormappos);*/
X}
X
X
Xgetsector(fd,s,filepos)
Xint fd;
Xsectortype **s;
Xint filepos;
X{
X *s = (sectortype *)malloc(sizeof(sectortype));
X Fileread(fd,(char *)*s, sizeof(sectortype), SECTORDATAFL, filepos );
X}
X
X
Xgetsmap(fd,map,filepos,nsects)
Xint fd;
Xsectortype *map;
Xint filepos;
Xint nsects;
X{
X  /* be sure to malloc() the amt of memory needed by getsmap */
X Fileread(fd,(char *)map, nsects*sizeof(sectortype), SECTORDATAFL, filepos );
X}
X
X
Xint getship(fd,s,shipnum)
Xint fd;
Xshiptype **s;
Xint shipnum;
X{
X struct stat buf;
X
X fstat(fd,&buf);
X if (buf.st_size / sizeof(shiptype) < shipnum) {
X	printf("Illegal ship number %d\n",shipnum);
X	return 0;
X } else {
X 	*s = (shiptype *)malloc(sizeof(shiptype));
X 	Fileread(fd, (char *)*s, sizeof(shiptype), SHIPDATAFL,
X					(shipnum-1)*sizeof(shiptype) );
X	return 1;
X }
X}
X
X
X/* gets the ship # listed in the top of the file SHIPFREEDATAFL. this
X** might have no other uses besides build().
X**  also locks the fd in shipdata.
X*/
Xint getdeadship(shipdata)
Xint shipdata;
X{
X struct stat buf;
X short shnum;	/* must use a pointer here; Fileread re-allocates the addr */
X int fd,lerr,lockt = NUM_TIMES_TO_WAIT_FOR_LOCK;
X
X while ((lerr=flock(shipdata, LOCK_SH|LOCK_EX|LOCK_NB ))== -1 && errno==EWOULDBLOCK) {
X	if (!lockt--) {
X		printf("too long. exit.\n");
X		exit(-1);
X	}
X	printf("getdeadship waiting on %s lock...\n",SHIPDATAFL);
X	sleep(2);
X }
X if (lerr<0 && errno!=EWOULDBLOCK) {
X	perror("getdeadship");
X	exit(-1);
X }
X
X stat(SHIPFREEDATAFL,&buf);
X
X if (buf.st_size) {
X	openshfdata(&fd);
X		/* put topmost entry in fpos */
X	Fileread(fd, (char *)&shnum, sizeof(short), SHIPFREEDATAFL, 
X			buf.st_size - sizeof(short) );
X		/* erase that entry, since it will now be filled */
X	printf("top dead ship == %d, read from posn %d\n",shnum,buf.st_size-sizeof(short));
X	ftruncate(fd, (long)(buf.st_size-sizeof(short)) );
X	close(fd);
X	return (int)shnum;
X } else
X	return -1;
X}
X
X
X
Xputsdata(fd,S)
Xint fd;
Xstruct data *S;
X{
X  Filewrite(fd,(char *)S, sizeof(struct data), STARDATAFL, 0 );
X}
X
X
Xputrace(r)
Xracetype *r;
X{
X int fd;
X
X if ( (fd = open(RACEDATAFL, O_WRONLY, 0777)) < 0) {
X	  perror("openrdata");
X	  printf("unable to open %s\n",RACEDATAFL);
X	  exit(-1);
X }
X Filewrite(fd,(char *)r, sizeof(racetype), RACEDATAFL, 
X		(r->Playernum-1)*sizeof(racetype) );
X close(fd);
X printf(" putrace pl#%d posn %d\n",r->Playernum,(r->Playernum-1)*sizeof(racetype) );
X}
X
X
Xputstar(fd,s,snum)
Xint fd;
Xstartype *s;
Xint snum;
X{
X  Filewrite(fd,(char *)s, sizeof(startype), STARDATAFL, 
X		(int)(sizeof(Sdata)+snum*sizeof(startype)) );
X}
X
Xputplanet(fd,p,filepos)
Xint fd;
Xplanettype *p;
Xint filepos;
X{
X Filewrite(fd,(char *)p, sizeof(planettype), PLANETDATAFL, filepos );
X}
X
Xputsector(fd,s,filepos)
Xint fd;
Xsectortype *s;
Xint filepos;
X{
X Filewrite(fd,(char *)s, sizeof(sectortype), SECTORDATAFL, filepos );
X}
X
Xputsmap(fd,map,filepos,nsects)
Xint fd;
Xsectortype *map;
Xint filepos;
Xint nsects;
X{
X Filewrite(fd,(char*)map, nsects*sizeof(sectortype), SECTORDATAFL, 
X	filepos );
X}
X
Xputship(fd,s,shipnum)
Xint fd;
Xshiptype *s;
Xint shipnum;
X{
X Filewrite(fd,(char *)s, sizeof(shiptype), SHIPDATAFL, 
X		(shipnum-1)*sizeof(shiptype) );
X}
X
X
Xint Numraces()
X{
X struct stat buf;
X
X stat(RACEDATAFL,&buf);
X return( (int)(buf.st_size / sizeof(racetype)) );
X}
X
X
X
Xint Numships(fd)	 /* return number of ships */
X{
X struct stat buf;
X int lerr;
X
X	/* check for locks on the fd and lock */
X while ((lerr=flock(fd, LOCK_SH|LOCK_EX|LOCK_NB ))== -1 && errno==EWOULDBLOCK){
X	printf("waiting on %s lock..\n",SHIPDATAFL);
X	sleep(1);
X }
X if (lerr== -1 && errno !=EACCES) {
X	printf("weird error.\n");
X	perror("numships");
X }
X fstat(fd,&buf);
X printf("numships %d\n",(int)(buf.st_size / sizeof(shiptype)) );
X return( (int)(buf.st_size / sizeof(shiptype)) );
X}
X
X
X
X
X/* 
X** destroys the ship at the file position given.
X*/
Xdestroyship(fd,shipnum)
Xint fd;
Xshort shipnum;
X{
X struct stat buf;
X
X printf("ship #%d destroyed.\n", shipnum);
X	/* write the ship # at the very end of SHIPFREEDATAFL */
X  fstat(fd,&buf);
X  Filewrite(fd,(char *)&shipnum, sizeof(shipnum), SHIPFREEDATAFL, buf.st_size );
X
X}
X
X
X
XPutpower(p)
Xstruct power p[MAXPLAYERS];
X{
Xint power_fd;
X
X if ( (power_fd = open(POWFL, O_RDWR, 0777)) < 0) {
X	  perror("open power data");
X	  printf("unable to open %s\n",POWFL);
X	  exit(-1);
X }
X write(power_fd, (char *)p, sizeof(*p)*MAXPLAYERS );
X close(power_fd);
X}
END_OF_FILE
if test 8074 -ne `wc -c <'files_shl.c'`; then
    echo shar: \"'files_shl.c'\" unpacked with wrong size!
fi
# end of 'files_shl.c'
fi
if test -f 'land.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'land.c'\"
else
echo shar: Extracting \"'land.c'\" \(6291 characters\)
sed "s/^X//" >'land.c' <<'END_OF_FILE'
X/*
X** Galactic Bloodshed (Robert Chansky, smq@b)
X**  land.c -- land a ship
X**  also.... dock -- dock a ship w/ another ship (not implemented)
X**  and..... assault -- a very un-PC version of land
X*/
X
X#include "vars.h"
X#include "ships.h"
X#include "races.h"
X#include <setjmp.h>
X#include <math.h>
X#include <curses.h>
Xextern jmp_buf main_jenv;
X#include <signal.h>
Xextern char Shipltrs[];
X
Xint land_sectdata,land_shfdata,land_shdata,land_pdata;
X
X
Xland(APcount, argn,args, assault)
Xint APcount;
Xint argn;
Xchar args[MAXARGS][COMMANDSIZE];
Xint assault;	/* unfriendly land */
X{
Xint land_handler();
Xchar c;
Xshiptype *s;
Xplanettype *p;
Xsectortype *sect;
Xplacetype crash;	/* in case of a crash */
Xbool planetmod=0,sectmod=0;
Xint shipnum,x= -1,y= -1,i;
Xfloat fuel;
Xdouble Dist;
Xchar tbuf[1000],buf[200];
X
Xland_sectdata = land_shfdata = land_shdata = land_pdata = NEUTRAL_FD;
Xsignal(SIGINT, land_handler);
X
X  if (argn!=2) {
X	printf("%s what ship #", args[0]);
X	scanf("%d",&shipnum);
X	getchr();
X  } else {
X	i = (args[1][0]=='#');
X	sscanf(args[1]+i,"%d",&shipnum);
X  }
X  openshdata(&land_shdata);
X  if (!getship(land_shdata, &s, shipnum)) {
X	land_handler();
X  }
X  if (s->owner!=Playernum) {
X	DontOwnErr(shipnum);
X	land_handler();
X  }
X  if (s->whatorbits != LEVEL_PLAN) {
X	printf("%s is not orbiting a planet.\n",Shipnames[s->type]);
X	land_handler();
X  }
X  if (s->rad) {
X	printf("%s is irradiated and inactive.\n",Shipnames[s->type]);
X	land_handler();
X  }
X  if (!enufAP(Stars[s->storbits]->AP, APcount)) 
X	land_handler();
X  if (s->is_docked) {
X	printf("Ship #%d is already docked.\n",shipnum);
X	land_handler();
X  }
X
X  /* if (s->whatdest==LEVEL_SHIP) {   */
X  /* } else { */
X  openpdata(&land_pdata);
X  getplanet(land_pdata, &p, Stars[s->storbits]->planetpos[s->pnumorbits]);
X  
X  printf("Planet /%s/%s has gravity field of %.2f.\n", Stars[s->storbits]->name,
X	Stars[s->storbits]->pnames[s->pnumorbits], gravity(p));
X
X  printf("Distance to planet: %.2f.\n",
X  	Dist = sqrt((double)Distsq( (double)Stars[s->storbits]->xpos + p->xpos, 
X  		      Stars[s->storbits]->ypos + p->ypos, 
X  		      (double)s->xpos, 
X  		      (double)s->ypos ) )
X  	);
X
X  if (Dist > DIST_TO_LAND) {
X     printf("Ship #%d must be %d or closer to the planet (%.2f).\n",shipnum, DIST_TO_LAND, Dist);
X     land_handler();
X  }
X
X  fuel = 0.05 + logscale(s->mass)*gravity(p) * LAND_GRAV_MASS_FACTOR + assault;
X
X  printf("That maneuver will cost you %.2f fuel (of %.2f).\n",fuel, s->fuel);
X
X  if (s->fuel < fuel) {
X	  tty_on();
X	  printf("NOT ENOUGH FUEL-- continue? (y/n) ");
X	  putchr(c = getchr());
X	  if (c != 'y') {
X		land_handler();
X		tty_off();
X	  }
X  }
X  tty_off();
X
X  do {
X    printf("%s on",(s->fuel < fuel) ? "CRASH" : args[0]);
X    GetMapSector(p, &x, &y);
X    if (assault) {
X	    opensectdata(&land_sectdata);
X	    getsector(land_sectdata,&sect,p->sectormappos+(y*p->Maxx+x)*sizeof(sectortype));
X	    if (sect->owner==Playernum) {
X		printf("You cannot assault your own sector.\n");
X		close(land_sectdata);
X		free(sect);
X	    } else if (sect->popn > 0) {
X		printf("The assaulted sector must have no population.\n");
X		close(land_sectdata);
X		free(sect);
X	    } else if (sect->des != DES_LAND) {
X		printf("You cannot land on a %c sector.\n",desshow(sect));
X		close(land_sectdata);
X		free(sect);
X	    }
X    }
X  } while (assault && (sect->owner==Playernum || sect->popn>0 || sect->des!=DES_LAND));
X
X  if (s->fuel < fuel) {
X
X	crash.level = LEVEL_PLAN;
X	crash.snum = s->storbits;
X	crash.pnum = s->pnumorbits;
X
X	printf("BO\007OM!! Ship #%d crashes on sector %d,%d with blast radius of %d.\n",
X		shipnum, x, y, (int)(s->mass/15+1+s->destruct/3) );
X
X	if (!fork()) {
X		/* fork off a child process to do damage */
X	  blast(crash, p, x, y, (int)(s->mass/15+1+s->destruct/3+s->fuel/5), 
X			(int)(s->destruct/3+2) );
X
X	  openshfdata(&land_shfdata);
X	  destroyship(land_shfdata,shipnum);	/* kill the ship */
X	  close(land_shfdata);
X
X	  for (i=0; i<MAXPSHIPS && p->shipnums[i]!=shipnum; i++)
X		if (p->shipnums[i] == shipnum) {
X			planetmod = 1;
X			p->shipnums[i] = 0;
X			p->numships--;
X		}
X	  
X	  deductAPs(APcount, s->storbits, 0);
X	  launch_handler();
X
X	  exit(0);
X	}
X  }
X  s->xpos = (float)x;
X  s->ypos = (float)y;
X
X  s->fuel -= fuel;
X  s->mass -= fuel * MASS_FUEL;
X  s->is_docked = 1;
X  s->whatdest = LEVEL_PLAN;	/* no destination */
X  s->deststar = s->storbits;
X  s->destpnum = s->pnumorbits;
X
X  if (assault) {
X		/* assault on planet increases combat readiness, */
X		/* but only if we aren't already well-established there */
X	if (!p->info[Playernum-1].numsectsowned && p->info[Playernum-1].comread < 50) {
X		p->info[Playernum-1].comread = 100;
X		p->info[Playernum-1].mob_set = 100;
X		sect->mobilization = 100;
X		sect->is_wasted = 0;
X	}
X	sectmod = planetmod = 1;
X	  /* unload some people onto the sector */
X	sect->popn = s->popn-1;
X	sect->owner = Playernum;
X	p->info[Playernum-1].numsectsowned++;
X	s->mass -= (s->popn-1) * Race->mass;
X	s->popn = 1;
X  }
X
X /* } */
X
X  deductAPs(APcount, s->storbits, 0);
X
X  putship(land_shdata, s, shipnum);
X  close(land_shdata);
X
X  if (planetmod) {
X	  putplanet(land_pdata,p,Stars[s->storbits]->planetpos[s->pnumorbits]);
X  }
X  close(land_pdata);
X  free(p);
X
X  if (sectmod)
X	  putsector(land_sectdata,sect,p->sectormappos+(y*p->Maxx+x)*sizeof(sectortype));
X  if (assault) {
X	  close(land_sectdata);
X	  free(sect);
X  }
X
X	/* send telegs to anyone there */
X  if (s->whatdest == LEVEL_PLAN) {
X	  teleg_add("",tbuf);
X	  if (assault)
X		  sprintf(buf,"BULLETIN!\n\nPlanet /%s/%s ASSAULTED by ship #%d on sector %.0f,%.0f!!\n", Stars[s->storbits]->name,
X			Stars[s->storbits]->pnames[s->pnumorbits], shipnum,
X			s->xpos, s->ypos);
X	  else
X		  sprintf(buf,"Bulletin...\n\nShip #%d observed landing on sector %.0f,%.0f,\nplanet /%s/%s.\n",shipnum,s->xpos,s->ypos,Stars[s->storbits]->name,
X			Stars[s->storbits]->pnames[s->pnumorbits]);
X	  teleg_add(buf,tbuf);
X	  for (i=1; i<MAXPLAYERS; i++)
X		if (p->info[i-1].numsectsowned && i!=Playernum)
X		     teleg_send(TELEG_PLAYER_AUTO, i, tbuf);
X  }
X
X  if (s->whatdest==LEVEL_PLAN)
X  	printf("ship #%d landed on planet.\n",shipnum);
X  else
X	printf("ship #%d docked.\n",shipnum);
X  free(s);
X}
X
X
X
Xland_handler(sig, code, scp)
Xint sig,code;
Xstruct sigcontext *scp;
X{
X close(land_pdata);
X close(land_shdata);
X close(land_sectdata);
X close(land_shfdata);
X longjmp(main_jenv,1);
X}
END_OF_FILE
if test 6291 -ne `wc -c <'land.c'`; then
    echo shar: \"'land.c'\" unpacked with wrong size!
fi
# end of 'land.c'
fi
if test -f 'load.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'load.c'\"
else
echo shar: Extracting \"'load.c'\" \(7371 characters\)
sed "s/^X//" >'load.c' <<'END_OF_FILE'
X
X/*
X * Galactic Bloodshed (Robert Chansky, smq@b)
X *  load.c -- load/unload stuff
X */
X
X#include "vars.h"
X#include "ships.h"
X#include "races.h"
X#include <curses.h>
X#include <signal.h>
X#include <setjmp.h>
Xextern jmp_buf main_jenv;
Xextern int Ignore_filelocks;
Xextern char telegram_buf[AUTO_TELEG_SIZE];
Xint load_shdata,load_pdata,load_sectdata;
X
X
Xload(APcount, argn,args)
Xint APcount;
Xint argn;
Xchar args[MAXARGS][COMMANDSIZE];
X{
Xint first=1,proc,Mod=0,jett=0,lolim,uplim,shipno,amt;
Xchar commod, buf[100],bufr[70],bufd[70],buff[70],bufc[70];
Xshiptype *s,*s2;
Xplanettype *p;
Xsectortype *sect;
Xint load_handler();
X
X    load_shdata = load_pdata = load_sectdata = NEUTRAL_FD;
X    signal(SIGINT, load_handler);
X
X    if (argn==1) {
X      printf("ship #");
X      scanf("%d",&shipno);
X      getchr();
X    } else 
X	shipno = atoi(args[1] + ((args[1][0])=='#') ? 1 : 0);
X
X    openshdata(&load_shdata);
X    if (!getship(load_shdata,&s,shipno)) {
X	load_handler();
X    }
X    if (s->owner!=Playernum || s->is_dead) {
X	DontOwnErr(shipno);
X	printf("(%d)\n",s->owner);
X	free(s);
X	load_handler();
X    }
X    if (s->rad) {
X	printf("%s #%d is irradiated and inactive.\n", Shipnames[s->type],shipno);
X	free(s);
X	load_handler();
X    }
X
X
X   do {
X
X    proc = 0;
X
X    if (s->type == OTYPE_TRANSDEV) {
X	Ignore_filelocks = 1;
X	if (!getship(load_shdata,&s2, s->orders.object.number)) {
X		printf("The hopper seems to be blocked.\n");
X		load_handler();
X	}
X	Ignore_filelocks = 0;
X	if (s2->is_dead) {
X		printf("The target device does not exist.\n");
X		load_handler();
X	}
X	if (s2->type!=OTYPE_TRANSDEV || !s2->orders.object.on) {
X		printf("The target device is not receiving.\n");
X		load_handler();
X	}
X    }
X
X
X    if ( !(s->is_docked && s->whatdest==LEVEL_PLAN && s->whatorbits==LEVEL_PLAN) ) {
X	if (s->type==OTYPE_TRANSDEV) {
X		printf("It does not seem to work in zero-g environments.\n");
X		load_handler();
X	}
X	printf("%s #%d is not landed.\n",is_object(s)?"object":"ship",shipno);
X      	tty_on();
X	printf("  jettison into open space (y/n)?");
X	jett = 1;
X      	commod=getchr();
X      	tty_off();
X      	if (commod!='y')
X		load_handler();
X    }
X
X
X    if (!jett) {
X    	openpdata(&load_pdata);
X    	getplanet(load_pdata,&p,Stars[Dir.snum]->planetpos[Dir.pnum]);
X    }
X
X    if (first) {
X      if (s->whatorbits==LEVEL_UNIV)
X    	if (!enufAP(Sdata.AP, APcount))
X		load_handler();
X      else 
X	if (!enufAP(Stars[s->storbits]->AP, APcount))
X		load_handler();
X    }
X
X
X   do {
X
X    tty_on();
X    printf("%s #%d:(rfdc? q) >", is_object(s) ? "object" : "ship",shipno);
X    commod = getchr();
X    putchr('\n');
X    tty_off();
X
X    if (!jett && commod=='c') {
X    	opensectdata(&load_sectdata);
X    	getsector(load_sectdata,&sect,p->sectormappos + ( (int)s->ypos*p->Maxx+(int)s->xpos) * sizeof(sectortype) );
X    }
X
X    switch (commod) {
X	case 'c': lolim = - s->popn;
X		  uplim = jett ? 0 : 
X			MIN(sect->popn, 
X			 	 Shipdata[s->type][ABIL_MAXCREW] - s->popn);
X		  proc = 1;
X		  break;
X	case 'd': lolim = - s->destruct;
X		  uplim = jett ? 0 : 
X			MIN(p->info[Playernum-1].destruct,
X			         Shipdata[s->type][ABIL_DESTCAP] - s->destruct);
X		  proc = 1;
X		  break;
X	case 'f': lolim = - s->fuel;
X		  uplim = jett ? 0 : MIN(p->info[Playernum-1].fuel,
X			         Shipdata[s->type][ABIL_FUELCAP] - s->fuel);
X		  proc = 1;
X		  break;
X	case 'r': lolim = - s->resource;
X		  uplim = jett ? 0 : MIN(p->info[Playernum-1].resource,
X			         Shipdata[s->type][ABIL_CARGO] - s->resource);
X		  proc = 1;
X		  break;
X	case '?': printf("\nship #%d at %.0f,%.0f:\n   res:%u\n   fuel:%.1f\n   crew:%u\n   dest:%u\n", shipno,s->xpos,s->ypos, s->resource, s->fuel, s->popn, s->destruct);
X		  proc = 0;
X		  break;
X	case 'q':
X	case ' ':
X		  load_handler();
X		  break;
X	default:  printf("%c not valid.\n",commod);
X		  proc = 0;
X		  load_handler();
X      }
X     } while (!proc);
X
X      tty_off();
X      amt = uplim + 1;
X      while (amt<lolim || amt>uplim) {
X	  printf("      amount (%d to %d) ",lolim,uplim);
X	  if (scanf("%d",&amt)!=1) 
X		amt=uplim+1;	/* force error */
X	  getchr();
X      }
X    if (amt == 0)
X	 load_handler();
X
X    switch (commod) {
X	case 'c': if (!jett) {
X		  	if (sect->popn==0 && amt<0) {
X				p->info[Playernum-1].numsectsowned++;
X				sect->owner = Playernum;
X				printf("sector %.0f,%.0f COLONIZED.\n",s->xpos,s->ypos);
X		  	}
X		  	sect->popn -= (us)amt;
X		  	p->popn -= amt;
X		  	if (sect->popn==0) {
X				p->info[Playernum-1].numsectsowned--;
X				sect->owner = 0;
X				printf("sector %.0f,%.0f evacuated.\n",s->xpos,s->ypos);
X		  	}
X		  }
X		  printf("crew complement of ship #%d is now %u.\n", 
X			shipno, s->popn+amt);
X		  s->popn += amt;
X		  s->mass += amt*Race->mass;
X		  Mod = 1;
X		  break;
X	case 'd': s->destruct += amt;
X		  s->mass += amt*MASS_DESTRUCT;
X		  if (!jett)
X		  	p->info[Playernum-1].destruct -= amt;
X		  Mod = 1;
X		  break;
X	case 'f': s->fuel += amt;
X		  s->mass += amt*MASS_FUEL;
X		  if (!jett)
X		  	p->info[Playernum-1].fuel -= amt;
X		  Mod = 1;
X		  break;
X	case 'r': s->resource += amt;
X		  s->mass += amt*MASS_RESOURCE;
X		  if (!jett)
X		  	p->info[Playernum-1].resource -= amt;
X		  Mod = 1;
X		  break;
X	case 'q':
X	case ' ':
X	case '?':
X	default:
X		break;
X    }
X
X    putship(load_shdata,s,shipno);
X
X    if (s->type==OTYPE_TRANSDEV) {
X	/* send stuff to other transport device */
X	if (s->resource) {
X		printf("Zap! %d resources sent.\n", s->resource);
X		sprintf(bufr, "%d Resources\n",s->resource);
X		s2->mass += s->resource * MASS_RESOURCE;
X		s2->resource += s->resource;
X		s->resource = 0;
X	} else
X		bufr[0] = '\0';
X	if (s->fuel) {
X		printf("Zap! %g fuel sent.\n", s->fuel);
X		sprintf(buff, "%g Fuel\n",s->fuel);
X		s2->mass += s->fuel * MASS_FUEL;
X		s2->fuel += s->fuel;
X		s->fuel = 0.0;
X	} else
X		buff[0] = '\0';
X	if (s->destruct) {
X		printf("Zap! %d destruct sent.\n", s->destruct);
X		sprintf(bufd, "%d Destruct\n",s->destruct);
X		s2->mass += s->destruct * MASS_DESTRUCT;
X		s2->destruct += s->destruct;
X		s->destruct = 0;
X	} else
X		bufd[0] = '\0';
X	if (s->popn) {
X		printf("Zap! %d popn sent.\n", s->popn);
X		sprintf(bufc, "%d %s\n",s->destruct,Race->Thing?"tons of biomass" : "population");
X		s2->mass += s->popn * Race->mass;
X		s2->popn += s->popn;
X		s->popn = 0;
X	} else
X		bufc[0] = '\0';
X	putship(load_shdata,s2,s->orders.object.number);
X
X      if (s2->owner!=s->owner) {
X	teleg_add("", telegram_buf);
X	teleg_add("BULLETIN!\n\n Audio-vibatory-physio-molecular transport device #",telegram_buf);
X	sprintf(buf,"%d just gave your ship #%d the following:\n", shipno, s->orders.object.number);
X	teleg_add(buf,telegram_buf);
X	teleg_add(bufr,telegram_buf);
X	teleg_add(bufd,telegram_buf);
X	teleg_add(buff,telegram_buf);
X	teleg_add(bufc,telegram_buf);
X	teleg_send(TELEG_PLAYER_AUTO, s2->owner, telegram_buf);
X      }
X    }
X
X
X    if (!jett) {
X
X      if (commod=='c') {
X	putsector(load_sectdata,sect,p->sectormappos + ( (int)s->ypos*p->Maxx+(int)s->xpos) * sizeof(sectortype) );
X    	close(load_sectdata);
X	free(sect);
X       }
X
X       putplanet(load_pdata,p,Stars[Dir.snum]->planetpos[Dir.pnum]);
X       close(load_pdata);
X       free(p);
X     }
X
X    if (Mod && first) {
X         first = 0;
X         if (s->whatorbits==LEVEL_UNIV)
X		deductAPs(APcount, 0, 1);	/* ded from sdata */
X         else 
X		deductAPs(APcount, s->storbits, 0);
X
X    }
X
X   } while (1);
X
X
X
X}
X
X
X
Xload_handler()
X{
X Ignore_filelocks = 0;
X close(load_shdata);
X close(load_pdata);
X close(load_sectdata);
X longjmp(main_jenv,1);
X}
END_OF_FILE
if test 7371 -ne `wc -c <'load.c'`; then
    echo shar: \"'load.c'\" unpacked with wrong size!
fi
# end of 'load.c'
fi
if test -f 'moveship.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'moveship.c'\"
else
echo shar: Extracting \"'moveship.c'\" \(9182 characters\)
sed "s/^X//" >'moveship.c' <<'END_OF_FILE'
X/*
X * Galactic Bloodshed (Robert Chansky, smq@b)
X *  moveship -- moves specified ship according to its orders.
X *	also deducts fuel from the ship's stores.
X */
X
X
X#include "vars.h"
X#include "ships.h"
X#include "shipdata.h"
X#include <math.h>
Xextern char telegram_buf[AUTO_TELEG_SIZE];
X  /* amount to move for each dir level. I arrived on these #'s only after
X	hours of dilligent tweaking */
X  /* amount to move for each directory level  */
Xfloat MoveConsts[] = { 3500.0, 300.0, 13.0 };
X  /* amnt to move for each ship speed level (ordered) */
Xfloat SpeedConsts[] = { 0.0, 0.80, 1.0, 1.2, 1.3 };
X  /* amount of fuel it costs to move at speed level */
Xfloat FuelConsts[] =  { 0.0, 0.75, 1.0, 1.3, 1.4 };
X
XMoveship(shipno,s,ost,dst,opl,dpl,dsh/*,sdatamod,stomod,stdmod,plomod,pldmod*/)
Xint shipno;
Xshiptype *s,*dsh;
Xstartype *ost,*dst;
Xplanettype *opl,*dpl;
X/*bool *sdatamod,*stomod,*stdmod,*plomod,*pldmod;*/
X{
X double heading,stardist,Ddist,dist,xdest,ydest,mfactor;
X char buf[100];
X float oldxpos,oldypos,fuse;
X register int i;
X bool move_err = 0;
X
X /*sdatamod = *stomod = *stdmod = *plomod = *pldmod = 0;*/
X
X printf("moving ship #%d\n",shipno);
X
X if (can_move(s) && !s->is_docked && !s->is_dead && s->whatdest!=LEVEL_UNIV) {
X
X    /* subtract fuel from the ship */
X   fuse = FuelConsts[s->speed] * FUEL_USE;
X   if (s->type == STYPE_POD)
X	fuse *= 0.4;
X
X   if (s->fuel < fuse) {
X	  /* ship is out of fuel; do whatever it is to do */
X	if (!s->notified) {
X	  s->notified = 1;
X	  teleg_add("",telegram_buf);	/* clear telegram buffer */
X	  sprintf(buf,"Telecomm from %s #%d\n\n",Shipnames[s->type],shipno);
X	  teleg_add(buf,telegram_buf);
X	  sprintf(buf,"%s #%d is out of fuel at ", Shipnames[s->type],shipno,
X				prin_ship_orbits(s));
X	  teleg_add(buf,telegram_buf);
X	  teleg_send(TELEG_PLAYER_AUTO, s->owner, telegram_buf);
X	}
X	return;
X   }
X
X/*******   move the ship towards dest ******/
X
X   oldxpos = s->xpos;	/* used in case of inablility to insert into data */
X   oldypos = s->ypos;
X
X   switch (s->whatdest) {
X      case LEVEL_STAR:
X	 xdest = dst->xpos;
X	 ydest = dst->ypos;
X	 break;
X      case LEVEL_PLAN:
X	/* dpl only defined & referenced if dest is a planet */
X	 xdest = dst->xpos + dpl->xpos;
X	 ydest = dst->ypos + dpl->ypos;
X	 break;
X      case LEVEL_SHIP:
X	 xdest = dsh->xpos;
X	 ydest = dsh->ypos;
X   }
X
X/*  update new xpos,ypos */
X   heading = atan2( xdest-s->xpos, (ydest - s->ypos)==0.0?0.000001:(ydest-s->ypos) );
X   mfactor = SpeedConsts[s->speed] * MoveConsts[s->whatorbits] 
X		/ (logscale((int)s->mass * 10) );
X   if (s->type == STYPE_POD)
X	mfactor *= 0.4;
X
X    /* keep from ending up in the middle of the system */
X   Ddist = sqrt( Distsq(s->xpos, s->ypos, xdest, ydest));
X   if (s->whatdest==LEVEL_UNIV)
X   	Ddist -= (SYSTEMSIZE - 1.0);
X   else if (s->whatdest==LEVEL_STAR)
X	Ddist -= PLORBITSIZE - 1.0;
X   else if (s->whatdest==LEVEL_SHIP && Ddist > SYSTEMSIZE) {
X     if (!s->notified) {
X	s->notified = 1;
X	teleg_add("",telegram_buf);
X   	sprintf(buf,"Telecomm from ship #%d at %s\n\n",shipno, 
X						prin_ship_orbits(s));
X   	teleg_add(buf,telegram_buf);
X   	sprintf(buf,"%s #%d cannot find destination ship #%d.\n", 
X				Shipnames[s->type],shipno,s->destshipno);
X   	teleg_add(buf,telegram_buf);
X   	teleg_send(TELEG_PLAYER_AUTO, s->owner, telegram_buf);
X	return;
X     }
X   }
X
X   if (Ddist <= 0.0)
X	Ddist = 0.0;
X
X   else if (Ddist > DIST_TO_LAND) {
X   	s->fuel -= fuse;
X   	printf(" subtracting %f fuel \n",fuse);
X    		/* subtract the fuel's mass */
X   	s->mass -= fuse * MASS_FUEL;
X
X		/* dont overshoot */
X   	xdest = sin(heading) * mfactor;
X    	if (abs(xdest) > Ddist) 
X		xdest = sgn(xdest) * Ddist;
X   	ydest = cos(heading) * mfactor;
X    	if (abs(ydest) > Ddist) 
X		ydest = sgn(ydest) * Ddist;
X   	s->xpos += xdest;
X   	s->ypos += ydest;
X   }
X
X/*****  check if far enough away from object it's orbiting to break orbit *****/
X   if (s->whatorbits==LEVEL_PLAN) {
X	 printf("dist from orbts planet is %lf\n",dist = sqrt( Distsq(s->xpos, s->ypos, 
X		ost->xpos+opl->xpos, ost->ypos+opl->ypos ) ) );
X	 if (dist > PLORBITSIZE) {
X		s->whatorbits = LEVEL_STAR;
X				/* insert ship to star data */
X		for (i=0; i<MAXSSHIPS && ost->shipnums[i]; i++) ;
X		if (i<MAXSSHIPS) {
X			ost->shipnums[i] = shipno;
X			ost->numships++;
X			/**stomod = 1;*/
X			printf("ship #%d now in system %s slot %d.\n",shipno,ost->name,i);
X				/* delete ship from planet list */
X			for (i=0; i<MAXPSHIPS && opl->shipnums[i]!=shipno; i++) ;
X			if (i<MAXPSHIPS) {
X		       		opl->shipnums[i]=0;
X		       		opl->numships--;
X		       		/*plomod = 1;*/
X	 	       		printf("ship #%d departed from planet /%s/%s.\n",shipno, ost->name, ost->pnames[s->pnumorbits]);
X			} else {move_err=1;printf("WARNING#1.. ship %d not found,pos%d.\n",shipno,i);}
X		} else {
X		   printf("WARNING#2..ship %d unable to insert.\n",shipno);
X		   move_err = 1;
X		   s->xpos = oldxpos;	/* cant insert, instead leave ship */
X		   s->ypos = oldypos;	/*  where it was.. */
X		}
X	 }
X   } else if (s->whatorbits==LEVEL_STAR) {
X	 printf("star orbits dist is %lf\n",dist = sqrt( Distsq(s->xpos, 
X	    s->ypos, ost->xpos, ost->ypos ) ) );
X	 if (dist > SYSTEMSIZE) {
X		s->whatorbits = LEVEL_UNIV;
X	     /* insert ship into universe data */
X		for (i=0; i<MAXUSHIPS && Sdata.shipnums[i]; i++) ;
X		if (i<MAXUSHIPS) {
X		   Sdata.shipnums[i] = shipno;
X		   Sdata.numships++;
X		   /*sdatamod = 1;	/* alert client program */
X	 	   printf("ship #%d departed from system %s.\n",shipno, ost->name);
X	     /* delete ship from star data */
X		   for (i=0; i<MAXSSHIPS && ost->shipnums[i]!=shipno; i++) ;
X		   if (i<MAXSSHIPS) {
X		       ost->shipnums[i]=0;
X		       ost->numships--;
X		       /*stomod = 1;*/
X		   } else {move_err=1;printf("WARNING#3.. ship %d not found,pos %d.\n",shipno,i);}
X		} else {	/* leave ship back where it was.. */
X		   printf("WARNING#4:cant insert into universe.\n");
X		   move_err = 1;
X		   s->xpos = oldxpos;
X		   s->ypos = oldypos;
X		}
X	 }
X   }
X
X/*******   check for arriving at destination *******/
X   if ( s->whatorbits==LEVEL_UNIV && (s->whatdest==LEVEL_STAR || s->whatdest==LEVEL_PLAN) ) {
X		/* dist to star not planet */
X	 stardist = (s->whatdest==LEVEL_PLAN) ? sqrt(Distsq(s->xpos,s->ypos,Stars[s->deststar]->xpos,Stars[s->deststar]->ypos)) : Ddist;
X	 printf("dist from dest syst is %lf\n",stardist);
X	 if (stardist <= SYSTEMSIZE) {
X	   s->whatorbits = LEVEL_STAR;
X	   s->storbits = s->deststar;
X	   if (s->type == STYPE_POD)
X		s->notified = 1;	/* signal to explode */
X			/* clear orders if the ship is not headed to a planet in
X			   this system */
X	     /* insert the ship */
X	   for (i=0; i<MAXSSHIPS && dst->shipnums[i]; i++) ;
X	   if (i<MAXSSHIPS) {
X		dst->shipnums[i] = shipno;
X		dst->numships++;
X		/**stdmod = 1;*/
X		 /* mark as explored by that player */
X		setbit(dst->explored, s->owner);
X		printf(" ship #%d arrived at system %s.\n",shipno,dst->name);
X	   	if (s->whatdest == LEVEL_STAR) {
X	   	  s->whatdest = LEVEL_UNIV;
X		  teleg_add("",telegram_buf);
X		  sprintf(buf,"Telecomm from ship #%d\n\n",shipno);
X		  teleg_add(buf,telegram_buf);
X		  sprintf(buf,"%s #%d arrived at system %s.\n",
X			   Shipnames[s->type], shipno, prin_ship_orbits(s));
X		  teleg_add(buf,telegram_buf);
X		  teleg_send(TELEG_PLAYER_AUTO, s->owner, telegram_buf);
X		}
X
X	       /* delete ship from Sdata */
X	        for (i=0; i<MAXUSHIPS && Sdata.shipnums[i]!=shipno; i++) ;
X	        if (i<MAXUSHIPS) {
X		     Sdata.shipnums[i] = 0;
X		     Sdata.numships--;
X		     /**sdatamod = 1;*/
X	        } else printf("can't delete ship #%d from univ.data\n",shipno);
X	   } else {
X		   printf("ship #%d cannot be inserted into star %d!\n",shipno,s->deststar);
X		   move_err = 1;
X		   s->xpos = oldxpos;
X		   s->ypos = oldypos;
X	   }
X	 }
X   } else if ( (s->whatdest==LEVEL_PLAN) && (s->deststar==s->storbits)  &&
X		!(s->whatorbits==LEVEL_PLAN && s->pnumorbits==s->destpnum)) {
X			/* headed for a planet in this system &
X			   we are not already there.. */
X	 printf("dist from target planet is %lf\n",Ddist );
X	 if (Ddist<=PLORBITSIZE) {
X	   s->whatorbits = LEVEL_PLAN;
X	   s->pnumorbits = s->destpnum;	
X		/* don't clear orders */
X	  /* insert the ship */
X	   for (i=0; dpl->shipnums[i] && i<MAXPSHIPS; i++) ;
X	   if (i<MAXPSHIPS) {
X		dpl->shipnums[i] = shipno;
X		dpl->numships++;
X		 /* mark as explored by that player */
X		dpl->info[s->owner-1].explored = 1;
X		teleg_add("",telegram_buf);
X		sprintf(buf,"Telecomm from ship #%d\n\n",shipno);
X		teleg_add(buf,telegram_buf);
X		sprintf(buf,"%s #%d arrived at planet %s.\n",Shipnames[s->type],
X					shipno, prin_ship_orbits(s));
X		teleg_add(buf,telegram_buf);
X		teleg_send(TELEG_PLAYER_AUTO, s->owner, telegram_buf);
X		/**pldmod = 1;*/
X	   	printf("ship #%d arrived at planet /%s/%s,slot %d.\n",shipno, ost->name, ost->pnames[s->pnumorbits],i);
X	       /* delete the ship from star */
X	   	for (i=0; ost->shipnums[i]!=shipno && i<MAXSSHIPS; i++) ;
X	   	if (i<MAXSSHIPS) {
X			ost->shipnums[i] = 0;
X			ost->numships--;
X			/**stomod = 1;*/
X	   	} else {
X			move_err=1;
X			printf("WARNING #5: can't delete from deststar!\n"); 
X			s->xpos = oldxpos;
X			s->ypos = oldypos;
X		}
X	   } else {
X		printf(" WARNING #6! can't insert\n");
X		move_err = 1;
X		s->xpos = oldxpos;
X		s->ypos = oldypos;
X	   }
X	 }
X  }
X }
X}
END_OF_FILE
if test 9182 -ne `wc -c <'moveship.c'`; then
    echo shar: \"'moveship.c'\" unpacked with wrong size!
fi
# end of 'moveship.c'
fi
if test -f 'survey.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'survey.c'\"
else
echo shar: Extracting \"'survey.c'\" \(4097 characters\)
sed "s/^X//" >'survey.c' <<'END_OF_FILE'
X/*
X * Galactic Bloodshed (Robert Chansky, smq@b)
X * survey.c -- print out survey for planets  
X */
X
X#include "vars.h"
X#include "races.h"
Xfloat compatibility();
Xextern char desshow();
X
Xsurvey(APcount, argn,args)
Xint APcount;
Xint argn;
Xchar args[MAXARGS][COMMANDSIZE];
X{
Xint lowx,hix,lowy,hiy,x2;
Xsectortype *s;
Xplanettype *p;
Xint survey_pdata,survey_sectdata;
X
Xif (argn==1) {   /* no args */
X
X if (Dir.level==LEVEL_PLAN) {
X  openpdata(&survey_pdata);
X  getplanet(survey_pdata,&p,Stars[Dir.snum]->planetpos[Dir.pnum]);
X  close(survey_pdata);
X  printf("%s:\n",Stars[Dir.snum]->pnames[Dir.pnum]);
X  printf("gravity   x,y absolute     x,y relative to %s\n",Stars[Dir.snum]->name);
X  printf("%7.2f   %7.1f,%7.1f   %8.1f,%8.1f\n", 
X		gravity(p),
X		p->xpos + Stars[Dir.snum]->xpos,
X		p->ypos + Stars[Dir.snum]->ypos,
X		p->xpos, p->ypos );
X
X  printf("======== planetary conditions: ========\n");
X  printf("atmosphere concentrations:\n");
X  printf("     methane %02d%%(%02d%%)     oxygen %02d%%(%02d%%)\n",
X		p->conditions[METHANE], Race->conditions[METHANE],
X		p->conditions[OXYGEN], Race->conditions[OXYGEN] );
X  printf("         CO2 %02d%%(%02d%%)   hydrogen %02d%%(%02d%%)      temperature: %3d (%3d)\n",
X		p->conditions[CO2], Race->conditions[CO2],
X		p->conditions[HYDROGEN], Race->conditions[HYDROGEN],
X		Temp(p->conditions[TEMP]), Temp(Race->conditions[TEMP]) );
X  printf("    nitrogen %02d%%(%02d%%)     sulfur %02d%%(%02d%%)           normal: %3d\n",
X		p->conditions[NITROGEN], Race->conditions[NITROGEN],
X		p->conditions[SULFUR], Race->conditions[SULFUR],
X		Temp(p->conditions[RTEMP]) );
X  printf("      helium %02d%%(%02d%%)      other %02d%%(%02d%%)         %s: %d%%\n",
X		p->conditions[HELIUM], Race->conditions[HELIUM],
X		p->conditions[OTHER], Race->conditions[OTHER],
X		p->conditions[TOXIC] > 80 ? "TOXICITY" : "toxicity",
X		p->conditions[TOXIC]);
X  printf("Total planetary compatibility: %.2f%%\n", compatibility(p, Race) );
X
X  printf("fuel_stock  resource_stock dest_pot.   %s    ^%s\n",
X			Race->Thing ? "biomass" : "popltn",
X			Race->Thing ? "biomass" : "popltn");
X  printf("%10lu  %14lu %9lu  %7lu%11lu\n", p->info[Playernum-1].fuel, 
X		 p->info[Playernum-1].resource, 
X		 p->info[Playernum-1].destruct,
X		 p->popn, p->maxpopn);
X
X  free(p);
X
X } else if (Dir.level==LEVEL_STAR) {
X
X  printf("Star %s\n",Stars[Dir.snum]->name);
X  printf("locn: %f,%f\n",Stars[Dir.snum]->xpos,Stars[Dir.snum]->ypos);
X  printf("gravity: %.2f\tstability: ", Stars[Dir.snum]->gravity);
X  if (Race->tech >= TECH_SEE_STABILITY)
X  	printf("%d%% (%s)\n",
X		Stars[Dir.snum]->stability, 
X		Stars[Dir.snum]->stability<20 ? "stable" :
X		Stars[Dir.snum]->stability<40 ? "unstable" : 
X		Stars[Dir.snum]->stability<60 ? "dangerous" : 
X		Stars[Dir.snum]->stability<100 ? "WARNING! nova iminent!" : 
X		"undergoing nova" );
X  else
X	printf("(cannot determine)\n");
X
X  printf("%d planets are ",Stars[Dir.snum]->numplanets);
X  for (x2=0; x2<Stars[Dir.snum]->numplanets; x2++)
X	printf("%s\t", Stars[Dir.snum]->pnames[x2]);
X  putchr('\n');
X
X } else if (Dir.level==LEVEL_UNIV)
X  printf("It's just _there_, you know?\n");
X} else if (argn==2)      /* argn==2, survey is on a sector */
X if (Dir.level==LEVEL_PLAN) {
X  openpdata(&survey_pdata);
X  getplanet(survey_pdata,&p,Stars[Dir.snum]->planetpos[Dir.pnum]);
X  close(survey_pdata);
X  opensectdata(&survey_sectdata);
X  getsmap(survey_sectdata,Smap,p->sectormappos,p->Maxx*p->Maxy);
X  close(survey_sectdata);
X
X  get4args(args[1],&x2,&hix,&lowy,&hiy); 
X  if (hix>=p->Maxx) hix=p->Maxx-1;
X  if (x2<0) x2=0;
X  if (lowy>=p->Maxy) lowy=p->Maxy-1;
X  if (hiy<0) hiy=0;
X  		/* ^^^ translate to lowx:hix,lowy:hiy */
X
X  printf(" x,y des eff mob frt res popn ^popn\n");
X
X  for (; lowy<=hiy; lowy++)
X   	for (lowx=x2; lowx<=hix; lowx++) {
X    		s=(&(Smap[lowy*p->Maxx+lowx]));
X    		/*if (s->owner==Playernum)*/
X       		printf("%2d,%-2d %c%4u%4u%4u%4u%5u%6d\n",
X			lowx,lowy,desshow(p,lowx,lowy), s->eff, s->mobilization,
X			s->fert, s->resource, s->popn,
X			maxsupport(s) );
X 	}
X free(p);
X } else
X	printf("scope must be a planet.\n");
X else if (argn>2)
X 	printf("survey: error in args.\n");
X
X}
END_OF_FILE
if test 4097 -ne `wc -c <'survey.c'`; then
    echo shar: \"'survey.c'\" unpacked with wrong size!
fi
# end of 'survey.c'
fi
echo shar: End of archive 3 \(of 7\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 7 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0