[net.sources.games] Trek73 Part 3

okamoto@ucbvax.BERKELEY.EDU (The New Number Who) (12/15/86)

This is a repost of part 3 of Trek73.  Apparently some mailers
couldn't handle a file that large.  My apologies.

Some people have mailed me that there are some problems in the
files parsit.c and save.c.  Both are due to SysV incompatabilities
with 4.[23]BSD.  Parsit has to do with a null pointer due to a bad
set of loop conditions.  Also, index should be replaced by strchr.
Save has some 4.3isms in it.  The routine symlink sets up a symbolic
link to a file.  SIGTSTP is a stop signal from the terminal (^Z).
You can probably just delete them.  Sorry about save, we truncated it
from rogue's save routine.

Enjoy,

The New Number Who,	okamoto@ucbvax.berkeley.edu
Jeff Okamoto		..!ucbvax!okamoto
"He took too much LDS while at Berkeley"

-----
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	firing.c
#	globals.c
#	init.c
#	main.c
# This archive created: Mon Dec 15 07:44:10 1986
# By:	Jeff Okamoto ()
export PATH; PATH=/bin:$PATH
if test -f 'firing.c'
then
	echo shar: will not over-write existing file "'firing.c'"
else
cat << \SHAR_EOF > 'firing.c'
/*
 * TREK73: firing.c
 *
 * Take care of firing phasers and torpedos for both enemy
 * and fed ships.
 *
 * phaser_firing, torpedo_firing, ship_detonate, torp_detonate
 *
 */

#include "externs.h"


phaser_firing(sp)
struct ship *sp;
{
	register int i;
	register float j;
	int	hit;
	struct	ship *ep;
	struct	torpedo *tp;
	int	s;
	int	x, y;
	struct	ship *target;
	struct	list *lp;
	float	bear;
	struct 	ship *fed;


	fed = shiplist[0];
	for (i=0; i<sp->num_phasers; i++) {
		if (sp->phasers[i].status & P_FIRING)
			break;
	}
	if (i == sp->num_phasers)
		return 0;
	sp->phasers[i].status &= ~P_FIRING;
	target = sp->phasers[i].target;
	/*
	 * Put in j the relative bearing of the phasers relative to the ship
	 * Put in bear the absolute direction the phasers are pointing
	 */
	bear = sp->phasers[i].bearing + sp->course;
	j = rectify(sp->phasers[i].bearing);
	if (betw(j, sp->p_blind_left, sp->p_blind_right)
	    && !is_dead(sp, S_ENG))
		return 0;
	if (target != NULL && is_dead(target, S_DEAD)) {
		if ((sp = fed) && (!shutup[PHASERS+i])
		    && !(is_dead(sp, S_DEAD))) {
			printf("%s phaser %d unlocking\n",
			    sp->name, i+1);
			shutup[PHASERS+i]++;
		}
		sp->phasers[i].target = NULL;
		return 0;
	}
	if (cantsee(sp))
		e_cloak_off(sp, fed);
	printf(" <%s frng phasers>\n", sp->name);
	for (lp = &head; lp != tail; lp = lp->fwd) {
		if (lp->type == 0)
			continue;
		ep = NULL;
		tp = NULL;
		if (lp->type == I_SHIP) {
			ep = lp->data.sp;
			if (ep == sp)
				continue;
			x = ep->x;
			y = ep->y;
		} else {
			tp = lp->data.tp;
			x = tp->x;
			y = tp->y;
		}
		hit = phaser_hit(sp, x, y, &sp->phasers[i], bear);
		if (hit <= 0)
			continue;
		if (tp) {
			if (tp->timedelay > segment) {
				switch (lp->type) {
				case I_TORPEDO:
					printf("hit on torpedo %d\n",
						tp->id);
					break;
				case I_ENG:
					printf("hit on %s's engineering\n",
						tp->from->name);
					break;
				case I_PROBE:
					printf("hit on probe %d\n", 
						tp->id);
					break;
				default:
					fprintf(stderr, "hit on lp->type\n",
						lp->type);
					break;
				}
				tp->timedelay = 0.;
			}
			tp->fuel -= hit/2;
			if (tp->fuel < 0)
				tp->fuel = 0;
			continue;
		}
		/*
		 * Determine which shield was hit
		 */
		j = rectify(bearing(x, sp->x, y, sp->y) - ep->course);
		if (j > 315.0 || j < 45.0)
			s = 1;
		else if (j < 135.0)
			s = 2;
		else if (j < 225.0)
			s = 3;
		else
			s = 4;
		(void) damage(hit, ep, s, &p_damage, D_PHASER);
	}
	/*
	 * Reduce the load by the firing percentage
	 */
	sp->phasers[i].load *= 1.0 - (float) sp->p_percent / 100;
	return 0;
}

torpedo_firing(sp)
struct ship *sp;
{
	register int i;
	register float j;
	register int th;
	struct	torpedo *tp;
	struct	ship *target;
	struct	list *lp;
	float	bear;
	struct	ship *fed;

	fed = shiplist[0];
	for (i=0; i<sp->num_tubes; i++) {
		if (sp->tubes[i].status & T_FIRING)
			break;
	}
	if (i == sp->num_tubes)
		return 0;
	sp->tubes[i].status &= ~T_FIRING;
	th = sp->tubes[i].load;
	if (th == 0)
		return 0;
	target = sp->tubes[i].target;
	/*
	 * Put in j the relative bearing of the tubes to the ship
	 * Put in bear the absolute direction the tubes are pointing
	 */
	bear = sp->tubes[i].bearing + sp->course;
	j = rectify(sp->tubes[i].bearing);
	if (betw(j, sp->t_blind_left, sp->t_blind_right) && !is_dead(sp, S_ENG))
		return 0;
	if (target != NULL && (is_dead(target, S_DEAD))) {
		if ((sp == fed) && !shutup[TUBES+i] && !is_dead(sp, S_DEAD)) {
			printf("   tube %d disengaging\n", i+1);
			shutup[TUBES+i]++;
		}
		sp->tubes[i].target = NULL;
		return 0;
	}
	sp->tubes[i].load = 0;
	lp = newitem(I_TORPEDO);
	lp->type = I_TORPEDO;
	lp->data.tp = MKNODE(struct torpedo, *, 1);
	if (lp->data.tp == (struct torpedo *)NULL) {
		fprintf(stderr, "torpedo_firing: malloc failed\n");
		exit(2);
	}
	tp = lp->data.tp;
	tp->from = sp;
	tp->x = sp->x;
	tp->y = sp->y;
	tp->target = NULL;
	tp->course = rectify(bear);
	tp->fuel = th;
	tp->speed = sp->t_lspeed + sp->warp;
	tp->newspeed = tp->speed;
	tp->timedelay = (float)sp->t_delay;
	tp->prox = sp->t_prox;
	tp->id = new_slot();
	tp->type = TP_TORPEDO;
	if (teletype)
		printf("\007");
	if (cantsee(sp))
		e_cloak_off(sp, fed);
	printf(" <<%s frng torpedo %d>>", sp->name, tp->id);
	if (teletype)
		printf("\007");
	printf("\n");
	return 1;
}

int ship_detonate(sp, lp)
struct ship *sp;
struct list *lp;
{
	register int fuel;
	register int i;

	fuel = 0;
	printf("++%s++ destruct.\n", sp->name);
	for (i=0; i<sp->num_phasers; i++)
		if (!(sp->phasers[i].status & P_DAMAGED))
			fuel += min(sp->phasers[i].load, MAX_PHASER_CHARGE);
	for (i=0; i<sp->num_tubes; i++)
		if (!(sp->tubes[i].status & T_DAMAGED))
			fuel += min(sp->tubes[i].load, MAX_TUBE_CHARGE);
	fuel += sp->pods;
	antimatter_hit((char *) sp, sp->x, sp->y, fuel);
	lp->type = 0;
	for (i=0; i< S_NUMSYSTEMS; i++)
		sp->status[i] = 100;	/* He's dead, Jim */
	sp->cloaking = C_NONE;
	sp->complement = -1;
}


