[comp.sources.x] v10i021: xtrek, Part10/11

ddickey@aspen.cray.com (Dan A. Dickey) (10/24/90)

Submitted-by: ddickey@aspen.cray.com (Dan A. Dickey)
Posting-number: Volume 10, Issue 21
Archive-name: xtrek/part10

#! /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
# If this archive is complete, you will see the following message at the end:
#		"End of archive 10 (of 11)."
#
# Contents:
#   subdaemon.c
#
# Wrapped by ddickey@cray.com on Thu Oct 11 11:43:58 1990
#
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f subdaemon.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"subdaemon.c\"
else
echo shar: Extracting \"subdaemon.c\" \(36322 characters\)
sed "s/^X//" >subdaemon.c <<'END_OF_subdaemon.c'
Xstatic char sccsid[] = "@(#)subdaemon.c	3.1";
X#ifndef lint
Xstatic char *rcsid_daemon_c = "$Header: /uraid2/riedl/src/xceltrek/RCS/subdaemon.c,v 1.1 88/04/18 16:10:46 riedl Exp Locker: riedl $";
X#endif	lint
X/* Copyright (c) 1986 	Chris Guthrie */
X
X#include <X11/Xlib.h>
X#include <stdio.h>
X#if !defined(cray)
X#include <sys/types.h>
X#endif
X#include <sys/time.h>
X#include <sys/file.h>
X
X#if defined(hpux) || defined(cray)
X#include <fcntl.h>
X#endif
X
X#include <sys/ioctl.h>
X#include <signal.h>
X#include <setjmp.h>
X#include "defs.h"
X#include "data.h"
Xextern long isin[], icos[];
X#include "planets.h"
X
X#define fuse(X) ((udcounter % (X)) == 0)
X/* Run the game */
X
Xdouble sqrt();
Xdouble pow();
Xdouble hypot();
X
Xstatic int	pldebug = 0;
Xstatic int	plfd;
Xextern int	debug;
X
X/*
X * initialize - allocate memory and initialize subdaemon
X */
Xinitialize()
X{
X    register int i;
X    int move();
X    int reaper();
X
X    udcounter = 0;
X    bzero(players, sizeof (struct player) * MAXPLAYER);
X    bzero(ships, sizeof (struct ship) * MAXPLAYER);
X    for (i = 0; i < MAXPLAYER; i++) {
X	players[i].p_status = PFREE;
X	players[i].p_warncount = 0;
X	ships[i].s_no = i;
X    }
X
X    plfd = open(PLFILE, O_RDWR, 0777);
X    if (plfd < 0) {
X	fprintf(stderr, "No planet file.  Restarting galaxy\n");
X	initplanets();
X    }
X    else {
X	if (read(plfd, planets, sizeof(pdata)) != sizeof(pdata)) {
X	    fprintf(stderr, "Planet file wrong size.  Restarting galaxy\n");
X	    initplanets();
X	}
X    }
X    for (i = 0; i < MAXPLANETS; i++)
X	planets[i].pl_drawtime = udcounter;
X}
X
X#define PLANET_ORBIT_FAC	3
X
Xinitplanets()
X{
X	register struct planet	*p;
X	register int		i, n;
X	int			orbang, orbvel;
X
X	bcopy(pdata, planets, sizeof (pdata));
X	for (i = 0, p = &planets[0]; i < MAXPLANETS; i++, p++) {
X		p->pl_no = i;
X		p->pl_namelen = strlen(p->pl_name);
X		p->pl_couptime = 0;
X		p->pl_deadtime = 0;
X		p->pl_info = (1 << p->pl_owner) | (1 << GOD);
X		switch (p->pl_type) {
X			case CLASSM:	strcpy(p->pl_tname, "ClassM");	break;
X			case SUN:	strcpy(p->pl_tname, "Sun");	break;
X			case MOON:	strcpy(p->pl_tname, "Moon");	break;
X			case GHOST:	strcpy(p->pl_tname, "Ghost");	break;
X			case DEAD:	strcpy(p->pl_tname, "Dead");	break;
X		}
X	}
X
X	planets[33].pl_x = GWIDTH / 2;	/* Put Murisak in the middle */
X	planets[33].pl_y = GWIDTH / 2;
X
X	planets[33].pl_primary = 33;	/* It orbits itself..stationary */
X	planets[33].pl_orbrad = 0;
X	planets[33].pl_orbang = 0;
X	planets[33].pl_orbvel = 0;
X
X	/* And then the other suns */
X	planets[32].pl_primary = 33;	/* Betelguese */
X	planets[32].pl_orbrad = 36399;
X	planets[32].pl_orbang = 32;
X	planets[32].pl_orbvel = 0;
X
X	planets[31].pl_primary = 33;	/* Kejela */
X	planets[31].pl_orbrad = 36399;
X	planets[31].pl_orbang = 224;
X	planets[31].pl_orbvel = 0;
X
X	planets[30].pl_primary = 33;	/* Sirius */
X	planets[30].pl_orbrad = 36399;
X	planets[30].pl_orbang = 160;
X	planets[30].pl_orbvel = 0;
X
X	planets[29].pl_primary = 33;	/* Sol */
X	planets[29].pl_orbrad = 36399;
X	planets[29].pl_orbang = 96;
X	planets[29].pl_orbvel = 0;
X
X	planets[35].pl_primary = 33;	/* Ghost 1 */
X	planets[35].pl_orbrad = 39708;
X	planets[35].pl_orbang = 0;
X	planets[35].pl_orbvel = 0;
X
X	planets[36].pl_primary = 33;	/* Ghost 2 */
X	planets[36].pl_orbrad = 39708;
X	planets[36].pl_orbang = 64;
X	planets[36].pl_orbvel = 0;
X
X	planets[37].pl_primary = 33;	/* Ghost 3 */
X	planets[37].pl_orbrad = 39708;
X	planets[37].pl_orbang = 128;
X	planets[37].pl_orbvel = 0;
X
X	planets[38].pl_primary = 33;	/* Ghost 4 */
X	planets[38].pl_orbrad = 39708;
X	planets[38].pl_orbang = 192;
X	planets[38].pl_orbvel = 0;
X
X	/* Murisak's planets */
X	planets[12].pl_primary = 33;	/* Janus */
X	planets[12].pl_orbrad = 8603;
X	planets[15].pl_primary = 33;	/* Seritil */
X	planets[15].pl_orbrad = 8603;
X	planets[13].pl_primary = 33;	/* Elas */
X	planets[13].pl_orbrad = 8603;
X	planets[14].pl_primary = 33;	/* Sherman */
X	planets[14].pl_orbrad = 8603;
X	planets[16].pl_primary = 33;	/* Cheron */
X	planets[16].pl_orbrad = 8603;
X
X	/* Sol's planets */
X	planets[0].pl_primary = 29;	/* Earth */
X	planets[0].pl_orbrad = 8603;
X	planets[7].pl_primary = 29;	/* Telos */
X	planets[7].pl_orbrad = 8603;
X	planets[10].pl_primary = 29;	/* Omega */
X	planets[10].pl_orbrad = 8603;
X
X	/* Sirius's planets */
X	planets[1].pl_primary = 30;	/* Romulus */
X	planets[1].pl_orbrad = 8603;
X	planets[4].pl_primary = 30;	/* Remus */
X	planets[4].pl_orbrad = 8603;
X	planets[11].pl_primary = 30;	/* Rho */
X	planets[11].pl_orbrad = 8603;
X
X	/* Kejela's planets */
X	planets[2].pl_primary = 31;	/* Klingus */
X	planets[2].pl_orbrad = 8603;
X	planets[5].pl_primary = 31;	/* Leudus */
X	planets[5].pl_orbrad = 8603;
X	planets[8].pl_primary = 31;	/* Tarsus */
X	planets[8].pl_orbrad = 8603;
X
X	/* Betelgeuse's planets */
X	planets[3].pl_primary = 32;	/* Orion */
X	planets[3].pl_orbrad = 8603;
X	planets[6].pl_primary = 32;	/* Oberon */
X	planets[6].pl_orbrad = 8603;
X	planets[9].pl_primary = 32;	/* Umbriel */
X	planets[9].pl_orbrad = 8603;
X
X	/* Side systems */
X	planets[20].pl_primary = 35;	/* Xidex */
X	planets[20].pl_orbrad = 3805;
X	planets[24].pl_primary = 35;	/* RigelB */
X	planets[24].pl_orbrad = 3805;
X	planets[19].pl_primary = 36;	/* Venar */
X	planets[19].pl_orbrad = 3805;
X	planets[23].pl_primary = 36;	/* Dyneb */
X	planets[23].pl_orbrad = 3805;
X	planets[18].pl_primary = 37;	/* Sarac */
X	planets[18].pl_orbrad = 3805;
X	planets[22].pl_primary = 37;	/* Eminiar */
X	planets[22].pl_orbrad = 3805;
X	planets[17].pl_primary = 38;	/* Dakel */
X	planets[17].pl_orbrad = 3805;
X	planets[21].pl_primary = 38;	/* Oldar */
X	planets[21].pl_orbrad = 3805;
X
X	/* Specials */
X	planets[34].pl_primary = 33;	/* Syrinx */
X	planets[34].pl_orbrad = 9265;
X	planets[25].pl_primary = 0;	/* Luna */
X	planets[25].pl_orbrad = 4136;
X	planets[26].pl_primary = 34;	/* Shitface */
X	planets[26].pl_orbrad = 9265;
X	planets[27].pl_primary = 34;	/* Hell */
X	planets[27].pl_orbrad = 6949;
X	planets[28].pl_primary = 34;	/* Jinx */
X	planets[28].pl_orbrad = 8603;
X	planets[39].pl_primary = 33;	/* Spare 1 */
X	planets[39].pl_orbrad = 16545;
X
X	/* Set orbital angles and velocities for planets, and place them. */
X	/* Murisak's planets */
X	orbang = random() % 256;
X	orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X	planets[12].pl_orbang = orbang;	/* Janus */
X	planets[12].pl_orbvel = orbvel;
X	planets[16].pl_orbang = (orbang + 1*(256/5)) % 256;	/* Cheron */
X	planets[16].pl_orbvel = orbvel;
X	planets[14].pl_orbang = (orbang + 2*(256/5)) % 256;	/* Sherman */
X	planets[14].pl_orbvel = orbvel;
X	planets[13].pl_orbang = (orbang + 3*(256/5)) % 256;	/* Elas */
X	planets[13].pl_orbvel = orbvel;
X	planets[15].pl_orbang = (orbang + 4*(256/5)) % 256;	/* Seritil */
X	planets[15].pl_orbvel = orbvel;
X
X	/* Sol's planets */
X	orbang = random() % 256;
X	orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X	planets[0].pl_orbang = orbang;	/* Earth */
X	planets[0].pl_orbvel = orbvel;
X	planets[7].pl_orbang = (orbang + 2*(256/3)) % 256;	/* Telos */
X	planets[7].pl_orbvel = orbvel;
X	planets[10].pl_orbang = (orbang + 1*(256/3)) % 256;	/* Omega */
X	planets[10].pl_orbvel = orbvel;
X	planets[25].pl_orbang = random() % 256;	/* Luna */
X	planets[25].pl_orbvel = 12 * orbvel;
X
X	/* Sirius's planets */
X	orbang = random() % 256;
X	orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X	planets[1].pl_orbang = orbang;	/* Romulus */
X	planets[1].pl_orbvel = orbvel;
X	planets[4].pl_orbang = (orbang + 2*(256/3)) % 256;	/* Remus */
X	planets[4].pl_orbvel = orbvel;
X	planets[11].pl_orbang = (orbang + 1*(256/3)) % 256;	/* Rho */
X	planets[11].pl_orbvel = orbvel;
X
X	/* Kejela's planets */
X	orbang = random() % 256;
X	orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X	planets[2].pl_orbang = orbang;	/* Klingus */
X	planets[2].pl_orbvel = orbvel;
X	planets[5].pl_orbang = (orbang + 2*(256/3)) % 256;	/* Leudus */
X	planets[5].pl_orbvel = orbvel;
X	planets[8].pl_orbang = (orbang + 1*(256/3)) % 256;	/* Tarsus */
X	planets[8].pl_orbvel = orbvel;
X
X	/* Betelgeuse's planets */
X	orbang = random() % 256;
X	orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X	planets[3].pl_orbang = orbang;	/* Orion */
X	planets[3].pl_orbvel = orbvel;
X	planets[6].pl_orbang = (orbang + 2*(256/3)) % 256;	/* Oberon */
X	planets[6].pl_orbvel = orbvel;
X	planets[9].pl_orbang = (orbang + 1*(256/3)) % 256;	/* Umbriel */
X	planets[9].pl_orbvel = orbvel;
X
X	/* Side systems */
X	orbang = random() % 256;
X	orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X	planets[20].pl_orbang = orbang;	/* Xidex */
X	planets[20].pl_orbvel = orbvel;
X	planets[24].pl_orbang = (orbang + 1*(256/2)) % 256;	/* RigelB */
X	planets[24].pl_orbvel = orbvel;
X	orbang = random() % 256;
X	orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X	planets[19].pl_orbang = orbang;	/* Venar */
X	planets[19].pl_orbvel = orbvel;
X	planets[23].pl_orbang = (orbang + 1*(256/2)) % 256;	/* Dyneb */
X	planets[23].pl_orbvel = orbvel;
X	orbang = random() % 256;
X	orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X	planets[18].pl_orbang = orbang;	/* Sarac */
X	planets[18].pl_orbvel = orbvel;
X	planets[22].pl_orbang = (orbang + 1*(256/2)) % 256;	/* Eminiar */
X	planets[22].pl_orbvel = orbvel;
X	orbang = random() % 256;
X	orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X	planets[17].pl_orbang = orbang;	/* Dakel */
X	planets[17].pl_orbvel = orbvel;
X	planets[21].pl_orbang = (orbang + 1*(256/2)) % 256;	/* Oldar */
X	planets[21].pl_orbvel = orbvel;
X
X	/* Specials */
X	planets[34].pl_orbvel = 0;	/* Syrinx */
X	orbang = random() % 256;
X	orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X	planets[26].pl_orbang = orbang;	/* Shitface */
X	planets[26].pl_orbvel = orbvel;
X	planets[27].pl_orbang = (orbang + 2*(256/3)) % 256;	/* Hell */
X	planets[27].pl_orbvel = orbvel;
X	planets[28].pl_orbang = (orbang + 1*(256/3)) % 256;	/* Jinx */
X	planets[28].pl_orbvel = orbvel;
X
X	/* Spare planets. */
X	planets[39].pl_orbang = random() % 256;	/* Spare 1 */
X	planets[39].pl_orbvel = ((random() % PLANET_ORBIT_FAC)+1) * ((random() % 2) * 2 - 1);
X
X	/* place the planets in their proper locations... */
X	for (n = 3; n > 0; n--)	/* Do it a few times to get things right */
X	for (i = MAXPLANETS-1, p = &planets[i]; i >= 0; i--, p--) {
X		if (p->pl_primary != i) {
X			p->pl_x = planets[p->pl_primary].pl_x + ((p->pl_orbrad * icos[p->pl_orbang]) >> TRIGSCALE);
X			p->pl_y = planets[p->pl_primary].pl_y + ((p->pl_orbrad * isin[p->pl_orbang]) >> TRIGSCALE);
X		}
X	}
X}
X
Xsave_planets() {
X  if (plfd > 0) {
X    lseek(plfd, 0, 0);
X    write(plfd, planets, sizeof(pdata));
X  }
X}
X
X/* These specify how often special actions will take place in
X   UPDATE units (0.20 seconds, currently.)
X*/
X
X#define PLAYERFUSE	1
X#define TORPFUSE	1
X#define PHASERFUSE	1
X#define TEAMFUSE	3
X#define PLFIGHTFUSE	5
X#define BEAMFUSE	5
X#define PLANETFUSE	61	/* was 301 - too slowww */
X#define REFRESHFUSE	1
X#define ROBOTFUSE	1
X#define	PMOVEFUSE	(1 * UPS)	/* Planets move every 6 seconds */
X#define	SAVEFUSE	(360 * UPS)	/* Save planets every 5 minutes */
X#define	DEBUGFUSE	(10 * UPS)	/* Debug stuff every 10 seconds */
X#define	TRACTORFUSE	(1 * UPS)	/* Tractor beams broken? */
X
Xmove()
X{
X	register int		i;
X	register struct player	*p;
X
X	if (pldebug)
X		checkplanets();
X	if (fuse(PLAYERFUSE)) /* Prepare team counters for update */
X		tcount[FED] = tcount[ROM] = tcount[KLI] = tcount[ORI] = 0;
X
X	for (i = 0, p = &players[0]; i < MAXPLAYER; i++, p++) {
X		if (debug && fuse(DEBUGFUSE) && p->p_status != PFREE) {
X			fprintf(stderr, "pno %d, p_status %d, p_flags 0x%x, s_no %d, s_numpilots %d, p_pick 0x%x\n",
X				p->p_no, p->p_status, p->p_flags,
X				p->p_ship->s_no, p->p_ship->s_numpilots, p->p_pick);
X		}
X		if (p->p_status == PMAP)
X			continue;
X
X		if (fuse(PLAYERFUSE) && (p->p_status != PFREE)) {
X			if (!p->p_copilot)
X				udplayer(p);
X		}
X		if (fuse(TRACTORFUSE) && (p->p_status == PALIVE)) {
X			if (!p->p_copilot && (p->p_ship->s_flags & SFTOWED))
X				tractorcheck(p);
X		}
X		if (pldebug)
X			checkplanets();
X		if (fuse(BEAMFUSE) && (p->p_status == PALIVE)) {
X			if (!p->p_copilot)
X				beam(p);
X		}
X	}
X	if (pldebug)
X		checkplanets();
X
X	/* Per tick things...one time for all players */
X	if (fuse(TORPFUSE)) {
X		udtorps();
X	}
X	if (pldebug)
X		checkplanets();
X	if (fuse(PHASERFUSE)) {
X		udphaser();
X	}
X	if (pldebug)
X		checkplanets();
X	if (fuse(TEAMFUSE)) {
X		teamtimers();
X	}
X	if (pldebug)
X		checkplanets();
X	if (fuse(PLFIGHTFUSE)) {
X		plfight();	/* Planet fire */
X	}
X	if (pldebug)
X		checkplanets();
X	if (fuse(PLANETFUSE)) {
X		udplanets();
X	}
X	if (pldebug)
X		checkplanets();
X	if (fuse(PMOVEFUSE)) {
X		moveplanets();
X	}
X	if (pldebug)
X		checkplanets();
X
X	/* Remaining player things... */
X	for (i = 0, p = &players[0]; i < MAXPLAYER; i++, p++) {
X		if (fuse(ROBOTFUSE) &&
X		    (p->p_status == PALIVE) &&
X		    (p->p_flags & PFROBOT)) {
X			udrobot(p);
X		}
X		if (pldebug)
X			checkplanets();
X		if (fuse(REFRESHFUSE) &&
X		    (p->p_status != PFREE && p->p_status != POUTFIT &&
X		     p->p_status != PSETUP && p->p_status != PMAP) &&
X		    !(p->p_flags & PFROBOT)) {
X			/* Can the player see their window? */
X			if ((p->p_flags & PFNOTSHOWING) == 0)
X				redraw(p);
X		}
X	}
X	if (pldebug)
X		checkplanets();
X	if (fuse(SAVEFUSE))
X		save_planets();
X	if (pldebug)
X		checkplanets();
X}
X
Xcheckplanets() {
X    register int i;
X    register struct planet *l;
X    int x;
X
X	x = 0;
X	for (i = MAXPLANETS-1, l = &planets[i]; i >= 0; i--, l--) {
X		if (i == 26 || i == 27 || i == 28 || i > 33)
X			continue;
X		if (l->pl_flags & PLINVIS)
X			x = 1;
X		if (l->pl_x < 0 || l->pl_x > GWIDTH || l->pl_y < 0 || l->pl_y > GWIDTH)
X			x = 1;
X		if (x == 1)
X			fprintf(stderr, "Planets out of order.\n");
X	}
X}
X
Xmoveplanets()
X{
X    register int i;
X    register struct planet *l;
X    int		orbang, oldx, oldy;
X
X    for (i = MAXPLANETS-1, l = &planets[i]; i >= 0; i--, l--) {
X	if (l->pl_primary != i && l->pl_orbvel) {
X		/* pl_orbvel is angle covered in 1 minute */
X		l->pl_suborbang += l->pl_orbvel;
X		while (abs(l->pl_suborbang) > (60 / (PMOVEFUSE / UPS))) {
X			if (l->pl_suborbang < 0) {
X				l->pl_suborbang += (60 / (PMOVEFUSE / UPS));
X				l->pl_orbang--;
X			} else {
X				l->pl_suborbang -= (60 / (PMOVEFUSE / UPS));
X				l->pl_orbang++;
X			}
X		}
X		l->pl_orbang %= 256;
X		if (l->pl_orbang < 0)
X			l->pl_orbang += 256;
X		oldx = l->pl_x;
X		l->pl_x = planets[l->pl_primary].pl_x + ((l->pl_orbrad * icos[l->pl_orbang]) >> TRIGSCALE);
X		oldy = l->pl_y;
X		l->pl_y = planets[l->pl_primary].pl_y + ((l->pl_orbrad * isin[l->pl_orbang]) >> TRIGSCALE);
X		if (oldx != l->pl_x || oldy != l->pl_y)
X			l->pl_drawtime = udcounter;
X	}
X    }
X}
X
Xudplayer(j)
Xregister struct player *j;
X{
X	auto_features(j);
X      switch (j->p_status) {
X      case PDEAD:
X	if (--j->p_ship->s_explode <= 0 && j->p_ship->s_ntorp <= 0) {
X	  if (!(j->p_flags & PFROBOT)) {
X		XSync(j->display, 1);
X		j->p_status = POUTFIT;
X	  } else {
X		/* NOTE: This is the last thing done to robots. */
X		j->p_status = PFREE;
X		j->p_warncount = 0;
X	  }
X	  j->p_redrawall = 1;
X	}
X	break;
X      case PALIVE:
X	j->p_ship->s_updates++;
X	if (j->p_ship->s_status == EXPLODE) {
X		j->p_ship->s_flags &= ~(SFCLOAK|SFDCLOAK);
X		if (j->p_ship->s_explode == PEXPTIME)
X		  blowup(j);		/* damage everyone else around */
X		if (--j->p_ship->s_explode <= 0) {
X			death(j);
X		}
X	} else {
X		/* Only count pilots...to get total number of ships. */
X		if (j->p_ship->s_no == j->p_no)
X			tcount[j->p_ship->s_team]++;
X
X		/* cool weapons */
X		cool_weapons(j);
X
X		/* cool engine */
X		cool_engines(j);
X
X		/* Add fuel */
X		add_fuel(j);
X
X		/* repair shields */
X		repair_shields(j);
X
X		/* repair damage */
X		repair_damage(j);
X
X		/* Charge for cloaking */
X		cloak_charge(j);
X
X		/* Set status of cloaking device depending on damage */
X		check_dcloak(j);
X
X		/* Move Player in orbit */
X		player_orbit(j);
X
X		/* Move player through space */
X		space_move(j);
X
X		/* Set player's alert status */
X		adjust_alert(j);
X	}
X	break;
X      }				/* end switch */
X}
X
Xtractorcheck(j)
Xregister struct player *j;
X{
X	register struct ship	*tower;
X
X	if (!j->p_ship->s_speed)	/* No chance... */
X		return;
X
X	if ((random() % 100) < (j->p_ship->s_speed * j->p_ship->s_speed)) {
X		tower = &ships[j->p_ship->s_towed];
X		tower->s_flags &= ~SFTOWING;
X		j->p_ship->s_flags &= ~SFTOWED;
X		warning(j, "Your ship broke free of the tractor beam.");
X	}
X}
X
Xudtorps()
X{
X    register int i;
X    register struct torp *j;
X
X    for (i = 0, j = &torps[i]; i < MAXPLAYER * MAXTORP; i++, j++) {
X	switch (j->t_status) {
X	    case TFREE:
X		continue;
X	    case TMOVE:
X	    case TSTRAIGHT:
X		j->t_x += (j->t_speed * icos[j->t_dir] * WARP1) >> TRIGSCALE;
X		if (universe.flags & WRAPAROUND) {
X			/* jas (Jeff Schmidt)  Wrap around torp in the x direction */
X			if (j->t_x < 0)
X				j->t_x = GWIDTH;
X			else if (j->t_x > GWIDTH)
X				j->t_x = 0;
X		} else {
X			if (j->t_x < 0) {
X			    j->t_x = 0;
X			    explode(j);
X			    break;
X			}
X			else if (j->t_x > GWIDTH) {
X			    j->t_x = GWIDTH;
X			    explode(j);
X			    break;
X			}
X		}
X		j->t_y += (j->t_speed * isin[j->t_dir] * WARP1) >> TRIGSCALE;
X		if (universe.flags & WRAPAROUND) {
X			/* jas (Jeff Schmidt)  Wrap around torp in the y direction */
X			if (j->t_y < 0)
X				j->t_y = GWIDTH;
X			else if (j->t_y > GWIDTH)
X				j->t_y = 0;
X		} else {
X			if (j->t_y < 0) {
X			    j->t_y = 0;
X			    explode(j);
X			    break;
X			}
X			else if (j->t_y > GWIDTH) {
X			    j->t_y = GWIDTH;
X			    explode(j);
X			    break;
X			}
X		}
X
X		/* Make sure that player torps wobble */
X		if (j->t_status == TMOVE)
X		    j->t_dir += (random() % 3) - 1;
X
X		if (near(j) || (j->t_fuse-- <= 0)) {
X 		    explode(j);
X		}
X		break;
X	    case TDET:
X		j->t_x += (j->t_speed * icos[j->t_dir] * WARP1) >> TRIGSCALE;
X		if (j->t_x < 0)
X		    j->t_x += GWIDTH;
X		else if (j->t_x > GWIDTH)
X		    j->t_x -= GWIDTH;
X		j->t_y += (j->t_speed * isin[j->t_dir] * WARP1) >> TRIGSCALE;
X		if (j->t_y < 0)
X		    j->t_y += GWIDTH;
X		else if (j->t_y > GWIDTH)
X		    j->t_y -= GWIDTH;
X		explode(j);
X		break;
X	    case TEXPLODE:
X		if (j->t_fuse-- <= 0) {
X		    j->t_status = TFREE;
X		    players[j->t_owner].p_ship->s_ntorp--;
X		}
X		break;
X	    case TOFF:
X		j->t_status = TFREE;
X		players[j->t_owner].p_ship->s_ntorp--;
X		break;
X	}
X    }
X}
X
X/* See if there is someone close enough to explode for */
Xnear(torp)
Xstruct torp *torp;
X{
X    register int i;
X    int dx, dy;
X    register struct player *j;
X
X    for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
X       if (!(j->p_status == PALIVE))
X	  continue;
X       if (isGod(j))
X		continue;
X       if (torp->t_owner == j->p_ship->s_no)
X	  continue;
X       if ((!(torp->t_war & (1 << j->p_ship->s_team))) &&
X	   (!((1 << torp->t_team) & (j->p_ship->s_swar | j->p_ship->s_hostile))))
X	  continue;
X       dx = torp->t_x - j->p_ship->s_x;
X       dy = torp->t_y - j->p_ship->s_y;
X       if (ABS(dx) > EXPDIST || ABS(dy) > EXPDIST)
X	  continue;
X       if (dx * dx + dy * dy < EXPDIST * EXPDIST)
X	  return 1;
X    }
X    return 0;
X}
X
X    
X
X/* Do damage to all surrounding players */
X
Xexplode(torp)
Xstruct torp *torp;
X{
X    register int i;
X    int dx, dy, dist;
X    int damage;
X    register struct player *j;
X
X    for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
X	if (!(j->p_status == PALIVE))
X	    continue;
X	if (isGod(j))
X		continue;
X	/* We can only explode so many times... */
X	if (j->p_ship->s_status == EXPLODE)
X	    continue;
X	if (torp->t_owner == j->p_ship->s_no)
X	    continue;
X
X	/* If we are at peace with them... torps don't hurt. */
X	if (!(players[torp->t_owner].p_ship->s_hostile & (1 << j->p_ship->s_team))
X	     && !((1 << players[torp->t_owner].p_ship->s_team) & j->p_ship->s_hostile))
X		continue;
X
X	dx = torp->t_x - j->p_ship->s_x;
X	dy = torp->t_y - j->p_ship->s_y;
X	if (ABS(dx) > TDAMDIST || ABS(dy) > TDAMDIST)
X	    continue;
X	dist = dx * dx + dy * dy;
X	if (dist > TDAMDIST * TDAMDIST)
X	    continue;
X	if (dist > EXPDIST * EXPDIST) {
X	    damage = torp->t_damage * (TDAMDIST - sqrt((double) dist)) /
X		(TDAMDIST - EXPDIST);
X	}
X	else {
X	    damage = torp->t_damage;
X	}
X	if (damage > 0) {
X	    /* First, check to see if torp owner has started a war */
X	    if (players[torp->t_owner].p_ship->s_hostile & (1 << j->p_ship->s_team)) {
X		players[torp->t_owner].p_ship->s_swar |= (1 << j->p_ship->s_team);
X	    }
X	    /* NOTE: Peaceful players & torps don't cause damage. See above. */
X	    /* Note that if a player is at peace with the victim, then
X	       the torp has caused damage either accidently, or because
X	       the victim was at war with, or hostile to, the player.
X	       In either case, we don't consider the damage to be
X	       an act of war. */
X
X	    if (j->p_ship->s_flags & SFSHIELD) {
X		j->p_ship->s_shield -= damage;
X		if (j->p_ship->s_shield < 0) {
X		    j->p_ship->s_damage -= j->p_ship->s_shield;
X		    j->p_ship->s_shield = 0;
X		}
X	    }
X	    else {
X		j->p_ship->s_damage += damage;
X	    }
X	    if (j->p_ship->s_damage >= j->p_ship->s_maxdamage) {
X		j->p_ship->s_status = EXPLODE;
X		j->p_ship->s_explode = PEXPTIME;
X		/* no points for killing yourself! */
X		if (torp->t_owner != j->p_ship->s_no) {
X		  /* No kills for practice robots either. */
X		  if ((j->p_flags & PFPRACTICER) == 0) {
X			players[torp->t_owner].p_ship->s_stats.st_kills +=  1.0
X			  + j->p_ship->s_armies * 0.1 + j->p_ship->s_stats.st_kills * 0.1;
X			players[torp->t_owner].p_ship->s_stats.st_armsship +=
X			  j->p_ship->s_armies;
X		        update_weapons(&players[torp->t_owner]);
X		  }
X		}
X		killmess(j, &players[torp->t_owner]);
X		j->p_ship->s_whydead = KTORP;
X		j->p_ship->s_whodead = torp->t_owner;
X	    }
X	}
X    }
X    torp->t_status = TEXPLODE;
X    torp->t_fuse = TEXPTIME;
X}
X
Xudplanets()
X{
X    register int i;
X    register struct planet *l;
X
X    for (i = 0, l = &planets[i]; i < MAXPLANETS; i++, l++) {
X	if (l->pl_armies == 0)
X	    continue;
X	if (l->pl_type == SUN || l->pl_type == MOON || l->pl_type == GHOST)
X		continue;
X#ifdef notdef  /* Looks like old attempt at plague. */
X	if ((random() % 3000) < l->pl_armies)
X	    l->pl_armies -= (random() % l->pl_armies);
X#endif
X	if ((l->pl_armies < 4) && ((random() % (l->pl_type == CLASSM ? 10 : 20)) == 0)) {
X	    l->pl_armies++;
X	    continue;
X	}
X	if ((random() % (l->pl_type == CLASSM ? 10 : 20)) == 0)
X	    l->pl_armies += (random() % 3) + 1;
X	    
X	if (l->pl_armies > (l->pl_type == CLASSM ? 125 : 75)) {
X		if ((random() % 90) == 0) {
X			/* Plague.. */
X			l->pl_armies = (random() % 20) + 5;
X		}
X	}
X    }
X}
X
Xudphaser()
X{
X    register int i;
X    register struct phaser *j;
X    register struct player *victim;
X
X    for (i = 0, j = &phasers[i]; i < MAXPLAYER; i++, j++) {
X	switch (j->ph_status) {
X	    case PHFREE:
X		continue;
X	    case PHMISS:
X		if (j->ph_fuse-- == 1)
X		    j->ph_status = PHFREE;
X		break;
X	    case PHHIT:
X		if (j->ph_fuse-- == PFIRETIME) {
X		    victim = &players[j->ph_target];
X		    if (isGod(victim)) continue;
X		    /* the victim may have been killed by a torp already */
X		    if (victim->p_status != PALIVE) continue;
X		    if (victim->p_ship->s_status == EXPLODE) continue;
X
X		    if (victim->p_ship->s_flags & SFSHIELD) {
X			victim->p_ship->s_shield -= j->ph_damage;
X			if (victim->p_ship->s_shield < 0) {
X			    victim->p_ship->s_damage -= victim->p_ship->s_shield;
X			    victim->p_ship->s_shield = 0;
X			}
X		    }
X		    else {
X			victim->p_ship->s_damage += j->ph_damage;
X		    }
X		    if (victim->p_ship->s_damage >= victim->p_ship->s_maxdamage) {
X			victim->p_ship->s_status = EXPLODE;
X			victim->p_ship->s_explode = PEXPTIME;
X			if ((victim->p_flags & PFPRACTICER) == 0) {
X			  players[i].p_ship->s_stats.st_kills += 1.0
X			    + victim->p_ship->s_armies * 0.1 + victim->p_ship->s_stats.st_kills * 0.1;
X			  players[i].p_ship->s_stats.st_armsship += victim->p_ship->s_armies;
X			  update_weapons(&players[i]);
X			}
X			killmess(victim, &players[i]);
X			victim->p_ship->s_whydead = KPHASER;
X			victim->p_ship->s_whodead = i;
X		    }
X		}
X		if (j->ph_fuse == 0)
X		    j->ph_status = PHFREE;
X		break;
X	}
X    }
X}
X
Xint pl_warning[MAXPLANETS];	/* To keep planets shut up for awhile */
Xint tm_robots[MAXTEAM + 1];	/* To limit the number of robots */
Xint tm_coup[MAXTEAM + 1];	/* To allow a coup */
X
Xteamtimers()
X{
X    register int i;
X    for (i = 0; i <= MAXTEAM; i++) {
X	if (tm_robots[i] > 0)
X	    tm_robots[i]--;
X	if (tm_coup[i] > 0)
X	    tm_coup[i]--;
X    }
X}
X
Xplfight()
X{
X    register int h, i;
X    register struct player *j;
X    register struct planet *l;
X    int dx, dy;
X    int damage;
X    int dist;
X    int rnd;
X    char buf[80];
X    char buf1[80];
X
X    for (h = 0, l = &planets[h]; h < MAXPLANETS; h++, l++) {
X	if (l->pl_flags & PLCOUP) {
X	    l->pl_flags &= ~PLCOUP;
X	    l->pl_owner = pdata[h].pl_owner;
X	    /* Make sure the newly coup'ed planet has some armies. */
X	    if (l->pl_armies <= 0) {
X		l->pl_armies = (random() % 5) + 1;
X	    }
X	}
X	if (pl_warning[h] > 0)
X	    pl_warning[h]--;
X	for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
X	    switch (j->p_status) {
X		case PFREE:
X		case PDEAD:
X		    continue;
X		case PALIVE:
X		    if (j->p_copilot)
X			continue;
X		    /* Do damage by planets */
X			if (l->pl_flags & PLINVIS) {
X				/* Only visible planets do damage... */
X				continue;
X			}
X			dx = ABS(l->pl_x - j->p_ship->s_x);
X			dy = ABS(l->pl_y - j->p_ship->s_y);
X			if (dx < 3 * PFIREDIST && dy < 3 * PFIREDIST && !isGod(j))
X			    l->pl_drawtime = udcounter;
X			if (j->p_ship->s_status == EXPLODE)
X				continue;
X			if (dx > PFIREDIST || dy > PFIREDIST)	/*XXX*/
X			    continue;
X			dist = (int) hypot((double) dx, (double) dy);
X			if (dist > PFIREDIST)
X			    continue;
X			/* If they are close enough, they get information. */
X			if (dist <= ORBDIST)
X			    l->pl_info |= (1 << j->p_ship->s_team);
X		    if (((j->p_ship->s_swar | j->p_ship->s_hostile) & (1 << l->pl_owner)) ||
X			l->pl_owner == SELFRULED || l->pl_type == SUN) {
X			if (l->pl_armies > 0) {
X			    damage = l->pl_armies / 30 + (random() % 4);
X			    if (damage > 8)
X				damage = 8;
X			} else
X			    damage = 0;
X			if (isGod(j))
X				damage = 0;
X			if (damage > 0) {
X			    if (j->p_ship->s_flags & SFSHIELD) {
X				j->p_ship->s_shield -= damage;
X				if (j->p_ship->s_shield < 0) {
X				    j->p_ship->s_damage -= j->p_ship->s_shield;
X				    j->p_ship->s_shield = 0;
X				}
X			    }
X			    else {
X				j->p_ship->s_damage += damage;
X			    }
X			    if (j->p_ship->s_damage >= j->p_ship->s_maxdamage) {
X			    j->p_ship->s_explode = PEXPTIME;
X			    j->p_ship->s_status = EXPLODE;
X			    sprintf(buf, "%s (%c%x) killed by %s (%c)",
X				j->p_name,
X				teamlet[j->p_ship->s_team],
X				j->p_ship->s_no,
X				l->pl_name,
X				teamlet[l->pl_owner]);
X			    pmessage(buf, 0, MALL, "GOD->ALL");
X			    j->p_ship->s_whydead = KPLANET;
X			    j->p_ship->s_whodead = h;
X			    }
X			}
X		    }
X		    /* do bombing */
X		    if ((!(j->p_ship->s_flags & SFORBIT)) || (!(j->p_ship->s_flags & SFBOMB)))
X			continue;
X		    if (j->p_ship->s_planet != l->pl_no)
X			continue;
X		    if (!((j->p_ship->s_swar | j->p_ship->s_hostile) & (1 << l->pl_owner)) &&
X			l->pl_owner != SELFRULED)
X			continue;
X		    if (l->pl_armies < 5)
X			continue;
X
X			/* Warn owning team */
X		    if (pl_warning[h] <= 0) {
X			pl_warning[h] = 50/PLFIGHTFUSE; 
X			sprintf(buf, "We are under attack.  Please send aid");
X			sprintf(buf1, "%-3s->%-3s",
X			    l->pl_name, teamshort[l->pl_owner]);
X			pmessage(buf, l->pl_owner, MTEAM, buf1);
X		    }
X
X		    damage = j->p_ship->s_torpdamage;
X		    damage *= damage;
X		    damage /= 200;
X
X		    rnd = random() % 100;
X		    if (rnd < 50 || damage <= 0) {
X			continue;
X		    }
X		    damage = random() % damage;
X		    if (damage <= 0)
X			continue;
X		    if (damage > l->pl_armies)
X			damage = l->pl_armies;
X		    l->pl_armies -= damage;
X		    j->p_ship->s_stats.st_kills += (0.02 * damage);
X		    j->p_ship->s_stats.st_armsbomb += damage;
X
X		    /* Send in a robot if there are no other defenders 
X			and the planet is in the team's home space */
X		    /* Send in an easy robot if the planet is not in */
X		    /*  the team's home space. */
X		    /* Send in robots until there are the same number */
X		    /* of defenders as attackers. */
X		    /* But don't start them up all at once
X		       (tm_robots is a timer). */
X
X		    /* NOTE: It would be nice to send in an extra robot if */
X		    /* there are only 1 or 2 team planets left.  Later. */
X
X		    if ((tcount[l->pl_owner] < tcount[j->p_ship->s_team]) && 
X			(pdata[h].pl_owner == l->pl_owner &&
X			 l->pl_owner != SELFRULED) &&
X			    tm_robots[l->pl_owner] == 0) {
X				startrobot(l->pl_owner, PFRSTICKY|PFRHARD);
X				tm_robots[l->pl_owner] = (60 + 
X				    (random() % 60)) /
X				    TEAMFUSE;
X		    } else if ((tcount[l->pl_owner] < tcount[j->p_ship->s_team]) && 
X			    l->pl_owner != SELFRULED &&
X			    tm_robots[l->pl_owner] == 0) {
X				startrobot(l->pl_owner, PFRSTICKY|PFPRACTICER);
X				tm_robots[l->pl_owner] = (60 + 
X				    (random() % 60)) /
X				    TEAMFUSE;
X		    }
X
X	    }
X	}
X    }
X}
X
X/* udrobot - Check if any of the robots in the player list deserve
X * their chance to execute this tick.  Note that hard robots 
X * get to recalculate more often.  In order not to kill the game
X * they only recalculate every other call; the other times they just
X * fire an additional torp.
X */
Xudrobot(j)
Xregister struct player *j;
X{
X	if (j->p_flags & PFRVHARD) { /* very hard robots recalculate every turn */
X	    rmove(j);
X	} else if (j->p_flags & PFRHARD) { /* hard robots recalculate more often */
X	    if (udcounter % 4 == j->p_ship->s_no % 4) rmove(j);
X	} else {
X	    if (udcounter % 10 == j->p_ship->s_no % 10) rmove(j);
X	}
X}
X
Xbeam(j)
Xregister struct player *j;
X{
X    register int h, i;
X    register struct planet *l;
X    char buf[132];
X    int		old_owner;
X
X	/* do beaming */
X	if (!(j->p_ship->s_flags & SFORBIT)) {
X		j->p_ship->s_flags &= ~(SFBEAMUP|SFBEAMDOWN);
X		return;
X	}
X
X      for (h = 0, l = &planets[h]; h < MAXPLANETS; h++, l++) {
X	    if (j->p_ship->s_planet != l->pl_no)
X		continue;
X	    if (j->p_ship->s_flags & SFBEAMUP) {
X		if (l->pl_armies < 5)
X		    continue;
X		if (j->p_ship->s_armies == j->p_ship->s_maxarmies)
X		    continue;
X		/* XXX */
X		if (!isGod(j) && j->p_ship->s_armies == floor(j->p_ship->s_stats.st_kills * 2.0))
X		    continue;
X		if (!isGod(j) && j->p_ship->s_team != l->pl_owner)
X		    continue;
X		j->p_ship->s_armies++;
X		l->pl_armies--;
X	    }
X	    if (j->p_ship->s_flags & SFBEAMDOWN) {
X		if (j->p_ship->s_armies == 0)
X		    continue;
X		if (!isGod(j) && j->p_ship->s_team != l->pl_owner) {
X		    j->p_ship->s_armies--;
X		    if (l->pl_armies) {
X			l->pl_armies--;
X			j->p_ship->s_stats.st_kills += 0.02;
X			j->p_ship->s_stats.st_armsbomb++;
X		    }
X		    else { 	/* planet taken over */
X			l->pl_armies++;
X			old_owner = l->pl_owner;
X			l->pl_owner = j->p_ship->s_team;
X			j->p_ship->s_stats.st_planets++;
X			j->p_ship->s_stats.st_kills += 0.25;
X			l->pl_info = (1 << j->p_ship->s_team);
X			l->pl_info |= (1 << GOD);
X			sprintf(buf, "%s taken over by %s (%c%x)",
X			    l->pl_name,
X			    j->p_name,
X			    teamlet[j->p_ship->s_team],
X			    j->p_ship->s_no);
X			pmessage(buf, 0, MALL, "GOD->ALL");
X			/* Don't wait for the fuse */
X			save_planets();
X			/* checkwin also checks & updates for genocides. */
X			checkwin(j, old_owner);
X		    }
X		} else {
X		    j->p_ship->s_armies--;
X		    l->pl_armies++;
X		}
X	    }
X	}
X}
X
Xblowup(sh)
Xstruct player *sh;
X{
X    register int i;
X    int dx, dy, dist;
X    int damage;
X    register struct player *j;
X
X    for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
X	if (j->p_status == PFREE || j->p_status == PDEAD || (j->p_status == PALIVE && j->p_ship->s_status == EXPLODE))
X	    continue;
X	if (sh == j)
X	    continue;
X	if (isGod(j))
X		continue;
X	dx = sh->p_ship->s_x - j->p_ship->s_x;
X	dy = sh->p_ship->s_y - j->p_ship->s_y;
X	if (ABS(dx) > TDAMDIST || ABS(dy) > TDAMDIST)
X	    continue;
X	dist = dx * dx + dy * dy;
X	if (dist > TDAMDIST * TDAMDIST)
X	    continue;
X	if (dist > EXPDIST * EXPDIST) {
X	    damage = j->p_ship->s_maxdamage * (TDAMDIST - sqrt((double) dist)) /
X		(TDAMDIST - EXPDIST);
X	}
X	else {
X	    damage = j->p_ship->s_maxdamage;
X	}
X	if (damage > 0) {
X	    if (j->p_ship->s_flags & SFSHIELD) {
X		j->p_ship->s_shield -= damage;
X		if (j->p_ship->s_shield < 0) {
X		    j->p_ship->s_damage -= j->p_ship->s_shield;
X		    j->p_ship->s_shield = 0;
X		}
X	    }
X	    else {
X		j->p_ship->s_damage += damage;
X	    }
X	    if (j->p_ship->s_damage >= j->p_ship->s_maxdamage) {
X		j->p_ship->s_status = EXPLODE;
X		j->p_ship->s_explode = PEXPTIME;
X		if ((j->p_flags & PFPRACTICER) == 0) {
X		  sh->p_ship->s_stats.st_kills += 
X			1.0 + j->p_ship->s_armies * 0.1 + j->p_ship->s_stats.st_kills * 0.1;
X		  sh->p_ship->s_stats.st_armsship += j->p_ship->s_armies;
X		  /* Don't update_weapons(sh); as sh is blowing up... */
X		}
X		killmess(j, sh);
X		j->p_ship->s_whydead = KSHIP;
X		j->p_ship->s_whodead = sh->p_ship->s_no;
X	    }
X	}
X    }
X}
X
X/* This function is called when a planet has been taken over.
X   It checks all the planets to see if the victory conditions
X   are right.  If so, it blows everyone out of the game and
X   resets the galaxy
X   As a subfunction, it checks for genocides.
X*/
Xcheckwin(winner, old_owner)
Xstruct player *winner;
Xint	old_owner;
X{
X    register int i, h;
X    register struct planet *l;
X    register struct player *j;
X    int team[MAXTEAM + 1];
X    char	buf[256];
X
X    for (i = 0; i < NUMTEAM; i++)
X	team[i] = 0;
X    
X    for (i = 0, l = &planets[i]; i < MAXPLANETS; i++, l++)
X	team[l->pl_owner]++;
X
X    /* First, check for a genocide. */
X    if (team[old_owner] == 0) {
X	/* Yup...just wiped them out. */
X	winner->p_ship->s_stats.st_genocides++;
X	sprintf(buf, "The %s was genocided by %s (%c%x)",
X		teamlong[old_owner], winner->p_name,
X		teamlet[winner->p_ship->s_team], winner->p_ship->s_no);
X	pmessage(buf, 0, MALL, "GOD->ALL");
X    }
X
X    for (i = 0; i < NUMTEAM; i++) {
X	if (team[i] == NUMCONPLANETS) {
X	    /* We have a winning team */
X	    for (h = 0, j = &players[0]; h < MAXPLAYER; h++, j++) {
X		if (j->p_status == PFREE)
X			continue;
X		j->p_ship->s_whydead = KWINNER;
X		j->p_ship->s_whodead = winner->p_ship->s_no;
X		death(j);
X		j->p_pick = ((1<<FED)|(1<<ROM)|(1<<KLI)|(1<<ORI));	/* Allow them to repick any team */
X		j->p_ship->s_team = 0;
X	    }
X	    winner->p_ship->s_stats.st_conqs++;
X	    initplanets();
X	    save_planets();
X	}
X    }
X}
X
Xkillmess(victim, killer)
Xstruct player *victim, *killer;
X{
X    register char *cp;
X    char buf[80];
X
X    buf[0] = '\0';
X    if (victim->p_ship->s_numpilots == 1)
X	sprintf(buf, "%s ", victim->p_name);
X    cp = &buf[strlen(buf)];
X
X    *cp++ = '(';
X    *cp++ = teamlet[victim->p_ship->s_team];
X    if (victim->p_ship->s_no <= 9)
X	    *cp++ = victim->p_ship->s_no + '0';
X    else
X	    *cp++ = victim->p_ship->s_no + 'A' - 10;
X    *cp++ = ')';
X
X    sprintf(cp, " was kill %0.2f for", killer->p_ship->s_stats.st_kills);
X
X    cp = &buf[strlen(buf)];
X    if (killer->p_ship->s_numpilots == 1) {
X	*cp++ = ' ';
X	strcpy(cp, killer->p_name);
X    }
X
X    cp = &buf[strlen(buf)];
X    *cp++ = ' ';
X    *cp++ = '(';
X    *cp++ = teamlet[killer->p_ship->s_team];
X    if (killer->p_ship->s_no <= 9)
X	    *cp++ = killer->p_ship->s_no + '0';
X    else
X	    *cp++ = killer->p_ship->s_no + 'A' - 10;
X    *cp++ = ')';
X    *cp = '\0';
X    pmessage(buf, 0, MALL, "GOD->ALL");
X}
X
Xdumpmessages()
X{
X    register int i;
X    register struct message *j;
X
X    for (i = 0, j = &messages[0]; i < MAXMESSAGE; i++, j++)
X	if (j->m_flags & MVALID)
X	    printf("%d, %s\n", i, j->m_data);
X}
X
Xstartrobot(team, flags)
Xint team;
Xint flags;
X{
X    register struct player	*p;
X    int rpno;
X    extern char *rnames[4];
X    extern int playerchange;
X
X    if ((rpno = findslot()) >= MAXPLAYER) return;
X    p = &players[rpno];
X    p->p_ship = &ships[rpno];
X    p->p_ship->s_numpilots = 1;
X    p->p_ship->s_team = team;
X    playerchange = 1;
X    strncpy(p->p_login, "Robot", strlen("Robot"));
X    p->p_login[strlen("Robot")] = NULL;
X    strncpy(p->p_name, rnames[team], strlen(rnames[team]));
X    p->p_name[strlen(rnames[team])] = NULL;
X    if (flags & PFRHARD)
X	strcat(p->p_name, "-II");
X    else if (flags & PFRVHARD)
X	strcat(p->p_name, "-III");
X    else
X	strcat(p->p_name, "-I");
X    enter(team, "Nowhere", rpno);
X    p->p_status = PALIVE;
X    p->p_flags |= PFROBOT;		/* Mark as a robot */
X    if (p->p_ship->s_flags & SFTOWED) {
X	ships[p->p_ship->s_towed].s_flags &= ~SFTOWING;
X    }
X    tow_off(p);
X    p->p_ship->s_phasercost = 0;
X    p->p_ship->s_torpcost = 0;
X    /* Set robot difficulty */
X    p->p_flags &= ~(PFRHOSTILE|PFRHARD|PFRVHARD);
X    p->p_flags |= flags;
X    if (p->p_flags & PFRHOSTILE)
X	p->p_ship->s_hostile |= (1 << team);
X}
X
END_OF_subdaemon.c
if test 36322 -ne `wc -c <subdaemon.c`; then
    echo shar: \"subdaemon.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 10 \(of 11\).
cp /dev/null ark10isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.