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.