int torp_detonate(tp, lp)
struct torpedo *tp;
struct list *lp;
{

	switch (lp->type) {
		case I_TORPEDO:
			printf(":: torp %d ::\n", tp->id);
			break;
		case I_PROBE:
			printf("** probe %d **\n", tp->id);
			break;
		case I_ENG:
			printf("## %s engineering ##\n", tp->from->name);
			break;
		default:
			fprintf(stderr, "torp_detonate lp->type %d\n",lp->type);
			break;
	}
	antimatter_hit((char *) tp, tp->x, tp->y, tp->fuel);
	return_slot(tp->id);
	delitem(lp);
}
SHAR_EOF
chmod +x 'firing.c'
fi # end of overwriting check
if test -f 'globals.c'
then
	echo shar: will not over-write existing file "'globals.c'"
else
cat << \SHAR_EOF > 'globals.c'
/*
 *
 * TREK73: globals.c
 *
 * Global variable declarations
 *
 */

#include "externs.h"

extern	int fire_phasers(), fire_tubes(), lock_phasers(), lock_tubes(),
	turn_phasers(), turn_tubes(), load_tubes(), phaser_status(),
	tube_status(), launch_probe(), probe_control(), pos_report(),
	pos_display(), pursue(), elude(), helm(), self_scan(), scan(),
	alter_power(), jettison_engineering(), detonate_engineering(),
	alterpntparams(), play_dead(), corbomite_bluff(), surrender_ship(),
	request_surrender(), self_destruct(), abort_self_destruct(),
	save_game(), survivors(), help(), vers();

extern 	int standard_strategy();

char encstr[] = "\211g\321_-\251b\324\237;\255\263\214g\"\327\224.,\252|9\265=\357+\343;\311]\341`\251\b\231)\266Y\325\251";

char version[] = "TREK73 Version 3.2 08/17/86";

char *sysname[] = {
	"Computer",		/* S_COMP */
	"Sensors",		/* S_SENSOR */
	"Probe launcher",	/* S_PROBE */
	"Warp Drive",		/* S_WARP */
};

char *statmsg[] = {			/* When this system is dead */
	"computer inoperable",		/* S_COMP */
	"sensors annihilated",		/* S_SENSOR */
	"probe launcher shot off",	/* S_PROBE */
	"warp drive disabled",		/* S_WARP */
	"engineering jettisoned",	/* S_ENG */
} ;

struct damage p_damage = {
	50, 2, 20, 10, 3,		/* eff, fuel, regen, crew, weapon */
	1000,	"Computer destroyed.",		/* S_COMP */
	500,	"Sensors demolished.",		/* S_SENSOR */
	100,	"Probe launcher crushed.",	/* S_PROBE */
	50,	"Warp drive destroyed.",	/* S_WARP */
} ;

struct damage a_damage = {
	100, 3, 10, 7, 6,		/* eff, fuel, regen, crew, weapon */
	1500,	"Computer banks pierced.",	/* S_COMP */
	750,	"Sensors smashed.",		/* S_SENSOR */
	150,	"Probe launcher shot off.",	/* S_PROBE */
	75,	"Warp drive disabled.",		/* S_WARP */
} ;


char *feds[] = {
	"Constitution", "Enterprise", "Hornet", "Lexington", "Potempkin",
	"Hood", "Kongo", "Republic", "Yorktown",
} ;

struct race_info aliens[MAXFOERACES] = {
	{
		"Klingon", "Empire", 0, 25, 25, 75, 75, 0,
		{ "Annihilation", "Crusher", "Devastator", "Merciless",
		  "Nemesis", "Pitiliess", "Ruthless", "Savage", "Vengeance",
		},
		{ "C-9 Dreadnought", "D-7 Battle Cruiser",
		  "D-6 Light Battlecruiser", "F-5L Destroyer",
		},
		{ "Koloth", "Kang", "Kor", "Krulix", "Korax", "Karg",
		  "Kron", "Kumerian",
		}, 0,
	},
	{
		"Romulan", "Star Empire", 0, 5, 5, 80, 50, 0,
		{ "Avenger", "Defiance", "Fearless", "Harrower", "Intrepid",
		  "Relentless", "Seeker", "Torch", "Vigilant",
		},
		{ "Condor Dreadnought", "Firehawk Heavy Cruiser",
		  "Sparrowhawk Light Cruiser", "Skyhawk Destroyer",
		},
		{ "Tal", "Tiercellus", "Diana", "Tama", "Subeus", "Turm",
		  "Strell", "Scipio",
		}, 0,
	},
	{
		"Kzinti", "Hegemony", 0, 50, 50, 50, 50, 0,
		{ "Black Hole", "Comet", "Ecliptic", "Galaxy", "Meteor",
		  "Nova", "Pulsar", "Quasar", "Satellite",
		},
		{ "Space Control Ship", "Strike Cruiser", "Light Cruiser",
		  "Destroyer",
		},
		{ "Hunter", "\"Cat Who Sleeps With Dogs\"", "Fellus", "Corda",
		  "\"Cat Who Fought Fuzzy Bear\"", "", "", "",
		}, 0,
	},
	{
		"Gorn", "Confederation", 0, 80, 50, 50, 50, 0,
		{ "Chimericon", "Dragonicon", "Ornithocon", "Predatoricon",
		  "Reptilicon", "Serpenticon", "Tyranicon", "Vipericon",
		  "Wyvericon",
		},
		{ "Tyrannosaurus Rex Dreadnought", "Allosaurus Heavy Cruiser",
		  "Megalosaurus Light Cruiser", "Carnosaurus Destroyer",
		},
		{ "Sslith", "Dardiss", "Ssor", "Sslitz", "S'Arnath",
		  "Zor", "", "",
		}, 0,
	},
	{
		"Orion", "Pirates", 0, 95, 5, 50, 60, 0,
		{ "Deuce Coupe", "Final Jeopardy", "Long John Dilithium",
		  "Millennium Pelican", "Omega Race", "Penzance",
		  "Road Warrior", "Scarlet Pimpernel", "Thunderduck",
		},
		{ "Battle Raider", "Heavy Cruiser", "Raider Cruiser",
		  "Light Raider",
		},
		{ "Daniel \"Deth\" O'Kay", "Neil Ricca", "Delilah Smith",
		  "Hamilcar", "Pharoah", "Felna Greymane", "Hacker", 
		  "Credenza",
		}, 0,
	},
	{
		"Hydran", "Monarchy", 0, 50, 50, 50, 50, 0,
		{ "Bravery", "Chivalry", "Devotion", "Fortitude", "Loyalty",
		  "Modesty", "Purity", "Resolution", "Tenacity",
		},
		{ "Paladin Dreadnought", "Ranger-class Cruiser",
		  "Horseman Light Cruiser", "Lancer Destroyer",
		},
		{ "Hypantspts", "S'Lenthna", "Hydraxan", "", "", "",
		  "", "",
		}, 0,
	},
	{
		"Lyran", "Empire", 0, 50, 50, 50, 50, 0,
		{ "Bandit", "Claw", "Dangerous", "Fury", "Mysterious",
		  "Sleek", "Tiger", "Vicious", "Wildcat",
		},
		{ "Lion Dreadnought", "Tiger Cruiser",
		  "Panther Light Cruiser", "Leopard Destroyer",
		},
		{ "Kleave", "Leyraf", "Kuhla", "Nashar",
		  "Prekor", "Ffarric", "Rippke", "Larkahn",
		}, 0,
	},
	{
		"Tholian", "Holdfast", 0, 75, 25, 50, 50, 0,
		{ "Bismark", "Centaur", "Draddock", "Forbin", "Kreiger",
		  "Shlurg", "Trakka", "Varnor", "Warrior",
		},
		{ "Tarantula Dreadnought", "Cruiser", "Improved Patrol Cruiser",
		  "Patrol Cruiser",
		},
		{ "Secthane", "Kotheme", "Sectin", "Brezgonne", "", "",
		  "", "",
		}, 0,
	},
	{
		"Monty Python", "Flying Circus", 0, -1, -1, -1, -1, 0,
		{ "Blancmange", "Spam", "R.J. Gumby", "Lumberjack",
		  "Dennis Moore", "Ministry of Silly Walks", "Argument Clinic",
		  "Piranha Brothers", "Upper Class Twit of the Year",
		},
		{ "Thingee", "Thingee", "Thingee", "Thingee",
		},
		{ "Cleese", "Chapman", "Idle", "Jones", "Gilliam", "Bruce",
		  "Throatwobblermangrove", "Arthur \"Two Sheds\" Jackson",
		}, 0,
	}
};


