lars@myab.UUCP (lars) (03/13/86)
#--------CUT---------CUT---------CUT---------CUT--------#
#########################################################
# #
# This is a shell archive file. To extract files: #
# #
# 1) Make a directory for the files. #
# 2) Write a file, such as "file.shar", containing #
# this archive file into the directory. #
# 3) Type "sh file.shar". Do not use csh. #
# #
#########################################################
#
#
echo x - main.c
sed 's/^Z//' >main.c <<\STUNKYFLUFF
Z#ifndef lint
Zstatic char rcsid[] = "$Header: main.c,v 2.2 85/08/06 22:26:37 matt Exp $";
Z#endif
Z/*
Z *
Z * search
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original by Greg Ordy 1979
Z * Rewrite by Sam Leffler 1981
Z * Socket code by Dave Pare 1983
Z * Ported & improved
Z * by Matt Crawford 1985
Z *
Z * main game iteration loop
Z *
Z * Copyright (c) 1979
Z */
Z
Z#include <stdio.h>
Z#include <sys/types.h>
Z#include <sys/ioctl.h>
Z#include <errno.h>
Z#include <sys/file.h>
Z#include <time.h>
Z#include <sys/ipc.h>
Z#include <sys/msg.h>
Z
Z#include "defines.h"
Z#include "structs.h"
Z
Zextern int sock;
Zstatic struct message message;
Z
Z/*
Z * Major data bases
Z */
Zt_torps torps[NTORP]; /* torpedoes data base */
Zt_sbase sbase[NBASE]; /* star bases data base */
Zt_planet planet; /* planet data base */
Zt_alien alien[NALIEN]; /* aliens data base */
Zt_burst bursts[NBURST]; /* shrapnel data base */
Zt_player player[NPLAYER]; /* players */
Z
Zint dtabsiz; /* descriptor table size */
Zint pfd; /* playerfile fd */
Zint errfile; /* error log file */
Zint nplayer; /* # of players currently in game */
Zint nobody; /* is anybody playing? */
Z
Zt_player *whoscab; /* identity of current scab */
Zint TDIST; /* max distance a torpedo can go */
Zchar xxi;
Zchar yyi;
Zchar ppx; /* planet x-coord */
Zchar ppy; /* planet y-coord */
Zchar dx;
Zchar dy;
Zlong ptime; /* search playing time counter */
Z
Zint NALIENS = NALIEN;
Zextern int errno;
Z/*
Z * Solar flare stuff
Z */
Zint sfcount; /* solar flare timer */
Zint sfflag; /* solar flare in progress */
Z
Zint gutsflag; /* playing in guts mode */
Z
Zint numbnode;
Zstruct plist *avl;
Zt_player *wholist;
Zchar visual[NPLAYER][NPLAYER];/* group visibility matrix */
Zint tim_inp;
Z
Z
Zmain(argc, argv)
Zint argc;
Zchar *argv[];
Z{
Z int cost;
Z extern t_player *newplayer();
Z extern void apilot(), autopi(), bcast(), bflush(), cput(),
Z dock(), done(), enteritem(), facts(), fnode(),
Z gathermsg(), groupm(), home(), init(), initplayer(),
Z invisible(), joing(), launch(), lookg(), magnif(),
Z makeburst(), makeflare(), makescab(), movealien(),
Z moveburst(), nuke(), orbit(), orbmove(), outgame(),
Z phaser(), pmesg(), prompt(), pstatus(), quitg(),
Z rmsg(), seeall(), seescab(), sethome(), set_delay(),
Z uplst(), xploit();
Z
Z register t_player *p;
Z register t_player *pl;
Z register t_alien *pa;
Z register t_burst *pb;
Z register t_sbase *ps;
Z register t_torps *pt;
Z t_player *np;
Z char x, y;
Z int mf;
Z int gutsvote;
Z char buf[255];
Z char xx, yy, c;
Z int port_num = DEFAULT_IN_PORT;
Z int nfds;
Z int mask;
Z int save_mask;
Z
Z /*
Z * set up data bases
Z */
Z setuid(geteuid());
Z init();
Z if (fork())
Z exit(0);
Z /*
Z * set up sockets: port number doesn't matter
Z * if INET isn't defined
Z */
Z if (!initsocks())
Z exit(1);
Z /*
Z * block indefinitely until the first player enters the game
Z * then start the player loop
Z */
Z nobody = 1;
Z /*
Z * Main loop -- works in a hard run polling the input socket
Z * of each player. Each turn around the loop defines a time
Z * unit in search.
Z */
Z for (;;) {
Z ptime++; /* time marches on ... */
Z if (--sfcount == 0) { /* ring a ding, time for a flare */
Z makeflare();
Z NALIENS = NALIEN-nplayer;
Z }
Z /*
Z * if nobody's playing, wait until someone generates
Z * some sort of request
Z */
Z if ((ptime % 16) == 0) {
Z np = newplayer(nobody);
Z if (np != NULL) {
Z nplayer++;
Z initplayer(np);
Z errlog("new player %s uid %d\n",
Z np->plname, np->uid);
Z for (p = player; p < &player[NPLAYER]; p++)
Z if (p->status.alive == TRUE && p != np)
Z pmesg(p, "From scanners-- NEW PLAYER");
Z if (gutsflag)
Z pmesg(np, "This game is in GUTS mode");
Z }
Z } else
Z set_delay();
Z /*
Z * Command scanning loop...
Z */
Z nobody = 0;
Z gutsvote = !gutsflag;
Z for (p = player; p < &player[NPLAYER]; p++) {
Z if (p->status.alive == FALSE) {
Z nobody++;
Z continue;
Z }
Z gutsvote = gutsflag ? gutsvote || p->status.guts
Z : gutsvote && p->status.guts;
Z if (p->status.ap == TRUE) /* update autopilot */
Z apilot(p);
Z if (p->status.orb == TRUE) /* update orbiting */
Z orbmove(p);
Z x = p->offx;
Z y = p->offy;
Z if (!p->ninput)
Z if (pinput(p) < 0)
Z continue;
Z if (p->ninput <= 0)
Z goto constvel;
Z c = (*p->pinputq++)&0177;
Z p->ninput--;
Z /*
Z * Two letter commands (e.g. launch torpedo) are
Z * marked as a command pending, so that when the
Z * second char comes in it can be processed entirely.
Z */
Z if (p->cmdpend > 0) {
Z switch (p->cmd) {
Z case 'h':
Z home(p, c);
Z break;
Z case '5':
Z case 't':
Z p->status.ap = FALSE;
Z launch((thing *)p, c, PLAYER, x, y,
Z 1, p->curx, p->cury, 0);
Z break;
Z case 'g':
Z groupm(p, c);
Z break;
Z case 'q':
Z quitg(p, c);
Z break;
Z case 'n':
Z nuke(p, c);
Z break;
Z case 'j':
Z joing(p, c);
Z break;
Z case 's':
Z sethome(p, c);
Z break;
Z case 'b':
Z bcast(p, c);
Z break;
Z case 'a':
Z autopi(p, c);
Z break;
Z case 'r':
Z rmsg(p, c);
Z break;
Z case 'm':
Z magnif(p, c);
Z break;
Z case 'Q':
Z if (c == 'P' && geteuid() == OWNERID &&
Z fork() == 0) {
Z execl("/usr/src/local/search/search",
Z "search", 0);
Z }
Z if (c == 'P')
Z pmesg(p, "Starting player search\n");
Z if (c != 'Y' && c != 'y') {
Z p->cmd = p->cmdpend = 0;
Z prompt(p, "");
Z goto constvel;
Z }
Z done(p);
Z break;
Z }
Z goto constvel;
Z }
Z switch (c) {
Z case 'e':
Z if (p->energy != p->preve) {
Z cput(EGYDATA, p, "%d", p->energy);
Z p->preve = p->energy;
Z }
Z break;
Z case 'p':
Z if (p->points != p->prevp) {
Z cput(PTDATA, p, "%d", p->points);
Z p->prevp = p->points;
Z }
Z break;
Z case 'f':
Z facts(p);
Z break;
Z case 'l':
Z lookg(p);
Z break;
Z case 'x':
Z xploit(p);
Z break;
Z case '0':
Z if (p->whocent == 0)
Z break;
Z if (isalien(p->whocent)) {
Z pa = (t_alien *)p->whocent;
Z /*
Z * Register a hit on an alien
Z */
Z pa->hit++; p->maxmaxe++;
Z if (pa->hit > 5) {
Z pa->stats = DEAD;
Z p->maxmaxe++;
Z }
Z pa->cix = -1;
Z pa->ciy = (rand()%3)-1;
Z p->points += 4;
Z message.mtype = p->uid+1;
Z message.text[0] = '\007';
Z message.text[1] = 0;
Z msgsnd(sock, &message, 2+8, 0);
Z }
Z break;
Z case 'i':
Z invisible(p);
Z break;
Z case 'c':
Z cput(TMDATA, p, "%d", (int)ptime);
Z break;
Z case 'o':
Z orbit(p);
Z x = p->offx;
Z y = p->offy;
Z break;
Z case 'z':
Z seescab(p);
Z break;
Z case 'd':
Z dock(p);
Z break;
Z case 'v':
Z cput(VLDATA, p, "%d %d", p->offx, -p->offy);
Z break;
Z case 'G':
Z p->status.guts = TRUE;
Z break;
Z case 'W':
Z p->status.guts = FALSE;
Z break;
Z case '\014': /* ^L */
Z case '@':
Z fnode(p->plstp);
Z initplayer(p);
Z break;
Z case 'Q':
Z prompt(p, "Really quit?");
Z goto savecmd;
Z case 'q':
Z case 'j':
Z prompt(p, "enter group members");
Z goto savecmd;
Z case 'b':
Z case 'g':
Z gathermsg(p);
Z /*FALL THRU*/
Z case 'r':
Z case 'h':
Z case 't':
Z case 'a':
Z case 'm':
Z case 's':
Z case 'n':
Z case '5':
Z savecmd:
Z p->cmdpend++;
Z p->cmd = c;
Z break;
Z default:
Z goto vel;
Z }
Z goto constvel;
Z vel:
Z /*
Z * Velocity changes handled here...
Z */
Z p->status.ap = p->status.orb = FALSE;
Z switch (c) {
Z case NO: y--; break;
Z case NE: x++; y--; break;
Z case EA: x++; break;
Z case SE: x++; y++; break;
Z case SO: y++; break;
Z case SW: x--; y++; break;
Z case WE: x--; break;
Z case NW: x--; y--; break;
Z default: goto constvel;
Z }
Z cost = max(energycost(p->offx,p->offy),
Z energycost(x,y));
Z if (cost > p->energy) {
Z pmesg(p, "Out of energy\n");
Z x = p->offx; y = p->offy;
Z } else {
Z p->offx = x;
Z p->offy = y;
Z p->energy -= cost + 1; /* consvel will add one */
Z cput(VLDATA, p, "%d %d", p->offx, -p->offy);
Z }
Zconstvel:
Z /*
Z * Update energy total for player:
Z * Non accelerating adds one unit/iteration
Z * magnification costs energy proportional to M-factor
Z * invisibility costs INCOST/iteration
Z */
Z p->curx = p->curx+x;
Z p->cury = p->cury+y;
Z p->energy++;
Z if (p->mflg > 1) p->energy -= p->mflg;
Z if (p->status.invis == TRUE)
Z p->energy = p->energy-INCOST;
Z if (p->maxe > p->maxmaxe) p->maxe = p->maxmaxe;
Z if (p->energy > p->maxe) p->energy = p->maxe;
Z if (p->energy < 0) outgame(p);
Z if (p->status.crash == TRUE) {
Z pstatus(p, "Crash into planet--all is lost!!");
Z if (p->points >= 50)
Z p->points -= 50;
Z p->status.killed = TRUE;
Z done(p);
Z }
Z /*
Z * Update energy display only every 16 iterations --
Z * otherwise, it would be constantly updated at
Z * great expense
Z */
Z if (p->energy != p->preve && (ptime&017) == 0) {
Z cput(EGYDATA, p, "%d", p->energy);
Z p->preve = p->energy;
Z }
Z /*
Z * Friction for high speeds.
Z */
Z if ((ptime&017) == 0) {
Z p->offx = friction(p->offx);
Z p->offy = friction(p->offy);
Z cput(VLDATA, p, "%d %d", p->offx, -p->offy);
Z }
Z if (p->points != p->prevp) {
Z cput(PTDATA, p, "%d", p->points);
Z p->prevp = p->points;
Z }
Z }
Z if (nobody < NPLAYER)
Z nobody = 0;
Z if (gutsvote && !gutsflag)
Z seeall("\07Entering GUTS mode-- beware!");
Z else if (gutsflag && !gutsvote)
Z for (p = player; p < &player[NPLAYER]; p++)
Z if (p->status.alive == TRUE)
Z pmesg(p, "Entering WIMP mode");
Z gutsflag = gutsvote;
Z moveburst();
Z /*
Z * Update the state of the aliens...
Z */
Z for (pa = alien; pa < &alien[NALIEN]; pa++) {
Z if (pa->stats == DEAD)
Z continue;
Z if (pa->type == WANDER) {
Z pa->count--;
Z /* time to change direction */
Z if (pa->count == 0) {
Z pa->cix = (rand()%3)-1;
Z pa->ciy = (rand()%3)-1;
Z pa->count = (rand()%50)+30;
Z }
Z }
Z /* shankers "dance" */
Z if (pa->type == SHANK && pa->aname == NAMESH)
Z movealien(pa);
Z else {
Z pa->cx = pa->cx + pa->cix;
Z pa->cy = pa->cy + pa->ciy;
Z }
Z }
Z /*
Z * Update motion of torpedoes.
Z * When looking for hits, try every point of movement.
Z */
Z for (pt = torps; pt < &torps[NTORP]; pt++) {
Z int fromx, fromy;
Z int tdx, tdy, apa;
Z int tdiffx, tdiffy;
Z
Z if (pt->owner == 0)
Z continue;
Z tdx = sign(pt->xinc); tdy = sign(pt->yinc);
Z tdiffx = pt->xinc*sign(tdx);
Z tdiffy = pt->yinc*sign(tdy);
Z pt->torx += pt->xinc;
Z pt->tory += pt->yinc;
Z pt->tcount--;
Z /*
Z * Check for alien hits
Z */
Z for (pa = alien; pa < &alien[NALIEN]; pa++) {
Z int numit;
Z if (pa->stats == DEAD)
Z continue;
Z fromx = pt->torx - pt->xinc;
Z fromy = pt->tory - pt->yinc;
Z apa = tdiffy - tdiffx; numit = 30;
Z do {
Z if (numit-- == 0) {
Z exit(1);
Z break;
Z }
Z if (apa < 0) {
Z fromx += tdx; apa += tdiffy;
Z } else if (apa > 0) {
Z fromy += tdy; apa -= tdiffx;
Z } else {
Z fromy += tdy; fromx += tdx;
Z apa = tdiffy-tdiffx;
Z }
Z if (pa->cx == fromx && pa->cy == fromy) {
Z pa->hit++;
Z if (pa->hit > 5) {
Z makeburst(pa->cx, pa->cy);
Z pa->stats = DEAD;
Z }
Z /* shot by a shanker */
Z if(isalien(pt->owner)) break;
Z pl = (t_player *)pt->owner;
Z /* 6 points for any hit on an alien */
Z pl->points += 6; pl->ahits++;
Z pl->maxmaxe += 1 + (pa->stats == DEAD);
Z /* X-aliens are worth 20 points */
Z if (pa->type == WANDER) pl->points += 20;
Z /*
Z * move off in a random direction
Z * after a hit
Z */
Z pa->cix = (rand()%3)-1;
Z pa->ciy = (rand()%3)-1;
Z if (pa->cix == 0 && pa->ciy == 0)
Z pa->cix = pa->ciy = 1;
Z /*
Z * Hit a shanker -- they fight back
Z */
Z if (pa->type == SHANK) {
Z pa->aname = NAMESH;
Z pa->whotoget = pt->owner;
Z pl->points += 20; pa->count = 0;
Z pmesg(pl, "From a shanker-- bonzai!");
Z }
Z pstatus(pl, "\007Torpedo hit on alien!");
Z pt->owner = 0; break;
Z }
Z } while (fromx != pt->torx && fromy != pt->tory);
Z }
Z if (pt->tcount == 0) pt->owner = 0;
Z }
Z /*
Z * Main screen update loop...
Z */
Z for (p = player; p < &player[NPLAYER]; p++) {
Z if (p->status.alive == FALSE)
Z continue;
Z wholist = p;
Z x = p->curx;
Z y = p->cury;
Z mf = p->mflg;
Z p->whocent = 0;
Z dx = x-ppx;
Z dy = y-ppy;
Z /*
Z * Display any portion of Quartone visible
Z */
Z if (dx > -18 && dx < 18 && dy > -10 && dy < 10) {
Z register int pp;
Z
Z for (pp = 0; pp != 17; pp++) {
Z dx = planet.places[pp][0];
Z dy = planet.places[pp][1];
Z if (!onscreen (dx, dy, x, y))
Z continue;
Z if (dx == x && dy == y)
Z p->status.crash = TRUE;
Z xx = (dx-x)/mf+XWIND;
Z yy = (dy-y)/mf+YWIND;
Z enteritem(xx, yy, NAMEP);
Z }
Z }
Z /*
Z * Shrapnel around?
Z */
Z for (pb = bursts; pb < &bursts[NBURST]; pb++) {
Z if (pb->cbactive == 0)
Z continue;
Z dx = x-pb->cbx;
Z dy = y-pb->cby;
Z if (dx > -21 && dx < 21 && dy > -13 && dy < 13) {
Z register int is;
Z
Z for (is = 0; is != 9; is++) {
Z dx = pb->shrap[is][0];
Z dy = pb->shrap[is][1];
Z if (dx == 0 && dy == 0)
Z continue;
Z if (!onscreen (dx, dy, x, y))
Z continue;
Z /* a piece hit -- mark it */
Z if (dx == x && dy == y)
Z p->status.bur = TRUE;
Z xx = (dx-x)/mf+XWIND;
Z yy = (dy-y)/mf+YWIND;
Z enteritem(xx, yy, '.');
Z }
Z }
Z }
Z /*
Z * Any star bases visible?
Z */
Z for (ps = sbase; ps < &sbase[NBASE]; ps++) {
Z if (!onscreen (ps->xpos, ps->ypos, x, y))
Z continue;
Z if (ps->xpos == x && ps->ypos == y)
Z p->whocent = (thing *)ps;
Z xx = (ps->xpos-x)/mf+XWIND;
Z yy = (ps->ypos-y)/mf+YWIND;
Z enteritem(xx, yy, '*');
Z }
Z /*
Z * Show other players -- take care of groups
Z */
Z for (pl = player; pl < &player[NPLAYER]; pl++) {
Z register int shift;
Z
Z if (pl == p)
Z continue;
Z if (pl->status.alive == FALSE)
Z continue;
Z if (!onscreen (pl->curx, pl->cury, x, y))
Z continue;
Z if (pl->status.invis == TRUE) {
Z if (!visual[pl-player][p-player])
Z continue;
Z shift = 'a'-'A';
Z } else
Z shift = 0;
Z if (pl->curx == x && pl->cury == y) {
Z p->whocent = (thing *)pl;
Z pl->whocent = (thing *)p;
Z }
Z xx = (pl->curx-x)/mf+XWIND;
Z yy = (pl->cury-y)/mf+YWIND;
Z c = (pl-player)+'A'+shift;
Z enteritem(xx, yy, c);
Z }
Z /*
Z * Show visible aliens...
Z */
Z for (pa = alien; pa < &alien[NALIEN]; pa++) {
Z if (pa->stats == DEAD)
Z continue;
Z if (!onscreen (pa->cx, pa->cy, x, y))
Z continue;
Z if (pa->cx == x && pa->cy == y)
Z p->whocent = (thing *)pa;
Z xx = (pa->cx-x)/mf+XWIND;
Z yy = (pa->cy-y)/mf+YWIND;
Z enteritem(xx, yy, pa->aname);
Z if (pa->type == SHANK && (t_player *)(pa->whotoget) == p)
Z pa->onscr = ON;
Z }
Z /*
Z * Track torpedoes...
Z */
Z for (pt = torps; pt < &torps[NTORP]; pt++) {
Z if (pt->owner == 0)
Z continue;
Z if (!onscreen (pt->torx, pt->tory, x, y))
Z continue;
Z if (pt->torx == x && pt->tory == y)
Z p->whocent = (thing *)pt;
Z xx = (pt->torx-x)/mf+XWIND;
Z yy = (pt->tory-y)/mf+YWIND;
Z enteritem(xx, yy, '+');
Z }
Z /*
Z * Update the display -- attempts minimal changes
Z */
Z uplst();
Z if (p->offx != 0)
Z cput(POS1DATA, p, "%d", p->curx);
Z if (p->offy != 0)
Z cput(POS2DATA, p, "%d", -p->cury);
Z if (p->status.bur == TRUE) { /* shrapnel damage */
Z pmesg(p, "From damage control-- Shrapnel!!");
Z cput(INDATA, p, "off");
Z p->status.bur = FALSE;
Z p->status.invis = FALSE;
Z p->energy -= SHRAPCOST;
Z if (p->energy < 0)
Z p->energy = 0;
Z p->maxe -= SHRAPCOST;
Z }
Z /*
Z * Check for damage
Z */
Z if (isalien(p->whocent) && ((t_alien *)p->whocent)->type == WANDER) {
Z /*
Z * X-alien collision
Z */
Z p->maxe = p->maxe-15;
Z if (p->energy > p->maxe)
Z p->energy = p->maxe;
Z pmesg(p, "From engine room-- Collision!!");
Z }
Z /*
Z * Torpedo hit, and not in orbit
Z */
Z if (istorp(p->whocent) &&
Z (gutsflag || p->status.orb == FALSE)) {
Z pt = (t_torps *)p->whocent;
Z /*
Z * If it's a shanker, let it get back to
Z * wandering -- it's done its job
Z */
Z if (isalien(pt->owner)) {
Z phaser((t_alien *)pt->owner, p);
Z pt->owner = 0;
Z continue;
Z }
Z /*
Z * Torpedo hit by a player
Z */
Z pl = (t_player *)pt->owner;
Z if (pl == p) {
Z pt->owner = 0;
Z pmesg(p, "From damage control-- SELF HIT!!!");
Z p->points -= 75;
Z p->maxmaxe--;
Z if (p->points < 0)
Z p->points = 0;
Z continue;
Z }
Z pt->owner = 0;
Z pstatus(pl, "\007Hit on %c", (p-player)+'A');
Z pstatus(p, "\007Torpedo damage suffered!");
Z pl->points += 50; pl->phits++; pl->maxmaxe++;
Z p->maxe -= 50;
Z if (p->energy > p->maxe) p->energy = p->maxe;
Z if (p->maxe <= 0) {
Z int booty = p->points / 5;
Z pmesg(p, "From damage control-- FATAL HIT!");
Z pmesg(pl, "From navigation-- TOTAL DESTRUCTION!");
Z pl->points += 5 + booty;
Z p->points -= booty;
Z pl->maxmaxe++; pl->pkills++;
Z /*
Z * Time for a new scab??
Z */
Z if ((pl->pkills%4) == 0)
Z makescab(pl);
Z makeburst(p->curx, p->cury);
Z p->status.killed = TRUE;
Z done(p);
Z }
Z }
Z }
Z /*
Z * trying to minimize the number of writes to the sockets.
Z */
Z for (p = player; p < &player[NPLAYER]; p++) {
Z if (p->status.alive == TRUE)
Z bflush(p);
Z }
Z }
Z}
Z
Zenergycost(dx, dy)
Zregister dx, dy;
Z{
Z dx <<= 1; dy <<= 1;
Z if (dx<0) dx = -dx;
Z if (dy<0) dy = -dy;
Z
Z if (dx>dy) return dx+dy/2;
Z else return dy+dx/2;
Z}
Z
Zfriction(n)
Z{
Z return n - n/4;
Z}
Z
Zmax(a,b)
Z{
Z return a>b ? a : b;
Z}
Z
Zsign(n)
Zint n;
Z{
Z if (n<0) return -1;
Z else return n ? 1 : 0;
Z}
STUNKYFLUFF
set `sum < main.c`
if test 2482 != $1
then
echo main.c: Error. number of characters is: $1, should be: 2482.
fi
#
#
echo x - planet.c
sed 's/^Z//' >planet.c <<\STUNKYFLUFF
Z#ifndef lint
Zstatic char rcsid[] = "$Header: planet.c,v 1.3 85/07/08 17:22:52 matt Exp $";
Z#endif
Z/*
Z *
Z * search
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original by Greg Ordy 1979
Z * Rewrite by Sam Leffler 1981
Z * Socket code by Dave Pare 1983
Z * Ported & improved
Z * by Matt Crawford 1985
Z *
Z * routines to manipulate orbiting of the planet
Z *
Z * Copyright (c) 1979
Z *
Z * $Log: planet.c,v $
Z * Revision 1.3 85/07/08 17:22:52 matt
Z * prepare for preliminary distribution
Z *
Z * Revision 1.2 85/02/10 19:19:24 matt
Z * Added more realistic orbiting.
Z *
Z */
Z
Z#include "defines.h"
Z#include "structs.h"
Z
Z/* orbit increments, indexed by the 0070 (CW) */
Z/* or 0007 (CCW) bits of an oentry[] element */
Z
Zstatic char omods[8][2] = {
Z { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, /* E, SE, S, SW */
Z {-1, 0}, {-1,-1}, { 0,-1}, { 1,-1} /* W, NW, N, NE */
Z};
Z
Z/* p->ocnt will be set odd for CCW orbits and always incremented by 2 */
Z
Z#define ORB_INCR(N) omods[( (p->ocnt&1) ? (N) : (N)>>3 )&0007]
Z
Z#define CAN_ENTER_HERE 0200
Z#define CAN_ORBIT_HERE 0100
Z
Z#define ORB_DATA(DX,DY) (oentry[22-(DX)-9*(DY)])
Z
Z/* the strange subscript formula above makes */
Z/* the following array correspond to the map */
Z
Zstatic char oentry[45] = { /* orbital entry calculations */
Z 0000, 0202, 0303, 0304, 0304, 0304, 0314, 0224, 0000,
Z 0202, 0373, 0000, 0000, 0000, 0000, 0000, 0315, 0224,
Z 0371, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0335,
Z 0260, 0351, 0000, 0000, 0000, 0000, 0000, 0337, 0246,
Z 0000, 0260, 0350, 0340, 0340, 0340, 0347, 0246, 0000
Z};
Z
Zvoid orbmove(p)
Zregister t_player *p;
Z{
Z extern void pmesg();
Z extern t_planet planet;
Z register char dx, dy, c;
Z
Z if((p->ocnt&06) == 4) {
Z dx = planet.places[8][0] - p->curx;
Z dy = planet.places[8][1] - p->cury;
Z if (dx < -4 || dx > 4 || dy < -2 || dy > 2
Z || !((c = ORB_DATA(dx,dy))&CAN_ORBIT_HERE)) {
Z /* should "never" happen */
Z pmesg(p, "Orbit unstable!\007");
Z p->status.orb = FALSE;
Z return;
Z }
Z p->offx = ORB_INCR(c)[0];
Z p->offy = ORB_INCR(c)[1];
Z } else {
Z p->offx = 0;
Z p->offy = 0;
Z }
Z p->ocnt += 2;
Z}
Z
Zvoid orbit(p)
Zregister t_player *p;
Z{
Z extern void pmesg();
Z extern int rand();
Z extern t_planet planet;
Z register char dx, dy, c;
Z int sense; /* CW or CCW ? */
Z
Z move(STDATAX, STDATAY, p);
Z if (p->offx < -1 || p->offx > 1 || p->offy < -1 || p->offy > 1) {
Z pmesg(p, "Velocity too great!!");
Z return;
Z }
Z dx = planet.places[8][0] - p->curx;
Z dy = planet.places[8][1] - p->cury;
Z if (dx < -4 || dx > 4 || dy < -2 || dy > 2
Z || !((c = ORB_DATA(dx,dy))&CAN_ENTER_HERE)) {
Z pmesg(p, "Too far from planet to orbit!");
Z return;
Z }
Z if ( ! p->status.orb ) {
Z p->status.orb = TRUE;
Z p->ocnt = 0;
Z sense = dx * p->offy - dy * p->offx; /* cross product */
Z if ( sense > 0 || (sense == 0 && rand()&01) )
Z p->ocnt = 1;
Z p->offx = p->offy = 0;
Z if ( !(c&CAN_ORBIT_HERE) ) {
Z /* jump to proper orbit location */
Z p->curx += ORB_INCR(c)[0];
Z p->cury += ORB_INCR(c)[1];
Z }
Z }
Z pmesg(p, "In orbit around: %s", planet.planetname);
Z}
STUNKYFLUFF
set `sum < planet.c`
if test 19515 != $1
then
echo planet.c: Error. number of characters is: $1, should be: 19515.
fi
#
#
echo x - playmap.c
sed 's/^Z//' >playmap.c <<\STUNKYFLUFF
Z#ifndef lint
Zstatic char rcsid[] = "$Header: playmap.c,v 2.2 85/04/10 22:53:20 matt Exp $";
Z#endif
Z/*
Z *
Z * search
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original by Sam Leffler 1981
Z * Socket code by Dave Pare 1983
Z * Ported & improved
Z * by Matt Crawford 1985
Z *
Z * routines to manipulate the player map
Z *
Z * Copyright (c) 1981
Z *
Z */
Z
Z#include "defines.h"
Z#include "structs.h"
Z
Z/*
Z * Screen locations for the players map fields -- if you make
Z * NPLAYER > 16, you'd better change this.
Z */
Zstatic struct statcoords {
Z char s_x;
Z char s_y;
Z} scoord[] = {
Z {0, 20}, {20, 20}, {40, 20}, {60, 20},
Z {0, 21}, {20, 21}, {40, 21}, {60, 21},
Z {0, 22}, {20, 22}, {40, 22}, {60, 22},
Z {0, 23}, {20, 23}, {40, 23}, {60, 23},
Z};
Z
Z/*
Z * Update the status of a player on everyone else's screen.
Z */
Zvoid pldisplay(pl, status)
Zregister t_player *pl;
Zchar *status;
Z{
Z extern void cput();
Z extern t_player player[NPLAYER];
Z register t_player *p;
Z register struct statcoords *pcoord = &scoord[pl-player];
Z
Z for (p = player; p < &player[NPLAYER]; p++) {
Z if (p->status.alive == FALSE || p == pl)
Z continue;
Z if (pl->status.begin == TRUE) {
Z cput(pcoord->s_x, pcoord->s_y, p, "%c[%s]%s ",
Z (pl-player)+'A', status, pl->plname);
Z } else
Z cput(pcoord->s_x+2, pcoord->s_y, p, status);
Z }
Z pl->status.begin = FALSE;
Z}
Z
Z/*
Z * Set up the player map for an entering player
Z */
Zvoid initpdisplay(pl)
Zregister t_player *pl;
Z{
Z extern void cput();
Z extern t_player player[NPLAYER];
Z char what;
Z register t_player *p;
Z register struct statcoords *pcoord;
Z
Z for (p = player; p < &player[NPLAYER]; p++) {
Z if (*p->plname == NULL || p->status.alive == FALSE)
Z continue;
Z pcoord = &scoord[p-player];
Z if (p->status.alive == FALSE) {
Z if (p->status.killed == TRUE)
Z what = 'd';
Z else
Z what = 'q';
Z }
Z else
Z what = 'a';
Z cput(pcoord->s_x, pcoord->s_y, pl, "%c[%c]: %s",
Z (p-player)+'A', what, p->plname);
Z }
Z}
STUNKYFLUFF
set `sum < playmap.c`
if test 18968 != $1
then
echo playmap.c: Error. number of characters is: $1, should be: 18968.
fi
#
#
echo x - tgoto.c
sed 's/^Z//' >tgoto.c <<\STUNKYFLUFF
Z#define CTRL(c) ('c' & 037)
Z
Z#include "defines.h"
Z#include "structs.h"
Zchar *_branchto();
Z
Z/*
Z * Routine to perform parameter substitution.
Z * p->CM is a string containing printf type escapes.
Z * The whole thing uses a stack, much like an HP 35.
Z * The following escapes are defined for substituting row/column:
Z *
Z * %d print pop() as in printf
Z * %[0]2d print pop() like %[0]2d
Z * %[0]3d print pop() like %[0]3d
Z * %c print pop() like %c
Z * %s print pop() like %s
Z * %l pop() a string and push its length.
Z *
Z * %p[1-0] push ith parm
Z * %P[a-z] set variable
Z * %g[a-z] get variable
Z * %'c' char constant c
Z * %{nn} integer constant nn
Z *
Z * %+ %- %* %/ %m arithmetic (%m is mod): push(pop() op pop())
Z * %& %| %^ bit operations: push(pop() op pop())
Z * %= %> %< logical operations: push(pop() op pop())
Z * %! %~ unary operations push(op pop())
Z * %b unary BCD conversion
Z * %d unary Delta Data conversion
Z *
Z * %? expr %t thenpart %e elsepart %;
Z * if-then-else, %e elsepart is optional.
Z * else-if's are possible ala Algol 68:
Z * %? c1 %t %e c2 %t %e c3 %t %e c4 %t %e %;
Z *
Z * all other characters are ``self-inserting''. %% gets % output.
Z */
Z
Z#define push(i) (stack[++top] = (i))
Z#define pop() (stack[top--])
Z
Zchar *
Ztgoto (p, p2, p1)
Z t_player *p;
Z int p2, p1;
Z{
Z static char result[32];
Z static char added[10];
Z int vars[26];
Z int stack[10], top = 0;
Z register char *cp = p->CM;
Z register char *outp = result;
Z register int c;
Z register int op;
Z int sign;
Z int onrow = 0;
Z int leadzero = 0; /* not having leading zero is unimplemented */
Z char *xp;
Z
Z if (cp == 0)
Z return ("OOPS: NULL ARG");
Z added[0] = 0;
Z
Z while (c = *cp++) {
Z if (c != '%') {
Z *outp++ = c;
Z continue;
Z }
Z op = stack[top];
Z if (*cp == '0') {
Z leadzero = 1;
Z cp++;
Z }
Z switch (c = *cp++) {
Z
Z /* PRINTING CASES */
Z case 'd':
Z if (op < 10)
Z goto one;
Z if (op < 100)
Z goto two;
Z /* fall into... */
Z
Z case '3':
Zthree:
Z if (c == '3' && *cp++ != 'd')
Z return ("OOPS: BAD CHAR AFTER %3");
Z *outp++ = (op / 100) | '0';
Z op %= 100;
Z /* fall into... */
Z
Z case '2':
Z if (op >= 100)
Z goto three;
Z if (c == '2' && *cp++ != 'd')
Z return ("OOPS: BAD CHAR AFTER %2");
Ztwo:
Z *outp++ = op / 10 | '0';
Zone:
Z *outp++ = op % 10 | '0';
Z (void) pop();
Z continue;
Z
Z case 'c':
Z /*
Z * Weird things can happen to nulls, EOT's, tabs, and
Z * newlines by the tty driver, arpanet, etc.
Z * So we instead we used to alter the place being
Z * addessed and then move the cursor locally using UP
Z * or RIGHT, before Tore made som changes.
Z */
Z switch (op) {
Z case 0:
Z op = 0200;
Z break;
Z }
Z
Z *outp++ = op;
Z (void) pop();
Z break;
Z
Z case 'l':
Z xp = (char *) pop();
Z push(strlen(xp));
Z break;
Z
Z case 's':
Z xp = (char *) pop();
Z while (*xp)
Z *outp++ = *xp++;
Z break;
Z
Z case '%':
Z *outp++ = c;
Z break;
Z
Z /*
Z * %i: shorthand for increment first two parms.
Z * Useful for terminals that start numbering from
Z * one instead of zero (like ANSI terminals).
Z */
Z case 'i':
Z p1++; p2++;
Z break;
Z
Z /* %pi: push the ith parameter */
Z case 'p':
Z switch (c = *cp++) {
Z case '1': push(p1); break;
Z case '2': push(p2); break;
Z default: return ("OOPS: BAD PARM NUMBER");
Z }
Z onrow = (c == '1');
Z break;
Z
Z /* %Pi: pop from stack into variable i (a-z) */
Z case 'P':
Z vars[*cp++ - 'a'] = pop();
Z break;
Z
Z /* %gi: push variable i (a-z) */
Z case 'g':
Z push(vars[*cp++ - 'a']);
Z break;
Z
Z /* %'c' : character constant */
Z case '\'':
Z push(*cp++);
Z if (*cp++ != '\'')
Z return ("OOPS: MISSING CLOSING QUOTE");
Z break;
Z
Z /* %{nn} : integer constant. */
Z case '{':
Z op = 0; sign = 1;
Z if (*cp == '-') {
Z sign = -1;
Z cp++;
Z } else if (*cp == '+')
Z cp++;
Z while ((c = *cp++) >= '0' && c <= '9') {
Z op = 10*op + c - '0';
Z }
Z if (c != '}')
Z return ("OOPS: MISSING CLOSING BRACE");
Z push(sign * op);
Z break;
Z
Z /* binary operators */
Z case '+': c=pop(); op=pop(); push(op + c); break;
Z case '-': c=pop(); op=pop(); push(op - c); break;
Z case '*': c=pop(); op=pop(); push(op * c); break;
Z case '/': c=pop(); op=pop(); push(op / c); break;
Z case 'm': c=pop(); op=pop(); push(op % c); break; /* %m: mod */
Z case '&': c=pop(); op=pop(); push(op & c); break;
Z case '|': c=pop(); op=pop(); push(op | c); break;
Z case '^': c=pop(); op=pop(); push(op ^ c); break;
Z case '=': c=pop(); op=pop(); push(op = c); break;
Z case '>': c=pop(); op=pop(); push(op > c); break;
Z case '<': c=pop(); op=pop(); push(op < c); break;
Z
Z /* Unary operators. */
Z case '!': stack[top] = !stack[top]; break;
Z case '~': stack[top] = ~stack[top]; break;
Z /* Sorry, no unary minus, because minus is binary. */
Z
Z /*
Z * If-then-else. Implemented by a low level hack of
Z * skipping forward until the match is found, counting
Z * nested if-then-elses.
Z */
Z case '?': /* IF - just a marker */
Z break;
Z
Z case 't': /* THEN - branch if false */
Z if (!pop())
Z cp = _branchto(cp, 'e');
Z break;
Z
Z case 'e': /* ELSE - branch to ENDIF */
Z cp = _branchto(cp, ';');
Z break;
Z
Z case ';': /* ENDIF - just a marker */
Z break;
Z
Z default:
Z return ("OOPS: BAD % SEQUENCE");
Z }
Z }
Z strcpy(outp, added);
Z return (result);
Z}
Z
Z
Zchar *
Z_branchto(cp, to)
Zregister char *cp;
Zchar to;
Z{
Z register int level = 0;
Z register char c;
Z
Z while (c = *cp++) {
Z if (c == '%') {
Z if ((c = *cp++) == to || c == ';') {
Z if (level == 0) {
Z return cp;
Z }
Z }
Z if (c == '?')
Z level++;
Z if (c == ';')
Z level--;
Z }
Z }
Z return ("OOPS: NO MATCHING ENDIF");
Z}
STUNKYFLUFF
set `sum < tgoto.c`
if test 62044 != $1
then
echo tgoto.c: Error. number of characters is: $1, should be: 62044.
fi
#
#
echo x - util.c
sed 's/^Z//' >util.c <<\STUNKYFLUFF
Z#ifndef lint
Zstatic char rcsid[] = "$Header: util.c,v 2.2 85/08/06 22:29:53 matt Exp $";
Z#endif
Z/*
Z *
Z * search
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original by Greg Ordy 1979
Z * Rewrite by Sam Leffler 1981
Z * Socket code by Dave Pare 1983
Z * Ported & improved
Z * by Matt Crawford 1985
Z *
Z * utility routines
Z *
Z * Copyright (c) 1979
Z *
Z * $Log: util.c,v $
Z * Revision 2.2 85/08/06 22:29:53 matt
Z * Change handling of "r", "b", "g", "j", "q" commands to
Z * provide better feedback, using per-player message buffer.
Z *
Z * Revision 2.1 85/04/10 17:32:11 matt
Z * Major de-linting and minor restructuring.
Z *
Z * Revision 1.4 85/02/24 22:52:07 matt
Z * Make the select() polls into real polls by setting the timeouts
Z * to zero. This cuts down on context switches and speeds the game
Z * up IMMENSELY!
Z *
Z * Revision 1.3 85/02/11 12:44:13 matt
Z * added GUTS mode
Z *
Z * Revision 1.2 85/02/09 23:50:55 matt
Z * Eliminated the dependence on the value of the mask after
Z * select() times out. Use the return value to distinguish
Z * a timeout!!
Z *
Z */
Z
Z#include <stdio.h>
Z#include <time.h>
Z#include <sys/types.h>
Z#include <signal.h>
Z#include <sys/ipc.h>
Z#include <sys/msg.h>
Z
Z#include "defines.h"
Z#include "structs.h"
Z
Zstruct message message;
Z
Zvoid pmesg();
Zint sock;
Z
Z/*
Z * Out of energy, out of game...
Z */
Zvoid
Zoutgame(p)
Zregister t_player *p;
Z{
Z extern void pstatus();
Z void done();
Z
Z p->status.alive = FALSE;
Z pstatus(p, "Out of energy, out of game!");
Z p->status.killed = TRUE;
Z done(p);
Z}
Z
Z
Z/*
Z * Cleanup after player leaves...
Z */
Zvoid
Zdone(p)
Zregister t_player *p;
Z{
Z extern void bflush(),
Z cput(),
Z fnode(),
Z pldisplay(),
Z putplayer();
Z extern t_player player[NPLAYER];
Z extern char visual[NPLAYER][NPLAYER];
Z extern t_player *whoscab;
Z extern int dtabsiz, nplayer;
Z register t_player *pl;
Z register int i, j;
Z int delay;
Z char junkbuf[4096];
Z int mask, y;
Z
Z nplayer--;
Z p->status.alive = FALSE;
Z cput(PTDATA, p, "%d", p->points);
Z move(0, 23, p); /* lower left hand corner? */
Z bflush(p);
Z delay = 0;
Z /*
Z * close down the socket:
Z * send an out-of-band message to the player,
Z * stop any more writes to the socket,
Z * read all the muck that's accumulated,
Z * then shut it down for good.
Z */
Z message.mtype = p->uid+1;
Z message.text[0] = '\0';
Z msgsnd(sock, &message, 8+1, 0);
Z j = p-player;
Z for (i=0,pl=player; i<NPLAYER; i++,pl++) {
Z visual[i][j] = visual[j][i] = 0;
Z if (pl->status.alive == FALSE)
Z continue;
Z for (y = 0; y != 3; y++)
Z if (pl->home[y] == (thing *)p)
Z pl->home[y] = NOTHING;
Z }
Z if (whoscab == p)
Z whoscab = NOBODY;
Z (void) putplayer(p);
Z (void) fnode(p->plstp);
Z (void) pldisplay(p, p->status.killed ? "d" : "q");
Z}
Z
Z/*
Z * Time for a solar flare...
Z */
Zvoid makeflare() {
Z extern t_player player[NPLAYER];
Z extern int sfflag,
Z gutsflag,
Z sfcount,
Z nplayer,
Z TDIST;
Z extern int rand();
Z extern void seeall();
Z
Z if (sfflag == ON) {
Z sfcount = 500+(rand()%128);
Z sfflag = OFF;
Z TDIST = TSIZE-(2*nplayer);
Z return;
Z }
Z sfcount = 30+(rand()%100);
Z sfflag = ON;
Z if (!gutsflag)
Z seeall("\07From radar-- Solar flare starting!!!");
Z}
Z
Z/*
Z * Autopilot update routine
Z */
Zvoid apilot(p)
Zregister t_player *p;
Z{
Z extern void cput();
Z register char dx, dy;
Z int xplus, yplus, cost;
Z
Z dx = *(p->apx) - p->curx;
Z dy = *(p->apy) - p->cury;
Z if (dx == 0 && dy == 0) {
Z cput(VLDATAX, VLDATAY, p, "%d %d\07", 0, 0);
Z p->status.ap = FALSE;
Z }
Z xplus = dx < 3 && dx > -3 ? 1 : 2;
Z yplus = dy < 3 && dy > -3 ? 1 : 2;
Z dx = dx < 0 ? -xplus : dx > 0 ? xplus : 0;
Z dy = dy < 0 ? -yplus : dy > 0 ? yplus : 0;
Z if (abs(dx - p->offx) > 1) dx = p->offx + sign(dx - p->offx);
Z if (abs(dy - p->offy) > 1) dy = p->offy + sign(dy - p->offy);
Z cost = 0;
Z if (dx != p->offx && dy != p->offy) {
Z cost = energycost(dx, dy);
Z if (cost > p->energy) {
Z pmesg(p, "Low on energy\n"); return;
Z }
Z } else cost = 0;
Z p->energy = p->energy+1-cost;
Z p->offx = dx; p->offy = dy;
Z if (cost) cput(VLDATA, p, "%d %d", p->offx, p->offy);
Z}
Z
Z/*
Z * errlog logs the errors found by other routines.
Z * this is needed since the main program closes stdout
Z * so we need to print out what's wrong into a file.
Z *
Z * Of course, if errlog isn't opened, then we'll never see
Z * anything bad (except a core-dump of searchd).
Z */
Z
Zerrlog(msg, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9)
Zchar *msg;
Z{
Z extern int errfile;
Z extern long lseek();
Z char buff[200];
Z
Z if (errfile < 0) {
Z signal(SIGQUIT, SIG_DFL);
Z kill(getpid(), SIGQUIT);
Z }
Z sprintf(buff, msg, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9);
Z (void)lseek(errfile, 0L, 2);
Z write(errfile, buff, strlen(buff));
Z}
Z
Z/*
Z * seeall makes everyone visible and sends them all the argument
Z * string as a message. This is used by makeflare and when
Z * entering guts mode.
Z */
Zvoid seeall(msg)
Zchar *msg;
Z{
Z extern t_player player[NPLAYER];
Z extern void cput();
Z register t_player *p;
Z
Z for (p = player; p < &player[NPLAYER]; p++) {
Z if (p->status.alive == FALSE)
Z continue;
Z cput(INDATA, p, "off");
Z pmesg(p, msg);
Z p->status.invis = FALSE;
Z }
Z}
Z
Zabs(x)
Z{
Z return x<0 ? -x : x;
Z}
STUNKYFLUFF
set `sum < util.c`
if test 62810 != $1
then
echo util.c: Error. number of characters is: $1, should be: 62810.
fi
#
#
echo x - defines.h
sed 's/^Z//' >defines.h <<\STUNKYFLUFF
Z/*
Z *
Z * search
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original by Greg Ordy 1979
Z * Rewrite by Sam Leffler 1981
Z * Socket code by Dave Pare 1983
Z * Ported & improved
Z * by Matt Crawford 1985
Z *
Z * defines and macros used by search code.
Z *
Z * Copyright (c) 1979
Z *
Z * $Header: defines.h,v 2.2 85/08/06 22:25:30 matt Exp $
Z * $Log: defines.h,v $
Z * Revision 2.2 85/08/06 22:25:30 matt
Z * Change definition of score and error log files for flexibility.
Z *
Z * Revision 2.1 85/04/10 17:30:57 matt
Z * Major de-linting and minor restructuring.
Z *
Z * Revision 1.2 85/02/11 14:59:08 matt
Z * raised NPLAYER to 15
Z */
Z
Z#define DEFAULT_IN_PORT 525 /* default internet port number */
Z
Z/*
Z * Configuration definitions
Z */
Z#define NPLAYER 16 /* # players supported */
Z#define MAXMAG '3' /* upper bound on magnification */
Z#define NBURST 2 /* # concurrent visible shrapnel */
Z#define NALIEN 20 /* # of aliens in game */
Z#define NBASE 3 /* # of starbases */
Z#define NSHANK 12 /* # of shanker aliens */
Z#define NWAND 4 /* # of X-aliens */
Z#define NTORP 26 /* # of available torpedoes (recycled) */
Z#define ITCHECK 128 /* # of iterations between new player check */
Z#define QSIZE 8 /* size of input q for buffering tty reads */
Z/*
Z * Energy costs for various items
Z */
Z#define SHRAPCOST 20 /* cost of being hit by a piece of shrapnel */
Z#define TPCOST 10 /* energy cost to shoot a torpedo */
Z#define INCOST 1 /* cost for staying invisible */
Z
Z#define SCABLETTER 27
Z#define TSIZE 37 /* lifetime of a torpedo */
Z/*
Z * State bits
Z */
Z#define ALIVE 0 /* player/alien/torpedo alive */
Z#define DEAD 7 /* player/alien/torpedo dead */
Z
Z#define OFF 17
Z#define ON 23
Z/*
Z * Alien types -- normal, shankers, X-aliens
Z */
Z#define NORM 11
Z#define SHANK 13
Z#define WANDER 17
Z/*
Z * Alien monikers -- shown on screen
Z */
Z#define NAMEAL '#' /* normal type */
Z#define NAMESH '@' /* shanker */
Z#define NAMEWD 'X' /* X-alien */
Z#define NAMEP '%' /* planet component */
Z/*
Z * Input directional keyboard definitions
Z */
Z#define NO '8'
Z#define NE '9'
Z#define EA '6'
Z#define SE '3'
Z#define SO '2'
Z#define SW '1'
Z#define WE '4'
Z#define NW '7'
Z/*
Z * Other sundry commands
Z */
Z#define FIRE '0'
Z/*
Z * Union type qualifiers -- used with varargs
Z */
Z#define PLAYER 1
Z#define ALIEN 2
Z#define PLANET 3
Z#define SBASE 4
Z#define TORPEDO 5
Z
Z#define onscreen(ox,oy,x,y) (ox >= (x - XWIND*mf) && \
Zox <= (x + XWIND * mf) && \
Zoy >= (y - YWIND * mf) && \
Zoy <= (y + YWIND * mf))
Z
Z#define NULL 0
Z#define NULLCH ((char *)0)
Z#define NULLINT ((int *)0)
Z#define NOTHING ((thing *)0)
Z#define NOBODY ((t_player *)0)
Z
Z#define TRUE 1
Z#define FALSE 0
Z
Z#define isbase(p) ((p) < (thing *)&sbase[NBASE] && \
Z (p) >= (thing *)sbase)
Z#define isplayer(p) ((p) < (thing *)&player[NPLAYER] && \
Z (p) >= (thing *)player)
Z#define isalien(p) ((p) < (thing *)&alien[NALIEN] && \
Z (p) >= (thing *)alien)
Z#define istorp(p) ((p) < (thing *)&torps[NTORP] && \
Z (p) >= (thing *)torps)
Z
Z/*#define clear(p) ((void) strcat(p->outputq, p->CL))*/
Z/*#define move(x, y, p) ((void) strcat(p->outputq, tgoto((p),(x),(y)) ))*/
Z
Z
Z#define POINTFILE LIBDIR/points"
Z#define ERRLOG LIBDIR/errlog"
Z
Z/*
Z * Coordinate definitions for the titles of screen fields --
Z * probably should be defined relative to the screen dimensions.
Z */
Z#define POSTITLE 55,1
Z#define EGYTITLE 56,4
Z#define HRTITLE 53,7
Z#define H1TITLE 53,8
Z#define H2TITLE 53,9
Z#define H3TITLE 53,10
Z#define PTTITLE 56,12
Z#define STTITLE 11,16
Z#define INTITLE 4,1
Z#define VLTITLE 5,4
Z#define TMTITLE 7,7
Z#define MFTITLE 5,10
Z#define MSTITLE 11,18
Z#define PLTITLE 23,19
Z#define XAXISTITLE CENTX,7
Z#define YAXISTITLE 34
Z
Z
Z/*
Z * Positions of data fields on screen
Z */
Z#define POS1DX 55
Z#define POS1DY 2
Z#define POS1DATA POS1DX,POS1DY
Z#define POS2DX 60
Z#define POS2DY 2
Z#define POS2DATA POS2DX,POS2DY
Z#define EGYDATAX 56
Z#define EGYDATAY 5
Z#define EGYDATA EGYDATAX,EGYDATAY
Z#define H1DATAX 55
Z#define H1DATAY 8
Z#define H1DATA H1DATAX,H1DATAY
Z#define H2DATAX 55
Z#define H2DATAY 9
Z#define H2DATA H2DATAX,H2DATAY
Z#define H3DATAX 55
Z#define H3DATAY 10
Z#define H3DATA H3DATAX,H3DATAY
Z#define PTDATAX 57
Z#define PTDATAY 13
Z#define PTDATA PTDATAX,PTDATAY
Z#define STDATAX 19
Z#define STDATAY 16
Z#define STDATA STDATAX,STDATAY
Z#define INDATAX 7
Z#define INDATAY 2
Z#define INDATA INDATAX,INDATAY
Z#define VLDATAX 5
Z#define VLDATAY 5
Z#define VLDATA VLDATAX,VLDATAY
Z#define TMDATAX 6
Z#define TMDATAY 8
Z#define TMDATA TMDATAX,TMDATAY
Z#define MFDATAX 8
Z#define MFDATAY 11
Z#define MFDATA MFDATAX,MFDATAY
Z#define MSDATAX 21
Z#define MSDATAY 18
Z#define MSDATA MSDATAX,MSDATAY
Z#define PROMPTX 11
Z#define PROMPTY 19
Z
Z/*
Z * Definition of screen origin of viewport -- objects are located
Z * relative when displayed in lists.c
Z */
Z#define CENTX 19
Z#define CENTY 0
Z
Z/*
Z * Dimensions of viewport
Z */
Z#define XWIND 15
Z#define YWIND 7
STUNKYFLUFF
set `sum < defines.h`
if test 27931 != $1
then
echo defines.h: Error. number of characters is: $1, should be: 27931.
fi
#
#
echo x - structs.h
sed 's/^Z//' >structs.h <<\STUNKYFLUFF
Z/*
Z *
Z * search
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original by Greg Ordy 1979
Z * Rewrite by Sam Leffler 1981
Z * Socket code by Dave Pare 1983
Z * Ported & improved
Z * by Matt Crawford 1985
Z *
Z * file contains data structure declarations used in search.
Z * originally these were spread across several .h files.
Z *
Z * Copyright (c) 1979
Z *
Z * $Header: structs.h,v 2.2 85/08/06 22:29:49 matt Exp $
Z * $Log: structs.h,v $
Z * Revision 2.2 85/08/06 22:29:49 matt
Z * Change handling of "r", "b", "g", "j", "q" commands to
Z * provide better feedback, using per-player message buffer.
Z *
Z * Revision 2.1 85/04/10 17:32:03 matt
Z * Major de-linting and minor restructuring.
Z *
Z * Revision 1.4 85/02/11 12:44:06 matt
Z * added GUTS mode
Z *
Z * Revision 1.3 84/07/08 13:40:29 matt
Z * Added two bytes of padding to the t_file structure. Vax compiler
Z * added them implicitly but Sun compiler did not, giving "bad new
Z * player read".
Z *
Z * Revision 1.2 84/07/07 18:11:31 matt
Z * Rearranged structure t_file because it gets sent across the
Z * net and may be padded differently by different compilers.
Z *
Z */
Z
Zstruct plist {
Z char zx;
Z char zy;
Z char zchar;
Z char zflg;
Z struct plist *zpnt;
Z};
Z
Z/*
Z * Shrapnel description data base
Z */
Ztypedef struct {
Z char cbx; /* x coord of center */
Z char cby; /* y coord of center */
Z char cbactive; /* any pieces still visible */
Z char cbcnt; /* time left to stay active */
Z char shrap[9][2]; /* offsets from center of pieces */
Z char shrapd[9]; /* offset from center of each piece */
Z} t_burst;
Z
Z/*
Z * Player structure -- contains everything you'd ever
Z * want to know about a player in the game
Z */
Ztypedef struct {
Z char plname[20]; /* player's name */
Z int uid; /* Uniq identifier of player */
Z short energy; /* current energy level */
Z short maxmaxe; /* max max energy */
Z short maxe; /* max energy to accumulate */
Z char curx; /* current x coord */
Z char cury; /* current y coord */
Z char gmess[40]; /* group message buffer */
Z/* status stuff */
Z struct {
Z unsigned orb : 1; /* in orbit? */
Z unsigned bur : 1; /* pending shrapnel damage */
Z unsigned ap : 1; /* in the middle of an autopilot */
Z unsigned crash : 1; /* crash into quartone? */
Z unsigned alive : 1; /* player alive? */
Z unsigned killed : 1; /* was the player killed? */
Z unsigned invis : 1; /* are we invisible */
Z unsigned begin : 1; /* new player? */
Z unsigned guts : 1; /* wants to play "guts" */
Z } status;
Z/* points */
Z int points; /* current point total for this round */
Z long pltime; /* playing time accumulated */
Z int pkills; /* kills of other players accumulated */
Z int phits; /* hits of other players accumulated */
Z int ahits; /* alien hits accumulated */
Z/* i/o */
Z char cmdpend; /* pending command */
Z char cmd; /* current command */
Z char inputq[QSIZE]; /* for buffering input from terminal */
Z char *pinputq; /* next char to read */
Z char ninput; /* # of chars in input q -- must fit QSIZE */
Z char outputq[2048]; /* characters to output - null terminated */
Z char *eoq; /* pointer to the current end-of-queue */
Z/* autopilot */
Z union thing_u *home[3]; /* autopilot channels */
Z char *apx; /* autopilot pointer - x coord */
Z char *apy; /* autopilot pointer - y coord */
Z union thing_u *whocent; /* center over who? */
Z/* screen stuff */
Z struct plist *plstp; /* head of screen list */
Z int preve; /* last energy value displayed */
Z int prevp; /* last point total displayed */
Z int mflg; /* magnification factor */
Z char offx; /* x offset from center */
Z char offy; /* y offset from center */
Z/* quartone stuff */
Z int ocnt; /* orbit count */
Z int qkill; /* quartonites killed during current xploit */
Z int nkcnt; /* nuke count */
Z int xcount; /* xploitation count */
Z int scabcount; /* scab threshold */
Z/* Termcap additions */
Z int ttyspeed; /* baud rate for padding */
Z char PC; /* pad char */
Z char *BC; /* backspace one char */
Z char *UP; /* move up one line */
Z char *CM; /* cursor motion string */
Z char *CL; /* clear screen */
Z char *CE; /* clear to end of line */
Z/* radio and broadcast message stuff */
Z char mesgbuf[40]; /* message buffer */
Z int mesglen; /* characters in buffer */
Z int mesgdst; /* radio message destination */
Z} t_player;
Z
Z/*
Z * Definition of an alien being
Z */
Ztypedef struct {
Z char type; /* shanker, X-alien, etc. */
Z char onscr; /* on screen? */
Z char cx; /* current x coord */
Z char cy; /* current y coord */
Z char cix; /* current increment in x direction */
Z char ciy; /* current increment in y direction */
Z char fx; /* x firing direction */
Z char fy; /* y firing direction */
Z char stats; /* state bits */
Z char hit; /* # of hits taken */
Z char count; /* # in existence */
Z char aname; /* alien moniker */
Z union thing_u *whotoget; /* player to attack -- shanker */
Z} t_alien;
Z
Z/*
Z * Planet definitions
Z */
Ztypedef struct {
Z char *planetname; /* planet's name */
Z char places[17][2]; /* offsets from center of pieces */
Z} t_planet;
Z
Z/*
Z * Location of starbases
Z */
Ztypedef struct {
Z char xpos; /* x coord of center */
Z char ypos; /* y coord of center */
Z} t_sbase;
Z
Z/*
Z * Info regarding torpedoes
Z */
Ztypedef struct {
Z char torx; /* current x coord */
Z char tory; /* current y coord */
Z union thing_u *owner; /* who shot it? */
Z union thing_u *target; /* destination */
Z char xinc; /* velocity increment in x direction */
Z char yinc; /* velocity increment in y direction */
Z char tcount; /* time to live counter */
Z} t_torps;
Z
Ztypedef union thing_u { /* need a tag for recursive structs */
Z t_player u_player;
Z t_alien u_alien;
Z t_sbase u_sbase;
Z t_torps u_torps;
Z} thing;
Z
Z/*
Z * User point totals data base
Z */
Ztypedef struct {
Z char ptname[20]; /* player name */
Z int ptpoints; /* total points */
Z int pthits; /* total player hits */
Z int ptahits; /* total alien hits */
Z int ptkills; /* total player kills */
Z int ptkilled; /* total times killed */
Z int ptlast; /* last game's score */
Z int ptbest; /* best score */
Z int ptgames; /* # games played */
Z} t_totals ;
Z
Z/*
Z * One file structure is read in for each player
Z * that gets into a game
Z */
Z
Ztypedef struct {
Z int uid; /* Uniq id for the player */
Z char p_name[20]; /* player's chosen moniker */
Z char p_BC[20]; /* backspace one character */
Z char p_UP[20]; /* move up one line */
Z char p_CM[40]; /* cursor motion string */
Z char p_CL[20]; /* clear screen */
Z char p_CE[20]; /* clear to end of line */
Z int p_speed; /* terminal's ioctl speed */
Z char p_PC; /* pad character */
Z char p_flags; /* status bits of player */
Z char p_xxx[2]; /* padding for portability */
Z} t_file;
Z
Zstruct message {
Z long mtype;
Z int ident;
Z char text[10000];
Z};
STUNKYFLUFF
set `sum < structs.h`
if test 9923 != $1
then
echo structs.h: Error. number of characters is: $1, should be: 9923.
fi
echo All done
exit 0
--
______________________________________________________
Lars Pensjo
{decvax,philabs}!mcvax!enea!chalmers!myab!larscagordon@watnot.UUCP (Chris Gordon) (03/16/86)
Where's part 1?
randy@chinet.UUCP (Randy Suess) (03/18/86)
In article <11625@watnot.UUCP> cagordon@watnot.UUCP (Chris Gordon) writes: >Where's part 1? Ihnp4, the midwest backbone site, had a spooler drive problem and dumped some news on the floor, part of which was the first part of search. So any sites fed *only* by ihnp4 probably won't have it. It mite be a good idea to wait to make sure this is true, then a site that does have it, repost just that one. -- .. that's the biz, sweetheart... Randy Suess chinet - Public Access UN*X (312) 545 7535 (h) (312) 283 0559 (system) ..!ihnp4!chinet!randy