float init_p_turn[MAXPHASERS][MAXPHASERS] = {
	{ 666.666 },
	{ 0.0 },
	{ 0.0, 0.0 },
	{ 90.0, 0.0, 270.0 },
	{ 90.0, 0.0, 0.0, 270.0 },
	{ 90.0, 0.0, 0.0, 0.0, 270.0 },
	{ 90.0, 90.0, 0.0, 0.0, 270.0, 270.0 },
	{ 90.0, 90.0, 0.0, 0.0, 0.0, 270.0, 270.0 },
	{ 90.0, 90.0, 0.0, 0.0, 0.0, 0.0, 270.0, 270.0 },
	{ 90.0, 90.0, 90.0, 0.0, 0.0, 0.0, 270.0, 270.0, 270.0 },
	{ 90.0, 90.0, 90.0, 0.0, 0.0, 0.0, 0.0, 270.0, 270.0, 270.0 },
};

float init_t_turn[MAXTUBES][MAXTUBES] = {
	{ 666.666 },
	{ 0.0 },
	{ 0.0, 0.0 },
	{ 60.0, 0.0, 300.0 },
	{ 60.0, 0.0, 0.0, 300.0 },
	{ 60.0, 0.0, 0.0, 0.0, 300.0 },
	{ 120.0, 60.0, 0.0, 0.0, 300.0, 240.0 },
	{ 120.0, 60.0, 0.0, 0.0, 0.0, 300.0, 240.0 },
	{ 120.0, 60.0, 60.0, 0.0, 0.0, 300.0, 300.0, 240.0 },
	{ 120.0, 60.0, 60.0, 0.0, 0.0, 0.0, 300.0, 300.0, 240.0 },
	{ 120.0, 120.0, 60.0, 60.0, 0.0, 0.0, 300.0,300.0, 240.0, 240.0 },
};

/*
 * for the linked list of items in space
 */
struct	list head;
struct	list *tail;

/*
 * Global definitions
 */
float	segment = 0.05;		/* Segment time */
float	timeperturn = 2.0;	/* Seconds per turn */

struct	ship *shiplist[10];	/* All the ships in the battle */

char	home[256];		/* Path to user's home directory */
char	savefile[256];		/* Path to save file */
char	captain[30];		/* captain's name */
char	science[30];		/* science officer's name */
char	engineer[30];		/* engineer's name */
char	com[30];		/* communications officer's name */
char	nav[30];		/* navigation officer's name */
char	helmsman[30];		/* helmsman's name */
char	title[9];		/* captain's title */
char	foerace[30];		/* enemy's race */
char	foename[30];		/* enemy's captain's name */
char	foestype[30];		/* enemy's ship type */
char	empire[30];		/* What the enemy's empire is called */
char	class[3];		/* Class of own ship */
char	foeclass[3];		/* Class of enemy ship(s) */
int	shipnum;		/* number of ships this time out */
int	enemynum;		/* Enemy identifier */
int	terse = 0;		/* print out initial description? */
int	silly = 0;		/* Use the Monty Python's Flying Curcus? */
int	defenseless = 0;	/* defensless ruse status */
int	corbomite = 0;		/* corbomite bluff status */
int	surrender = 0;		/* surrender offered by federation? */
int	surrenderp = 0;		/* Did we request that the enemy surrenders? */
int	restart = 0;		/* Should we restart the game? */
char	shutup[HIGHSHUTUP];	/* Turn off messages after first printing */
char	slots[HIGHSLOT];	/* Id slots */
int	global = NORMAL;	/* Situation status */
char	*options;		/* Environment variable */
char	sex[20];		/* From environment */
char	shipname[30];		/* From environment */
char	racename[20];		/* From environment */
int	reengaged = 0;		/* Re-engaging far-off ships? */
char    com_delay[6];		/* Number of seconds per real-time turn */
int	teletype = 0;		/* Flag for special teletype options */
int	time_delay = 30;	/* Time to enter command */
int	trace = TR_OFF;		/* Trace flag for debugging and records */
char	can_cloak = 0;		/* Can enemy ship cloak? */
double	o_bpv;			/* BPV of us */
double	e_bpv;			/* BPV of enemy */

struct ship_stat	us;	/* Our ship definition */
struct ship_stat	them;	/* Their ship definition */

struct  cmd cmds[] = {
	{ fire_phasers,		"1",	"Fire phasers",			TURN },
	{ fire_tubes,		"2",	"Fire photon torpedoes",	TURN },
	{ lock_phasers, 	"3",	"Lock phasers onto target",	TURN },
	{ lock_tubes,		"4",	"Lock tubes onto target",	TURN },
	{ turn_phasers,		"5",	"Manually rotate phasers",	TURN },
	{ turn_tubes,		"6",	"Manually rotate tubes",	TURN },
	{ phaser_status,	"7",	"Phaser status",		FREE },
	{ tube_status,		"8",	"Tube status",			FREE },
	{ load_tubes,		"9",	"Load/unload torpedo tubes",	TURN },
	{ launch_probe,		"10",	"Launch antimatter probe",	TURN },
	{ probe_control,	"11",	"Probe control",		TURN },
	{ pos_report,		"12",	"Position report",		FREE },
	{ pos_display,		"13",	"Position display",		FREE },
	{ pursue,		"14",	"Pursue an enemy vessel",	TURN },
	{ elude,		"15",	"Elude an enemy vessel",	TURN },
	{ helm,			"16",	"Change course and speed",	TURN },
	{ self_scan,		"17",	"Damage report",		FREE },
	{ scan,			"18",	"Scan enemy",			TURN },
	{ alter_power,		"19",	"Alter power distribution",	TURN },
	{ jettison_engineering,	"20",   "Jettison engineering",		TURN },
	{ detonate_engineering,	"21",  	"Detonate engineering",		TURN },
	{ alterpntparams,	"22",	"Alter firing parameters", 	TURN},
	{ play_dead,		"23",	"Attempt defenseless ruse",	TURN },
	{ corbomite_bluff,	"24",	"Attempt corbomite bluff(s)",	TURN },
	{ surrender_ship,	"25",	"Surrender",			TURN },
	{ request_surrender,	"26",	"Ask enemy to surrender",	TURN },
	{ self_destruct,	"27",	"Initiate self-destruct",	TURN },
	{ abort_self_destruct,	"28",	"Abort self-destruct",		TURN },
	{ survivors,		"29",	"Survivors report",		FREE },
	{ vers,			"30",	"Print version number",		FREE },
	{ save_game,		"31",	"Saves game",			FREE },
	{ help,			"32",	"Reprints above list",		FREE },
	{ NULL,			NULL,	NULL,				TURN },
} ;

int	high_command = 32;	/* XXX */

	/* used to print cmd list */
int	cmdarraysize = sizeof(cmds) / sizeof (struct cmd) -1; 

/*	Strategy table */
int (*strategies[])() = {
	standard_strategy,
};
SHAR_EOF
chmod +x 'globals.c'
fi # end of overwriting check
if test -f 'init.c'
then
	echo shar: will not over-write existing file "'init.c'"
else
cat << \SHAR_EOF > 'init.c'
/*
 * TREK73: init.c
 *
 * Game initialization routines
 *
 * name_crew, init_ships
 *
 */

#include "externs.h"
#include <fcntl.h>

name_crew()
{
	char buf1[30];
	int loop;
	int len;

	if (com_delay[0] != 0)
		time_delay = atoi(com_delay);
	if (science[0] == '\0')
		(void) strcpy(science, "Spock");
	if (engineer[0] == '\0')
		(void) strcpy(engineer, "Scott");
	if (com[0] == '\0')
		(void) strcpy(com, "Uhura");
	if (nav[0] == '\0')
		(void) strcpy(nav, "Chekov");
	if (helmsman[0] == '\0')
		(void) strcpy(helmsman, "Sulu");
	if (captain[0] == '\0') {
		printf("\n\nCaptain: my last name is ");
		if (gets(buf1) == NULL || *buf1 == '\0')
			exit(1);
		(void) strncpy (captain, buf1, sizeof captain);
		captain[sizeof captain - 1] = '\0';
	}
	if (captain[0] == '*') {
		terse = 1;
		len = strlen(captain) + 1;
		for (loop = 1; loop <= len; loop++)
			captain[loop-1] = captain[loop];
	}
	if (sex[0] != '\0') {
		(void) strncpy(buf1, sex, sizeof sex);
		sex[sizeof sex - 1] = '\0';
	} else {
		printf("%s: My sex is: ",captain);
		if (gets(buf1) == NULL || *buf1 == '\0')
			exit(1);
	}
	switch(*buf1) {
	case 'M':
	case 'm':
		(void) strcpy(title, "Sir");
		break;
	case 'F':
	case 'f':
		(void) strcpy(title, "Ma'am");
		break;
	default :
		switch ((int)(random() % 6)) {
		case 0:
			(void) strcpy(title, "Fag");
			break;
		case 1:
			(void) strcpy(title, "Fairy");
			break;
		case 2:
			(void) strcpy(title, "Fruit");
			break;
		case 3:
			(void) strcpy(title, "Weirdo");
			break;
		case 4:
			(void) strcpy(title, "Gumby");
			break;
		case 5:
			(void) strcpy(title, "Freak");
			break;
		}
	}
}


init_ships()
{
	struct ship_stat *my_class, *his_class, *ship_class(), *read_class();
	int myread, hisread;	/* Did we read from file? */
	register int i;
	register int j;
	register struct ship *sp;
	register struct list *lp;
	int range;
	float bear;
	char *tmp;
	int swap1, swap2;
	int offset;
	int loop;
	char buf1[30];

getships:
	printf("   I'm expecting [1-9] enemy vessels ");
	if (gets(buf1) == NULL || *buf1 == NULL) {
		printf("%s:  %s, Starfleet Command reports that you have been\n",
		    com, title);
		puts("   relieved of command for dereliction of duty.");
		exit(1);
	}
	if (buf1[0] != '\0') {
		i = atoi(buf1);
		if (i < 1 || i > MAXESHIPS) {
			printf("%s:   %s, Starfleet Command reports that it can only\n",
			    com, title);
			printf("   be from 1 to 9.  Try again.\n");
			printf("%s:  Correct, Lieutenant -- just testing your attention..\n",
			    captain);
			goto getships;
		}
		shipnum = i;
	} else
		shipnum = randm(MAXESHIPS);
	for (loop = 0; loop < shipnum; loop++);
		slots[loop] = 'X';
	offset = !silly;
	if (racename[0] == '\0') {
		enemynum = randm(MAXFOERACES - offset) - 1;
	} else {
		for (loop=0; loop<MAXFOERACES; loop++)
			if (!strncmp(racename, aliens[loop].race_name, strlen(racename))) {
				enemynum = loop;
				break;
			}
		if (loop == MAXFOERACES) {
			printf("Cannot find race %s.\n", racename);
			enemynum = randm(MAXFOERACES - offset) - 1;
		}
	}
	if (class[0] == '\0')
		(void) strcpy(class, "CA");
	if (foeclass[0] == '\0')
		(void) strcpy(foeclass, "CA");
	myread = 0;
	hisread = 0;
	if ((my_class = ship_class(class)) == NULL)
		if ((my_class = read_class(class, 0)) == NULL)
			my_class = ship_class("CA");
		else
			myread = 1;
	if ((his_class = ship_class(foeclass)) == NULL)
		if ((his_class = read_class(foeclass, 1)) == NULL)
			his_class = ship_class("CA");
		else {
			hisread = 1;
			enemynum = randm(MAXFOERACES-1);
		}
	if (!hisread) {
		(void) strncpy(foerace, aliens[enemynum].race_name,
		    sizeof foerace);
		(void) strncpy(foestype,
		    aliens[enemynum].ship_types[his_class->class_num],
		    sizeof foestype);
		(void) strncpy(empire, aliens[enemynum].empire_name,
		    sizeof empire);
	}
	while (foename[0] == '\0')
		(void) strncpy(foename,
		    aliens[enemynum].captains[randm(MAXECAPS) - 1],
		    sizeof foename);
	foerace[sizeof foerace - 1] = '\0';
	foestype[sizeof foestype - 1] = '\0';
	empire[sizeof empire - 1] = '\0';
	foename[sizeof foename - 1] = '\0';
	/*
	 * Randomize the enemy ships 
	 */
	for (loop = 0; loop < 20; loop++) {
		swap1 = randm(MAXESHIPS) - 1;
		swap2 = randm(MAXESHIPS) - 1;
		tmp = aliens[enemynum].ship_names[swap1];
		aliens[enemynum].ship_names[swap1] = aliens[enemynum].ship_names[swap2];
		aliens[enemynum].ship_names[swap2] = tmp;
	}
	/*
	 * Everybody is centered on the Federation ship
	 * (for now, anyways)
	 */
	for (i=0; i<=shipnum; i++) {
		lp = newitem(I_SHIP);
		lp->data.sp = MKNODE(struct ship, *, 1);
		sp = shiplist[i] = lp->data.sp;
		if (sp == (struct ship *)NULL) {
			fprintf(stderr, "init_ships: malloc failed\n");
			exit(2);
		}
		if (i)
			(void) strncpy(sp->name,
			    aliens[enemynum].ship_names[i-1],
			    sizeof sp->name);
		(void) strncpy(sp->class, his_class->abbr,
		    sizeof sp->class);
		sp->warp = sp->newwarp = 1.0;
		sp->course = sp->newcourse = (float)randm(360);
		sp->eff = his_class->e_eff;
		sp->regen = his_class->regen;
		sp->energy = his_class->energy;
		sp->pods = his_class->pods;
		sp->id = i;
		sp->p_spread = INIT_P_SPREAD;
		sp->num_phasers = his_class->num_phaser;
		sp->num_tubes = his_class->num_torp;
		sp->max_speed = his_class->e_warpmax;
		sp->orig_max = his_class->e_warpmax;
		sp->deg_turn = his_class->turn_rate;
		sp->ph_damage = his_class->ph_shield;
		sp->tu_damage = his_class->tp_shield;
		sp->p_blind_left = his_class->p_blind_left;
		sp->p_blind_right = his_class->p_blind_right;
		sp->t_blind_left = his_class->t_blind_left;
		sp->t_blind_right = his_class->t_blind_right;
		for (j=0; j<SHIELDS; j++) {
			sp->shields[j].eff = 1.0;
			sp->shields[j].drain = 1.0;
			sp->shields[j].attemp_drain = 1.0;
		}
		for (j=0; j<sp->num_phasers; j++) {
			sp->phasers[j].target = NULL;
			sp->phasers[j].bearing = init_p_turn[sp->num_phasers][j];
			sp->phasers[j].load = INIT_P_LOAD;
			sp->phasers[j].drain = INIT_P_DRAIN;
			sp->phasers[j].status = P_NORMAL;
		}
		for (j=0; j<sp->num_tubes; j++) {
			sp->tubes[j].target = NULL;
			sp->tubes[j].bearing = init_t_turn[sp->num_tubes][j];
			sp->tubes[j].load = INIT_T_LOAD;
			sp->tubes[j].status = T_NORMAL;
		}
		sp->t_lspeed = INIT_T_SPEED;
		sp->t_prox = INIT_T_PROX;
		sp->t_delay = INIT_T_TIME;
		sp->p_percent = INIT_P_PERCENT;
		for (j=0; j<MAXSYSTEMS; j++)	/* Everything is OK */
			sp->status[j] = 0;
		sp->target = NULL;
		sp->relbear = 0.0;
		sp->delay = 10000.;
		range = 4100 + randm(300) - i * 200;
		bear = toradians(randm(360));
		sp->x = range * cos(bear);
		sp->y = range * sin(bear);
		sp->complement = his_class->e_crew;
		sp->strategy = strategies[0];
		if (!strcmp(foerace, "Romulan") || can_cloak)
			sp->cloaking = C_OFF;
		else
			sp->cloaking = C_NONE;
		sp->cloak_energy = his_class->cloaking_energy;
		sp->cloak_delay = CLOAK_DELAY;
		sp->position.x = 0;
		sp->position.y = 0;
		sp->position.warp = 0.0;
		sp->position.range = 0;
		sp->position.bearing = 0.0;
		sp->position.course = 0.0;
		sp->p_firing_delay = his_class->p_firing_delay;
		sp->t_firing_delay = his_class->t_firing_delay;
	}
	/*
	 * federation exceptions
	 */
	sp = shiplist[0];
	(void) strcpy(sp->class, my_class->abbr);
	sp->course = sp->newcourse = 0.0;
	sp->x = sp->y = 0;
	sp->eff = my_class->o_eff;
	sp->regen = my_class->regen;
	sp->energy = my_class->energy;
	sp->pods = my_class->pods;
	sp->complement = my_class->o_crew;
	sp->num_phasers = my_class->num_phaser;
	sp->num_tubes = my_class->num_torp;
	sp->max_speed = my_class->o_warpmax;
	sp->orig_max = my_class->o_warpmax;
	sp->deg_turn = my_class->turn_rate;
	sp->ph_damage = my_class->ph_shield;
	sp->tu_damage = my_class->tp_shield;
	sp->cloaking = C_NONE;
	for (j=0; j<sp->num_phasers; j++) {
		sp->phasers[j].target = NULL;
		sp->phasers[j].bearing = init_p_turn[sp->num_phasers][j];
		sp->phasers[j].load = INIT_P_LOAD;
		sp->phasers[j].drain = INIT_P_DRAIN;
		sp->phasers[j].status = P_NORMAL;
	}
	for (j=0; j<sp->num_tubes; j++) {
		sp->tubes[j].target = NULL;
		sp->tubes[j].bearing = init_t_turn[sp->num_tubes][j];
		sp->tubes[j].load = INIT_T_LOAD;
		sp->tubes[j].status = T_NORMAL;
	}
	sp->p_firing_delay = my_class->p_firing_delay;
	sp->t_firing_delay = my_class->t_firing_delay;
	if (strlen(shipname) == 0) {
		i = randm(MAXFEDS) - 1;
		(void) strcpy(sp->name, feds[i]);
		(void) strcpy(shipname, sp->name);
	} else {
		(void) strcpy(sp->name, shipname);
	}
	for(loop=shipnum + 1; loop < HIGHSLOT; loop++)
		slots[loop] = ' ';
}

struct ship_stat *read_class(str, flag)
char *str;
int flag;
{
	int fd, bytes;
	char path[BUFSIZ];

	sprintf(path, "%s.trek%s", home, str);
	if ((fd = open(path, O_RDONLY, 0)) < 0) {
		printf("Could not find file %s\n", path);
		return(NULL);
	}
	switch (flag) {
	case 0:
		if ((bytes = read(fd, &us, sizeof(us))) != sizeof(us)) {
			puts("Bad format in file");
			return(NULL);
		}
		return(&us);
		break;
	case 1:
		if ((bytes = read(fd, &them, sizeof(them)))
		    != sizeof(them)) {
			puts("Bad format in file");
			return(NULL);
		}
		if ((bytes = read(fd, foestype, 30)) < 0)
			return(NULL);
		if ((bytes = read(fd, foerace, 30)) < 0)
			return(NULL);
		if ((bytes = read(fd, empire, 30)) < 0)
			return(NULL);
		if ((bytes = read(fd, &can_cloak, 1)) < 0)
			return(NULL);
		if ((bytes = read(fd, &e_bpv, sizeof(int))) < 0)
			return(NULL);

		return(&them);
		break;
		
	}
}
SHAR_EOF
chmod +x 'init.c'
fi # end of overwriting check
if test -f 'main.c'
then
	echo shar: will not over-write existing file "'main.c'"
else
cat << \SHAR_EOF > 'main.c'
/*
 * TREK73: main.c
 *
 * Originally written (in HP-2000 BASIC) by
 *	William K. Char, Perry Lee, and Dan Gee
 *
 * Rewritten in C by
 *	Dave Pare (sdcsvax!sdamos!mr-frog)
 * 		  (mr-frog@amos.ling.ucsd.edu)
 *		and
 *	Christopher Williams (ucbvax!ucbmerlin!williams)
 *			     (williams@merlin.berkeley.edu)
 *
 * Corrected, Completed, and Enhanced by
 *	Jeff Okamoto	(ucbvax!okamoto)
 *			(okamoto@cory.berkeley.edu)
 *	Peter Yee	(ucbvax!yee)
 *			(yee@ucbarpa.berkeley.edu)
 *	Matt Dillon	(ucbvax!dillon)
 *			(dillon@berkeley.edu)
 *	Dave Sharnoff	(ucbvax!ucbcory!muir)
 *			(muir@cogsci.berkeley.edu)
 *	Joel Duisman	(ucbvax!duisman)
 *			(duisman@miro.berkeley.edu)
 *	    and
 *	Roger J. Noe    (riccb!rjnoe)
 *			(ihnp4!riccb!rjnoe@berkeley.edu)
 *
 * Main Loop
 *
 * main, alarmtrap, quitgame, buffering
 *
 */

#include "externs.h"
#include <signal.h>
#include <setjmp.h>

static jmp_buf	jumpbuf;


main(argc, argv, envp)
int argc;
char *argv[];
char *envp[];
{
	register char		*env;
	int			alarmtrap();
	int			quitgame();

	if (buffering(stdout) < 0)
		perror("cannot fstat stdout");
	(void) signal(SIGALRM, alarmtrap);
	(void) signal(SIGINT, quitgame);
	srandom(time(0));
	time_delay = 30;
	set_save();
	if (argc > 1)
		if (argv[1][0] != '-') {
			restore(argv[1], envp);	/* Will not return */
			exit(1);
		}
	options = getenv("TREK73OPTS");
	if (options != NULL)
		parse_opts(options);
	get_comlineopts(argc, argv);
	if (restart && savefile[0] != '\0') {
		restore(savefile, envp);	/* Will not return */
		exit(1);
	}
	name_crew();
	init_ships();
	(void) mission();
	(void) alert();
	playit();
}
	/*
	 * Main loop
	 */
playit()
{
	struct cmd		*scancmd();
	int			alarmtrap();
	int			quitgame();
	register struct ship	*sp;
	char			buf1[30];
	struct cmd		*cp;
	int			loop;

	(void) setjmp(jumpbuf);
	sp = shiplist[0];
	if (!(is_dead(sp, S_DEAD))) {
next:
		for (loop = 0; loop < HIGHSHUTUP; loop++)
			shutup[loop] = 0;
		fflush(stdin);
		printf("\n%s: Code [1-%d] ", captain, high_command);
		fflush(stdout);
		(void) alarm((unsigned) time_delay);
		if (gets(buf1) != NULL) {
			(void) alarm(0);
			cp = scancmd(buf1);
			if (cp != NULL) {
				(*cp->routine)(sp);
				if (cp->turns == FREE)
					goto next;
			} else
				printf("\n%s: %s, I am unable to interpret your last utterance.\n", science, title);
		} else
			(void) alarm(0);
	}
	alarmtrap(0);
	/* This point is never reached since alarmtrap() always concludes
	   with a longjmp() back to the setjmp() above the next: label */
	/*NOTREACHED*/
}

alarmtrap(sig)
int sig;
{
	register int i;

	if (sig) {
		puts("\n** TIME **");
		(void) signal(sig, alarmtrap);
		stdin->_cnt = 0;
	}
	for (i = 1; i <= shipnum; i++)
		shiplist[i]->strategy(shiplist[i]);
	if (!(is_dead(shiplist[0], S_DEAD)))
		printf("\n");
	(void) move_ships();
	(void) check_targets();
	(void) misc_timers();
	(void) disposition();
	longjmp(jumpbuf, 1);
}


quitgame()
{
	char answer[20];
	unsigned timeleft;

	timeleft = alarm(0);
	(void) signal(SIGINT, SIG_IGN);
	puts("\n\nDo you really wish to stop now?  Answer yes or no:");
	if(gets(answer) == NULL || answer[0] == 'y' || answer[0] == 'Y')
		exit(0);
	(void) signal(SIGINT, quitgame);
	if(timeleft)
		(void) alarm((unsigned)timeleft);
	return;
}


/* buffering: Determine whether or not stream is to be buffered.  If it's a
   character-special device, any buffering in effect will remain.  If it's not
   a character-special device, then stream will be unbuffered.  There are many
   ways to decide what to do here.  One would have been to make it unbuffered
   if and only if !isatty(fileno(stream)).  This is usually implemented as a
   single ioctl() system call which returns true if the ioctl() succeeds,
   false if it fails.  But there are ways it could fail and still be a tty.
   Then there's also examination of stream->_flag.  UNIX is supposed to make
   any stream attached to a terminal line-buffered and all others fully buf-
   fered by default.  But sometimes even when isatty() succeeds, stream->_flag
   indicates _IOFBF, not _IOLBF.  And even if it is determined that the stream
   should be line buffered, setvbuf(3S) doesn't work right (in UNIX 5.2) to
   make it _IOLBF.  So about the only choice is to do a straightforward
   fstat() and ascertain definitely to what the stream is attached.  Then go
   with old reliable setbuf(stream, NULL) to make it _IONBF.  The whole reason
   this is being done is because the user may be using a pipefitting program
   to collect a "transcript" of a session (e.g. tee(1)), or redirecting to a
   regular file and then keeping a tail(1) going forever to actually play the
   game.  This assures that the output will keep pace with the execution with
   no sacrifice in efficiency for normal execution.	[RJN]		*****/

#include <sys/types.h>
#include <sys/stat.h>

int
buffering(stream)
FILE	*stream;
{
	struct stat	st;
	if (fstat(fileno(stream), &st) < 0)
		return -1;
	if ((st.st_mode & S_IFMT) != S_IFCHR)
		setbuf(stream, NULL);
	return 0;
}
SHAR_EOF
chmod +x 'main.c'
fi # end of overwriting check
#	End of shell archive
exit 0

okamoto@ucbvax.BERKELEY.EDU (The New Number Who) (12/15/86)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	misc.c
#	mission.c
#	bpv.c
#	shipyard.c
# This archive created: Mon Dec 15 07:44:24 1986
# By:	Jeff Okamoto ()
export PATH; PATH=/bin:$PATH
if test -f 'misc.c'
then
	echo shar: will not over-write existing file "'misc.c'"
else
cat << \SHAR_EOF > 'misc.c'
/*
 * TREK73: misc.c
 *
 * Miscellaneous Routines
 *
 * help, scancmd, new_slot, return_slot, vowelstr,
 * check_p_damage, check_t_damage, check_p_turn, check_t_turn,
 * ship_class
 *
 */

#include "externs.h"

int help(dummy)
struct ship *dummy;
{
	struct cmd	*cpbegin, *cpmiddle;

	puts("\nTrek73 Commands:");
	puts("Code		Command			Code		Command");
	putchar('\n');
	cpbegin = &cmds[0];
	cpmiddle = &cmds[(cmdarraysize + 1) >> 1];
	while (cpmiddle->routine != NULL) {
		printf("%3s:  %c %-31s:%3s:  %c %-31s\n",
		    cpbegin->word1, ((cpbegin->turns) ? ' ' : '*'),
		    cpbegin->word2, cpmiddle->word1,
		    ((cpmiddle->turns) ? ' ' : '*'), cpmiddle->word2);
		cpbegin++;
		cpmiddle++;
	}
	if (cmdarraysize & 1)
		printf("%3s:  %c %-31s", cpbegin->word1,
		    ((cpbegin->turns) ? ' ' : '*'), cpbegin->word2);
	puts("\n\n * does not use a turn");
	dummy = dummy;				/* LINT */
}

struct cmd *scancmd(buf)
char *buf;
{
	static char **argp = NULL;
	struct	cmd *cp;
	int	argnum;
	int	first;

	argnum = parsit(buf, &argp);
	first = strlen(argp[0]);
	if (argnum && first)
		for (cp = &cmds[0]; cp->routine != NULL; cp++)
			if (!strncmp(argp[0], cp->word1, first))
				return (cp);
	return (NULL);
}

/*
 * This routine handles getting unique identifier numbers for
 * all objects.
 */
new_slot()
{
	/*
	 * This is to make it appear that in a 2-ship duel, for
	 * instance, the first object to appear will be numbered
	 * as 3.
	 */
	int i = shipnum + 2;

	while ((slots[i] == 'X') && (i <= HIGHSLOT))
		i++;
	if (i > HIGHSLOT) {
		puts("The game will terminate now due to an inability to handle the number of");
		puts("objects in space (i.e. vessels, torpedoes, probes, etc).  Sorry!");
		exit(-1);
	}
	slots[i] = 'X';
	return i;
}

/* 
 * This routine handles returning identifiers
 */
return_slot(i)
int i;
{
	if (slots[i] != 'X')
		printf("FATAL ERROR - Slot already empty!");
	slots[i] = ' ';
}


char *vowelstr(str)
char *str;
{
	switch(*str) {
		case 'a': case 'A':
		case 'e': case 'E':
		case 'i': case 'I':
		case 'o': case 'O':
		case 'u': case 'U':
			return "n";
		default:
			return "";
	}
}


/*
 * This routine takes an array generated from commands 1, 3, and 5
 * to print out a list of those phasers damaged and unable to
 * either fire, lock, or turn.
 */
check_p_damage(array, sp, string)
int array[];
struct ship *sp;
char *string;
{
	int i, j;

	j = 0;
	for (i=0; i<sp->num_phasers; i++) {
		if (array[i] && (sp->phasers[i].status & P_DAMAGED)) {
			if (!j)
				printf("Computer: Phaser(s) %d", i+1);
			else
				printf(", %d", i+1);
			j++;
		}
	}
	if (j > 1)
		printf(" are damaged and unable to %s.\n", string);
	else if (j == 1)
		printf(" is damaged and unable to %s.\n", string);
}

/*
 * This routine takes an array generated from commands 2, 4, and 6
 * to print out a list of those tubes damaged and unable to either
 * fire, lock, or turn.
 */
check_t_damage(array, sp, string)
int array[];
struct ship *sp;
char *string;
{
	int i, j;

	j = 0;
	for (i=0; i<sp->num_tubes; i++) {
		if (array[i] && (sp->tubes[i].status & P_DAMAGED)) {
			if (!j)
				printf("Computer: Tube(s) %d", i+1);
			else
				printf(", %d", i+1);
			j++;
		}
	}
	if (j > 1)
		printf(" are damaged and unable to %s.\n", string);
	else if (j == 1)
		printf(" is damaged and unable to %s.\n", string);
}

/*
 * This routine checks to see if a phaser is pointing into our
 * blind side
 */
check_p_turn(array, sp, flag)
int array[];
struct ship *sp;
int flag;			/* If 1, came from fire_phasers */
{
	register int i;
	register int j;
	register float k;
	register float bear;
	struct ship *target;

	j = 0;
	for (i=0; i<sp->num_phasers; i++) {
		if (!array[i])
			continue;
		if (flag && !(sp->phasers[i].status & P_FIRING))
			continue;
		target = sp->phasers[i].target;
		/*
		 * This hack is here since when the phaser is locked,
		 * the bearing points at the target, whereas when
		 * not locked, the bearing is relative to the ship.
		 */
		if (target == NULL) {
			bear = sp->phasers[i].bearing + sp->course;
			k = sp->phasers[i].bearing;
		} else {
			bear = bearing(sp->x, target->x, sp->y, target->y);
			k = bear - sp->course;
		}
		k = rectify(k);

		if (betw(k, sp->p_blind_left, sp->p_blind_right)
		    && !(is_dead(sp, S_ENG))) {
			if (!j)
				printf("Computer: Phaser(s) %d", i + 1);
			else
				printf(", %d", i + 1);
			j++;
		}
	}
	if (j > 1)
		printf(" are pointing into our blind side.\n");
	else if (j == 1)
		printf(" is pointing into our blind side.\n");
}

/*
 * This routine checks to see if a tube is turned into
 * our blind side.
 */
check_t_turn(array, sp, flag)
int array[];
struct ship *sp;
int flag;			/* If 1, came from fire_tubes */
{
	register int i;
	register int j;
	register float k;
	register float bear;
	struct ship *target;

	j = 0;
	for (i=0; i<sp->num_tubes; i++) {
		if (!array[i])
			continue;
		if (flag && !(sp->tubes[i].status & T_FIRING))
			continue;
		target = sp->tubes[i].target;
		/*
		 * This hack is here since when the tube is locked,
		 * the bearing points at the target, whereas when
		 * not locked, the bearing is relative to the ship.
		 */
		if (target == NULL) {
			bear = sp->tubes[i].bearing + sp->course;
			k = sp->tubes[i].bearing;
		} else {
			bear = bearing(sp->x, target->x, sp->y, target->y);
			k = bear - sp->course;
		}
		k = rectify(k);
		if (betw(k, sp->t_blind_left, sp->t_blind_right) && !(is_dead(sp, S_ENG))) {
			if (!j)
				printf("Computer: Tubes(s) %d", i + 1);
			else
				printf(", %d", i + 1);
			j++;
		}
	}
	if (j > 1)
		printf(" are pointing into our blind side.\n");
	else if (j == 1)
		printf(" is pointing into our blind side.\n");
}

struct ship_stat *ship_class(s)
char *s;
{
	int i;

	for (i = 0; i< MAXSHIPCLASS; i++)
		if (!strcmp(stats[i].abbr, s)) {
			return(&stats[i]);
		}
	return(NULL);
}
SHAR_EOF
chmod +x 'misc.c'
fi # end of overwriting check
if test -f 'mission.c'
then
	echo shar: will not over-write existing file "'mission.c'"
else
cat << \SHAR_EOF > 'mission.c'
/*
 * TREK73: mission.c
 *
 * Mission Assignment Routines
 *
 * mission, alert, missionlog
 */

#ifdef BSD
#include <sys/time.h>
#endif
#ifdef SYSV
#include <time.h>
#endif

#include "externs.h"


mission()
{
	int onef;
	char temp[3];

	if (terse)
		return;
	onef = (shipnum == 1);
	puts("\n\n\nSpace, the final frontier.");
	printf("These are the voyages of the starship %s.\n", shiplist[0]->name);
	puts("Its five year mission: to explore strange new worlds,");
	puts("to seek out new life and new civilizations,");
	puts("to boldly go where no man has gone before!");
	puts("\n                    S T A R    T R E K\n");
	missionlog();
	if (onef)
		strcpy(temp, "a");
	else
		sprintf(temp,"%d", shipnum);
	printf("%s:  %s, I'm picking up %s vessel%s on an interception\n",
	    helmsman, title, temp, plural(shipnum));
	printf("   course with the %s.\n", shiplist[0]->name);
	printf("%s:  Sensors identify %s as ", science, onef ? "it" : "them");
	if (onef)
		printf("a%s ", vowelstr(foerace));
	printf("%s %s%s,\n", foerace, foestype, plural(shipnum));
	printf("   probably under the command of Captain %s.\n", foename);
	printf("%s:  Sound general quarters, Lieutenant!\n", captain);
	printf("%s:  Aye, %s!\n", com,  title);
}

alert()
{
	register int i;

	printf("Computer: The %ss are attacking the %s with the ",
	    foerace, shiplist[0]->name);
	if (shipnum == 1) {
		printf("%s", shiplist[1]->name);
	} else {
		for (i = 1; i <= shipnum; i++) {
			if (i == shipnum)
				printf("and the ");
			printf("%s", shiplist[i]->name);
			if (i == shipnum)
				continue;
			printf(", ");
			if (i == 1 || i == 6)
				printf("\n   ");
		}
	}
	printf(".\n");
}

missionlog()
{
	static char *missiontab[] = {

	/* "The Trouble with Tribbles" */
	"   We are acting in response to a Priority 1 distress call from",
	"space station K7.",

	/* "The Gamesters of Triskelion" */
	"   We are orbiting Gamma 2 to make a routine check of automatic",
	"communications and astrogation stations.",

	/* "Metamorphosis" */
	"   We are on course for Epsilon Canares 3 to treat Commissioner",
	"Headford for Sukaro's disease.",

	/* "Journey to Babel" */
	"   We have been assigned to transport ambassadors to a diplomatic",
	"conference on the planet code named Babel.",

	/* ?? */
	"   Our mission is to investigate a find of tritanium on Beta 7.",
	0,

	/* "Shore Leave" */
	"   We are orbiting Rigel 4 for therapeutic shore leave.",
	0,

	/* "A Piece of the Action" */
	"   We are orbiting Sigma Iota 2 to study the effects of",
	"contamination upon a developing culture.",

	/* "The Immunity Syndrome" */
	"   We have altered course for a resue mission on the Gamma 7A",
	"system.",

	/* "Amok Time" */
	"   We are presently on course for Altair 6 to attend inauguration",
	"cermonies on the planet.",

	/* "Who Mourns for Adonis?" */
	"   We are on a cartographic mission to Pollux 9.",
	0,

	/* "The Changeling" */
	"   We are headed for Malurian in response to a distress call",
	"from that system.",

	/* "Mirror, Mirror" */
	"   We are to negotiate a treaty to mine dilithium crystals from",
	"the Halkans.",

	/* "The Apple" */
	"   We are to investigate strange sensor readings reported by a",
	"scoutship investigating Gamma Triangula 6.",

	/* "The Doomsday Machine" */
	"   We are headed for planets L370 and L374 to investigate the",
	"disappearance of the starship Constellation in that vincinity.",

	/* "The Ultimate Computer" */
	"   We are ordered, with a skeleton crew, to proceed to Space",
	"Station K2 to test Dr. Richard Daystrom's computer M5.",

	/* "Bread and Circuses" */
	"   We have encountered debris from the SS Beagle and are",
	"proceeding to investigate.",

	/* "Patterns of Force" */
	"   We are on course for Ekos to locate John Gill.",
	0,

	/* "The Paradise Syndrome" */
	"   We are to divert an asteroid from destroying an inhabited",
	"planet.",

	/* "And The Children Shall Lead" */
	"   We are responding to a distresss call form the scientific",
	"expedition on Triacus.",

	/* "Is There in Truth No Beauty?" */
	"   We have been assigned to transport the Medusan Ambassador to",
	"to his home planet.",

	/* "Star Trek II -- The Wrath of Khan" */
	"   We are within the Neutral Zone on a mission to rescue the",
	"Kobayashi Maru.",

	};
	long t1;
	struct tm *localtime(), *date;

	t1 = time(0);
	date = localtime(&t1);
	printf("%s:  Captain's log, stardate %02d%02d.%02d\n",
	    captain, date->tm_year, date->tm_mon+1, date->tm_mday);
	t1 = (randm(sizeof missiontab / sizeof (char *)) - 1) & ~01;
	puts(missiontab[t1]);
	if (missiontab[++t1])
		printf("   %s\n", missiontab[t1]);
}
SHAR_EOF
chmod +x 'mission.c'
fi # end of overwriting check
if test -f 'bpv.c'
then
	echo shar: will not over-write existing file "'bpv.c'"
else
cat << \SHAR_EOF > 'bpv.c'
/*
 * TREK73: bpv.c
 *
 * Calculate Basic Point Values for all ships.
 *
 */

#include <stdio.h>
#include "externs.h"

main()
{
	double crew, pods, regen, num_weapons, phaser, torp;
	double bpv;
	double atof();
	int i;
	char buf[20];

	printf("Regeneration multiplier :");
	gets(buf);
	regen = atof(buf);
	printf("Pods divisor            :");
	gets(buf);
	pods = atof(buf);
	printf("Phaser multiplier       :");
	gets(buf);
	phaser = atof(buf);
	printf("Torpedo multiplier      :");
	gets(buf);
	torp = atof(buf);
	printf("Weapons multiplier      :");
	gets(buf);
	num_weapons = atof(buf);
	printf("Crew divisor            :");
	gets(buf);
	crew = atof(buf);

	for(i=0; i<MAXSHIPCLASS; i++) {
		bpv = 0.;
		bpv += stats[i].regen * regen;
		bpv += stats[i].pods / pods;
		bpv += stats[i].ph_shield * phaser;
		bpv += stats[i].tp_shield * torp;
		bpv += (stats[i].num_phaser + stats[i].num_torp) * num_weapons;
		bpv += stats[i].o_crew / crew;
		printf("%s: BPV = %.2f\n", stats[i].abbr, bpv);
	}
}
SHAR_EOF
chmod +x 'bpv.c'
fi # end of overwriting check
if test -f 'shipyard.c'
then
	echo shar: will not over-write existing file "'shipyard.c'"
else
cat << \SHAR_EOF > 'shipyard.c'
/*
 * TREK73: shipyard.c
 *
 * Design your own ship
 *
 */

#include <stdio.h>
#include <strings.h>
#include <fcntl.h>
#include "externs.h"

char buf[20];
char class[3];
char cloak;
double bpv;
struct {
	char description[30];
	char race[30];
	char empire[30];
} stuff;

struct ship_stat design;

main()
{
	double regen, efficiency, atof(), floor(), round();
	int crew, phasers, torps, pods, max_speed, turn, p_div, t_div;
	int done, atoi();

	printf("Class identifier           :");
	gets(class);
	class[2] = '\0';
	printf("Class description          :");
	gets(stuff.description);
	stuff.description[29] = '\0';
	printf("Race name                  :");
	gets(stuff.race);
	stuff.race[29] = '\0';
	printf("Empire name                :");
	gets(stuff.empire);
	stuff.empire[29] = '\0';
	done = 0;
	while (!done) {
		printf("Regeneration               :");
		gets(buf);
		regen = atof(buf);
		if (regen >= 0)
			done = 1;
		else
			printf(">>> Be reasonable.\n");
	}
	done = 0;
	while (!done) {
		printf("Pods                       :");
		gets(buf);
		pods = atof(buf);
		if (pods >= 0)
			done = 1;
		else
			printf(">>> Be reasonable.\n");
	}
	done = 0;
	while (!done) {
		printf("Number of phasers          :");
		gets(buf);
		phasers = atoi(buf);
		if ((phasers >= 0) && (phasers < MAXWEAPONS))
			done = 1;
		else
			if (phasers < 0)
				printf(">>> Be reasonable.\n");
			else
				printf(">>> Can't have more than %d.\n",
				    MAXWEAPONS-1);
	}
	done = 0;
	while (!done) {
		printf("Number of tubes            :");
		gets(buf);
		torps = atoi(buf);
		if ((torps >= 0) && (torps < MAXWEAPONS))
			done = 1;
		else
			if (torps < 0)
				printf(">>> Be reasonable.\n");
			else
				printf(">>> Can't have more than %d.\n",
				    MAXWEAPONS-1);
	}
	done = 0;
	while (!done) {
		printf("Shield divisor for phasers :");
		gets(buf);
		p_div = atof(buf);
		if (p_div > 0)
			done = 1;
		else
			printf(">>> Be reasonable.\n");
	}
	done = 0;
	while (!done) {
		printf("Shield divisor for torps   :");
		gets(buf);
		t_div = atof(buf);
		if (t_div > 0)
			done = 1;
		else
			printf(">>> Be reasonable.\n");
	}
	done = 0;
	while (!done) {
		printf("Crew                       :");
		gets(buf);
		crew = atoi(buf);
		if (crew > 0)
			done = 1;
		else
			printf(">>> Be reasonable.\n");
	}
	printf("Can the ship cloak         ?");
	gets(buf);
	if (buf != NULL && (buf[0] == 'y' || buf[0] == 'Y'))
		cloak = 1;
	else
		cloak = 0;

	bpv = 0.;
	bpv += regen * 12;
	bpv += pods / 2;
	bpv += p_div * 30;
	bpv += t_div * 40;
	bpv += (phasers + torps) * 10;
	bpv += crew / 15;
	printf("%s: BPV = %.2f\n", class, bpv);

	efficiency = round(4 * (0.0034 * bpv - 0.78)) / 4;
	if (efficiency < 0.25)
		efficiency = 0.25;
	turn = 10 - floor(bpv / 100);
	if (turn < 1)
		turn = 1;
	max_speed = (int) round(-0.004 * bpv + 11);
	if (max_speed < 1)
		max_speed = 1;

	printf("Efficiency = %.2f\n", efficiency);
	printf("Turn = %d\n", turn);
	printf("Max speed = %d\n", max_speed);

	strcpy(design.abbr, class);
	design.num_phaser = phasers;
	design.num_torp = torps;
	design.o_warpmax = max_speed;
	design.e_warpmax = max_speed + 2;
	design.o_eff = efficiency;
	design.e_eff = efficiency;
	design.regen = regen;
	/* XXXX */
	design.energy = pods * 3 / 4;
	design.pods = pods;
	design.o_crew = crew;
	design.e_crew = crew * 5 / 4;
	design.ph_shield = p_div;
	design.tp_shield = t_div;
	design.turn_rate = turn;
	design.cloaking_energy = 4;
	/* XXXX */
	design.t_blind_left = 135;
	design.t_blind_right = 225;
	design.p_blind_left = 125;
	design.p_blind_right = 235;
	design.p_firing_delay = 4;
	design.t_firing_delay = 4;

	save_design();
}

double round(x)
double x;
{
	return( floor(x + 0.5));
}

save_design()
{
	int fd, bytes;
	char path[BUFSIZ];
	char *home, *getenv();

	if ((home = getenv("HOME")) != NULL)
		strcpy(path, home);
	else
		strcpy(path, ".");
	
	strcat(path, "/.trek");
	strcat(path, design.abbr);
	printf("Saving to file %s\n", path);
	
	if ((fd = open(path, O_WRONLY|O_CREAT, 0644)) < 0) {
		perror("open");
		exit(1);
	}
	bytes = write(fd, (char *)&design, sizeof(struct ship_stat));
	if (bytes != sizeof(struct ship_stat)) {
		fprintf(stderr, "Wrote only %d, not %d bytes\n", bytes,
		    sizeof(struct ship_stat));
		unlink(path);
		exit(1);
	}
	bytes = write(fd, &stuff, sizeof(stuff));
	bytes = write(fd, &cloak, 1);
	bytes = write(fd, (char *)&bpv, sizeof(int));
	close(fd);
}
SHAR_EOF
chmod +x 'shipyard.c'
fi # end of overwriting check
#	End of shell archive
exit 0