changeset 8:0836fb919dfa

First entry of Paradise Server 2.9 patch 10 Beta
author darius
date Sat, 06 Dec 1997 04:37:05 +0000
parents 814de70c9f67
children 331055a97a9d
files src/sockio.c src/stats.c src/struct.h src/structdesc.c src/structdesc.h src/sysdefaults.c src/terrain.c src/terrain.h src/timecheck.c src/tool-ds.c src/tool-heraldry.c src/tool-hr.c src/tool-hs.c src/tool-mes.c src/tool-pl.c src/tool-promo.c src/tool-reset.c src/tool-trim.c src/tool-util.c src/tool-util.h src/tool-wm.c src/tool-xtk.c src/tourny.c src/util.c src/wander2.c src/warning.c src/wm
diffstat 27 files changed, 7244 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sockio.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,440 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+
+#include "data.h"
+#include "packets.h"
+#include "shmem.h"
+
+#define BUFSIZE 16738
+static char buf[BUFSIZE];	/* Socket buffer */
+static char *bufptr = buf;
+#define UDPBUFSIZE 960		/* (tweakable; should be under 1300) */
+static char udpbuf[UDPBUFSIZE];	/* UDP socket buffer */
+static char *udpbufptr = udpbuf;
+#ifdef DOUBLE_UDP
+static char scbuf[UDPBUFSIZE];	/* semi-critical UDP socket buffer */
+static char *scbufptr = scbuf;	/* (only used for double UDP) */
+#endif
+static long sequence;		/* the holy sequence number */
+
+#define FAT_THRESH	500	/* if more than this, don't add fat */
+
+extern int udpMode;
+
+
+extern int clientDead;
+
+int 
+buffersEmpty()
+{
+  return bufptr == buf &&
+  (commMode != COMM_UDP || udpbufptr == buf);
+}
+
+void 
+resetUDPbuffer()
+{
+  if (udpbufptr != udpbuf)
+  {
+    udpbufptr = udpbuf;		/* clear out any old data */
+    sequence--;			/* we just killed a sequence packet */
+  }
+}
+
+void 
+resetUDPsequence()
+{
+  sequence = 1;
+}
+
+/*
+ * If we're in UDP mode, add a sequence number to the transmission buffer.
+ * Returns the #of bytes inserted.
+ * 
+ * This will add a sequence # to transmissions on either channel.  However, the
+ * current implementation doesn't put sequences on TCP transmissions because
+ * mixed TCP packets and UDP packets rarely arrive in the order in which they
+ * were sent.
+ */
+int
+addSequence(outbuf)
+  char *outbuf;
+{
+  struct sequence_spacket *ssp;
+
+  if (commMode != COMM_UDP || udpMode == MODE_TCP)
+    return (0);
+
+  packets_sent++;
+
+  ssp = (struct sequence_spacket *) outbuf;
+  ssp->type = SP_SEQUENCE;
+  ssp->sequence = htons((unsigned short) sequence);
+  sequence++;
+
+  return (sizeof(struct sequence_spacket));
+}
+
+/* Flush the socket buffer */
+void
+flushSockBuf()
+{
+  int cc;
+
+  if (clientDead)
+    return;
+  if (bufptr != buf)
+  {
+    if ((cc = gwrite(sock, buf, bufptr - buf)) != bufptr - buf)
+    {
+      fprintf(stderr, "std flush gwrite failed (%d, error %d)\n",
+	      cc, errno);
+      clientDead = 1;
+    }
+    bufptr = buf /* + addSequence(buf) */ ;
+  }
+  /*
+   * This is where we try to add fat.  There's no point in checking at the
+   * other places which call gwrite(), because they only call it when the
+   * buffer is already full.
+   */
+  if (udpSock >= 0
+      && udpMode == MODE_FAT
+      && (udpbufptr - udpbuf) < FAT_THRESH)
+    fatten();
+
+  if (udpSock >= 0 && udpbufptr != udpbuf)
+  {
+#ifdef BROKEN
+    /* debugging only!! */
+    if (sequence % 5 == 0)
+    {
+      /* act as if we did the gwrite(), but don't */
+      udpbufptr = udpbuf + addSequence(udpbuf);
+      goto foo;
+    }
+#endif
+    if ((cc = gwrite(udpSock, udpbuf, udpbufptr - udpbuf)) != udpbufptr - udpbuf)
+    {
+      fprintf(stderr, "UDP flush gwrite failed (%d, error %d)\n",
+	      cc, errno);
+      /* clientDead=1; */
+      UDPDIAG(("*** UDP disconnected for %s\n", me->p_name));
+      printUdpInfo();
+      closeUdpConn();
+      commMode = COMM_TCP;
+    }
+#ifdef DOUBLE_UDP
+    sendSC();
+#endif
+    udpbufptr = udpbuf + addSequence(udpbuf);
+  }
+#ifdef BROKEN
+foo:
+#endif
+  if (udpMode == MODE_FAT)
+    fatMerge();
+}
+
+void 
+build_select_masks(readfds, writefds)
+  fd_set *readfds, *writefds;
+{
+  if (readfds)
+  {
+    FD_ZERO(readfds);
+    FD_SET(sock, readfds);
+    if (udpSock >= 0)
+      FD_SET(udpSock, readfds);
+  }
+  if (writefds)
+  {
+    FD_ZERO(writefds);
+    if (haveDeferredPackets())
+      FD_SET(sock, writefds);
+  }
+}
+
+int
+socketPause()
+{
+  struct timeval timeout;
+  fd_set readfds, writefds;
+
+  timeout.tv_sec = 1;
+  timeout.tv_usec = 0;
+
+  build_select_masks(&readfds, &writefds);
+
+  return select(32, (fd_set *) & readfds, &writefds, 0, &timeout);
+}
+
+int
+socketWait()
+{
+  fd_set readfds, writefds;
+
+  build_select_masks(&readfds, &writefds);
+
+  return select(32, &readfds, &writefds, 0, (struct timeval *) 0);
+}
+
+int
+gwrite(fd, wbuf, bytes)
+  int fd;
+  char *wbuf;
+  int bytes;
+{
+  int orig = bytes;
+  int n;
+  char tempbuf[80];
+  struct timeval to;
+
+
+  while (bytes)
+  {
+    n = write(fd, wbuf, bytes);
+    if (n < 0)
+    {
+      if (errno == ENOBUFS)
+      {
+	/*
+	 * The man pages don't mention this as a possibility. Yet, it
+	 * happens.  I guess I just wait for 1/10 sec, and continue?
+	 */
+	/*
+	 * I would use usleep() to do this, but this system ain't got it...
+	 */
+	/* note: changed from 100 ms to 20 ms. (HAK) */
+	to.tv_sec = 0;
+	to.tv_usec = 20000;
+	select(0, NULL, NULL, NULL, &to);
+	continue;
+      }
+      if (errno == EINTR)	/* interrupted by signal, restart */
+	continue;
+
+      if (fd == udpSock)
+      {
+	/* do we want Hiccup code here? */
+	UDPDIAG(("Tried to write %d, 0x%lx, %d (error %d)\n",
+		 fd, (unsigned long) wbuf, bytes, errno));
+	printUdpInfo();
+	logmessage("UDP gwrite failed:");
+      }
+      sprintf(tempbuf, "Died in gwrite, n=%d, errno=%d <%s@%s>",
+	      n, errno, me->p_login, me->p_full_hostname);
+      logmessage(tempbuf);
+      return (-1);
+    }
+    bytes -= n;
+    wbuf += n;
+  }
+  return (orig);
+}
+
+
+void 
+sendUDPbuffered(issc, packet, size)
+  int issc;			/* is semi-critical */
+  void *packet;
+  int size;
+{
+  if (udpbufptr - udpbuf + size >= UDPBUFSIZE)
+  {
+    int cc;
+    if ((cc = gwrite(udpSock, udpbuf, udpbufptr - udpbuf)) !=
+	udpbufptr - udpbuf)
+    {
+      fprintf(stderr, "UDP gwrite failed (%d, error %d)\n",
+	      cc, errno);
+      /* clientDead=1; */
+      UDPDIAG(("*** UDP disconnected for %s\n", me->p_name));
+      printUdpInfo();
+      closeUdpConn();
+      commMode = COMM_TCP;
+    }
+#ifdef DOUBLE_UDP
+    sendSC();			/* send semi-critical info, if needed */
+#endif
+    udpbufptr = udpbuf + addSequence(udpbuf);
+  }
+  memcpy(udpbufptr, packet, size);
+  udpbufptr += size;
+
+#ifdef DOUBLE_UDP
+  if (issc && udpMode == MODE_DOUBLE)
+  {
+    memcpy(scbufptr, packet, size);
+    scbufptr += size;
+    V_UDPDIAG((" adding SC\n"));
+  }
+#endif
+  if (issc && udpMode == MODE_FAT)
+  {
+    updateFat(packet);
+  }
+}
+
+
+void 
+sendTCPbuffered(packet, size)
+  void *packet;
+  int size;
+{
+  int cc;
+  /* these are critical packets; send them via TCP */
+#ifdef FEATURE_DIAG
+  /* check the packet & see if we're adding packet type 60 to the buffer */
+  if (*((char *) packet) == SP_FEATURE)
+  {
+    fprintf(stderr, "Sending SP_FEATURE packet\n");
+  }
+#endif
+  if (bufptr - buf + size >= BUFSIZE)
+  {
+#ifdef FEATURE_DIAG
+    if (*((char *) packet) == SP_FEATURE)
+    {
+      fprintf(stderr, "Sending TCP buffer, delaying write.\n");
+    }
+#endif
+    if ((cc = gwrite(sock, buf, bufptr - buf)) != bufptr - buf)
+    {
+      fprintf(stderr, "TCP gwrite failed (%d, error %d)\n",
+	      cc, errno);
+      clientDead = 1;
+    }
+    bufptr = buf /* + addSequence(buf) */ ;
+  }
+#ifdef FEATURE_DIAG
+  if (*((char *) packet) == SP_FEATURE)
+  {
+    fprintf(stderr, "Adding SP_FEATURE packet to buffer.\n");
+  }
+#endif
+  memcpy(bufptr, packet, size);
+  bufptr += size;
+}
+
+/* Transmission of some packets can be delayed indefinitely */
+
+struct deferred_packet
+{
+  void *data;
+  int size;
+  struct deferred_packet *next;
+};
+
+struct deferred_packet *df_head, *df_tail;
+
+int 
+haveDeferredPackets()
+{
+  return df_head != 0;
+}
+
+/* Put a packet on the deferred queue. */
+
+void 
+sendTCPdeferred(packet, size)
+  void *packet;
+  int size;
+{
+#if 1
+  /* I'm having problems with UDP connection packet */
+  sendTCPbuffered(packet, size);
+#else
+  struct deferred_packet *pkt;
+  pkt = (struct deferred_packet *) malloc(sizeof(*pkt));
+  pkt->data = malloc(size);
+  pkt->size = size;
+  memcpy(pkt->data, packet, size);
+  pkt->next = 0;
+
+  if (df_tail)
+  {
+    df_tail->next = pkt;
+  }
+  else
+  {
+    df_head = pkt;
+  }
+  df_tail = pkt;
+#endif
+}
+
+/*
+ * When the socket is ready for write, toss a packet through the pipe
+ * Hopefully it won't block...
+ */
+
+void 
+flushDeferred()
+{
+  int rval;
+
+  if (df_head == 0)
+    return;
+
+  /* could block, oh well */
+  rval = gwrite(sock, df_head->data, df_head->size);
+
+  if (rval != df_head->size)
+  {
+    fprintf(stderr, "TCP gwrite (deferred) failed (%d, error %d)\n",
+	    rval, errno);
+    clientDead = 1;
+  }
+
+  {
+    struct deferred_packet *temp = df_head;
+    df_head = temp->next;
+    free(temp->data);
+    free(temp);
+  }
+  if (!df_head)
+    df_tail = 0;		/* queue is empty */
+}
+
+/* sends all the deferred packets through the TCP buffer */
+void 
+undeferDeferred()
+{
+  while (df_head)
+  {
+    sendTCPbuffered(df_head->data, df_head->size);
+
+    {
+      struct deferred_packet *temp = df_head;
+      df_head = temp->next;
+      free(temp->data);
+      free(temp);
+    }
+  }
+  df_tail = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,56 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+#include "defs.h"
+#include "struct.h"
+#include "shmem.h"
+
+void
+credit_armiesbombed(plyr, armies, plan)
+  struct player *plyr;
+  int armies;
+  struct planet *plan;
+{
+  double factor;
+
+  if (!status->tourn)
+    return;			/* nothing counts outside T-mode */
+
+  plyr->p_armsbomb += armies;	/* inc armies bombed */
+
+  /* no honor in beating up on someone who isn't there */
+  factor = (plan->pl_owner == NOBODY) ? 0.5 : 1.0;
+
+  plyr->p_stats.st_di += 0.02 * armies * factor;	/* inc players DI */
+#ifdef WB_BOMBING_CREDIT
+  if (plyr->p_ship.s_type == WARBASE)
+    plyr->p_stats.st_di += 0.02 * armies * factor;
+#endif
+  plyr->p_kills += 0.02 * armies * factor;	/* increase players kills */
+
+  armies = random_round(factor * armies);
+
+  status->armsbomb += armies;
+  plyr->p_stats.st_tarmsbomb += armies;	/* increase player stats */
+#ifdef WB_BOMBING_CREDIT
+  if (plyr->p_ship.s_type == WARBASE)
+    plyr->p_stats.st_tarmsbomb += armies;
+#endif
+  checkmaxkills(plyr->p_no);	/* check if over max kills */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/struct.h	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,1174 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#ifndef struct_h_
+#define struct_h_
+
+
+#include "defs.h"
+
+
+
+
+
+/*-----------------------------SHIP STRUCTURE------------------------------*/
+
+enum ship_types_e
+{
+  SCOUT, DESTROYER, CRUISER, BATTLESHIP, ASSAULT, STARBASE, ATT,
+  JUMPSHIP, FRIGATE, WARBASE, LIGHTCRUISER, CARRIER, UTILITY, PATROL
+
+#if 1
+#define	NUM_TYPES	14	/* this is less clean, but cc has a */
+  /* problem with using an enum constant */
+  /* as an array dimension.  POS compiler. */
+#else
+  NUM_TYPES
+#endif
+};
+
+struct drivestat
+{
+  /* various drive type statistics */
+  int acc;			/* acceleration */
+  int dec;			/* decelleration */
+  int cost;			/* fuel cost */
+  int maxspeed;			/* maximum speed */
+  int etemp;			/* engine temperature */
+};
+
+struct weaponstat
+{
+  short damage;			/* damage potential */
+  short speed;			/* speed for missiles, range for beams */
+  short cost;			/* fuel cost */
+  short fuse;			/* how long they last */
+  short wtemp;			/* weapon temperature cost */
+  short wtemp_halfarc;		/* Arc the penalty is calculated from */
+  short wtemp_factor;		/* Penalty Factor 1-16 of wtemp caused */
+  short count;			/* how many we can have airborne */
+  short aux;			/* aux field */
+  /* aux is turn rate for torps and plasmas. */
+};
+
+struct ship
+{
+
+  short s_type;			/* ship type, defined with the number */
+  short s_alttype;		/* This MUST be a legal vanilla bronco type */
+  char s_name[32];		/* ship's name */
+
+  /* engine characteristics */
+  int s_turns;			/* ship\'s turning */
+#undef	s_imp			/* bloody obsolete header files */
+  struct drivestat s_imp;	/* impulse drive stats */
+  struct drivestat s_after;	/* impulse drive stats */
+  struct drivestat s_warp;	/* impulse drive stats */
+  int s_warpinitcost;		/* fuel charge to initialize warp */
+  int s_warpinittime;		/* time to initialize warp */
+  int s_warpprepspeed;		/* speed while initializing warp */
+
+  short s_mass;			/* to guage affect of tractor beams */
+
+  /* tractor characteristics */
+  short s_tractstr;		/* Strength of tractor beam */
+  float s_tractrng;		/* tractor range */
+  int s_tractcost;		/* fuel used by tractors */
+  int s_tractetemp;		/* e-temp caused by tractors */
+
+  struct weaponstat s_torp;	/* torp characteristics */
+  struct weaponstat s_phaser;	/* phaser characteristics */
+  struct weaponstat s_missile;	/* missile characteristics */
+  struct weaponstat s_plasma;	/* plasma characteristics */
+  short s_missilestored;	/* how many missiles can we store? */
+
+  /* Raynfala's Butt Torp Code. Gjor's Ship Patch for his code to do it */
+  /* for each ship.						       */
+
+  short s_torp_penalty_halfarc;
+  short s_torp_penalty_factor;
+
+  int s_maxwpntemp;		/* max W-temp */
+  short s_wpncoolrate;		/* weapon cool rate */
+
+  int s_maxegntemp;		/* max engine temp */
+  short s_egncoolrate;		/* engine cool rate */
+
+  /* fuel characteristics */
+  int s_maxfuel;		/* ship's maximum fuel */
+  short s_recharge;		/* speed fuel recharges */
+  int s_mingivefuel;		/* ship must have this much to give fuel */
+  int s_takeonfuel;		/* how fast ship takes on fuel */
+
+  short s_expldam;		/* damage done by ship's explosion (assuming
+				 * his fuel tank is empty) */
+  short s_fueldam;		/* the amount of _additional_ damage that
+				 * this ship's explosion does with a full
+				 * tank */
+
+  /* miscellaneous army stats */
+  float s_armyperkill;		/* the number of armies per kill */
+  short s_maxarmies;		/* max armies ship can carry */
+  int s_bomb;			/* bomb damage ship can do */
+
+  /* hull, shield and repair stats */
+  short s_repair;		/* ship's repair rate */
+  int s_maxdamage;		/* maximum damage ship can take */
+  int s_maxshield;		/* maximum shield value */
+  int s_shieldcost;		/* cost in fuel of shields being up */
+
+  short s_detcost;		/* fuel cost of detting */
+  int s_detdist;		/* fuel cost of detting */
+  short s_cloakcost;		/* base fuel cost of cloaking */
+
+  short s_scanrange;		/* range of the ship's scanners */
+
+  short s_numports;		/* how many docking ports do we have? */
+
+  char s_letter;		/* the letter used to enter as that ship */
+  char s_desig1;		/* the designation used (such as A, in AS */
+  char s_desig2;		/* the designation used (such as S, in AS */
+
+  short s_bitmap;		/* the bitmap to use */
+  short s_width;		/* width of bitmap */
+  short s_height;		/* height of bitmap */
+
+  /* ship requisition limitations */
+  int s_timer;			/* value to set timer to get another ship */
+  int s_maxnum;			/* maximum number of these per team */
+  int s_rank;			/* minimum rank for this sucker */
+  int s_numdefn;		/* number of player necessary */
+  int s_numplan;		/* number of planets */
+
+  long s_nflags;		/* attributes for ship type, SFN flags */
+};
+
+/*
+ * ATTENTION!!! Changes to these flags should be mirrored in structdesc.c
+ */
+/* For s_nflags field */
+#if 0
+#define SFNDOCKON       (1<< 0)	/* specify a ship to docked on */
+#define SFNCANDOCK      (1<< 1)	/* specify a ship can dock */
+#else
+#define SFNUNDOCKABLE	(1<< 0)	/* this ship can not dock with another */
+#define SFNCANORBIT     (1<< 1)	/* specify a ship can orbit */
+#endif
+#define SFNCANWARP      (1<< 2)	/* this ship can go warp */
+#define SFNCANFUEL	(1<< 3)	/* base can give docked ships fuel */
+#define SFNCANREPAIR	(1<< 4)	/* base can repair docked ships */
+#define SFNCANREFIT	(1<< 5)	/* base allows a refit while docked */
+#define SFNARMYNEEDKILL (1<< 6)	/* does ship need kills to carry */
+
+#define SFNHASPHASERS	(1<< 7)	/* this ship has phasers */
+
+#define SFNPLASMASTYLE  (1<< 8)	/* style of firing plasmas */
+
+#define SFNMASSPRODUCED (1<< 9)	/* ship can appear docked to an SB or UT */
+
+#define SFNPLASMAARMED	(1<<10)
+#define SFNHASMISSILE	(1<<11)
+
+#define SFNHASFIGHTERS	(1<<12)	/* ship has a fighter bay */
+
+#if 0
+#define allows_docking(s_ship)	((s_ship).s_nflags & SFNDOCKON)
+#define can_dock(s_ship)	((s_ship).s_nflags & SFNCANDOCK)
+#else
+#define allows_docking(s_ship)	((s_ship).s_numports>0)
+#define can_dock(s_ship)	((s_ship).s_numports==0 && !((s_ship).s_nflags&SFNUNDOCKABLE))
+#endif
+/*-------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+/*----------------------------STATS STRUCTURE------------------------------*/
+
+struct stats
+{
+  int st_genocides;		/* number of genocides participated in */
+  float st_tmaxkills;		/* max kills ever */
+  float st_di;			/* total destruction inflicted for all time */
+  int st_tkills;		/* Kills in tournament play */
+  int st_tlosses;		/* Losses in tournament play */
+  int st_tarmsbomb;		/* Tournament armies bombed */
+  int st_tresbomb;		/* resources bombed off */
+  int st_tdooshes;		/* armies killed while being carried */
+  int st_tplanets;		/* Tournament planets conquered */
+  int st_tticks;		/* Tournament ticks */
+  /* SB/WB/JS stats are entirely separate */
+  int st_sbkills;		/* Kills as starbase */
+  int st_sblosses;		/* Losses as starbase */
+  int st_sbticks;		/* Time as starbase */
+  float st_sbmaxkills;		/* Max kills as starbase */
+  int st_wbkills;		/* Kills as warbase */
+  int st_wblosses;		/* Losses as warbase */
+  int st_wbticks;		/* Time as warbase */
+  float st_wbmaxkills;		/* Max kills as warbase */
+  int st_jsplanets;		/* planets assisted with in JS */
+  int st_jsticks;		/* ticks played as a JS */
+  long st_lastlogin;		/* Last time this player was played */
+  int st_flags;			/* Misc option flags */
+  int st_cluesuccess;		/* how many times you passed a clue check */
+  char st_pad[92];		/* space for expansion */
+  int st_rank;			/* Ranking of the player */
+  int st_royal;			/* royaly, specialty, rank */
+};
+
+/*
+ * These are for the flags field and control the preset options of the
+ * players client.
+ */
+#if 0
+#define ST_MAPMODE      0x001
+#define ST_NAMEMODE     0x002
+#define ST_SHOWSHIELDS  0x004
+#endif
+#define ST_NOBITMAPS	(1<<0)
+#define ST_KEEPPEACE    (1<<3)
+#if 0
+#define ST_SHOWLOCAL    0x010	/* two bits for these two */
+#define ST_SHOWGLOBAL   0x040
+#endif
+#define ST_CYBORG	(1<<8)
+
+/* initial value to put in flags */
+#define ST_INITIAL ST_KEEPPEACE
+/*
+ * ST_MAPMODE+ST_NAMEMODE+ST_SHOWSHIELDS+ \
+ * ST_KEEPPEACE+ST_SHOWLOCAL*2+ST_SHOWGLOBAL*2;
+ */
+
+/*-------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+/*---------------------------VARIOUS STRUCTURES----------------------------*/
+
+/*
+ * This is used to indicate various things about the game and to hold global
+ * stats about it.  All stats are only updated while in t-mode.
+ */
+struct status
+{
+  int active;			/* for interfacing with people who */
+  unsigned int wait, count;	/* want to get into the game */
+  unsigned int number, request, answer;
+  unsigned char tourn;		/* Tournament mode? */
+  unsigned long dooshes;	/* total number of armies dooshed */
+  unsigned long armsbomb;	/* all t-mode armies bombed */
+  unsigned long resbomb;	/* resources bombed */
+  unsigned long planets;	/* all t-mode planets taken */
+  unsigned long kills;		/* all t-mode kills made */
+  unsigned long losses;		/* all t-mode losses */
+  unsigned long genocides;	/* number of genocides */
+  unsigned long sbkills;	/* total kills in SB's */
+  unsigned long sblosses;	/* total losses in Sb's */
+  unsigned long sbtime;		/* total time in SB's */
+  unsigned long wbkills;	/* kills in warbases */
+  unsigned long wblosses;	/* losses in warbases */
+  unsigned long wbtime;		/* total time played in wb's */
+  unsigned long jsplanets;	/* total planets taken by jump ships */
+  unsigned long jstime;		/* total time in a jump ship */
+  unsigned long time;		/* t-mode time */
+  unsigned long timeprod;	/* t-mode ship ticks--sort of like */
+  /* manhours in t-mode */
+  unsigned long clock;		/* clock used for timestamping */
+  int nukegame;			/* set to PID of daemon */
+  int gameup;			/* is game up */
+};
+
+/*
+ * Some of the stuff above belongs in struct status2
+ */
+
+struct league_team
+{
+  int index;			/* team index, not mask. -1 means captain
+				 * hasn't chosen yet */
+  int captain;			/* player number of captain */
+  char name[32];
+  int timeouts_left;		/* NYI */
+  int ready;
+  int desirepause;		/* do we want to pause the game? */
+
+  struct
+  {
+    int regulation;		/* game length */
+    int overtime;
+    int maxplayers;		/* max players per team */
+    int galaxyreset;		/* do we want to reset the galaxy? */
+    int restart;		/* should we restart team selection? */
+  }   desired;
+};
+
+struct status2
+{
+#ifdef LEAGUE_SUPPORT
+  int league;			/* are we playing league? 0 means no. 1 means
+				 * we're prepping (captains choose sides). 2
+				 * means we're almost there. 3 means we're in
+				 * regulation league play. 4 means we're in
+				 * overtime */
+  int leagueticksleft;		/* ticks left in game play */
+
+  struct league_team home, away;
+
+  int timeout_timeleft;		/* ticks left in a timeout */
+  int awaypassed;		/* does the away team get first choice? this
+				 * becomes 1 if they PASS */
+  int paused;			/* contains 0 if the game is not paused.
+				 * contains the number of ticks left before
+				 * return to normal play if already paused */
+  int pausemsgfuse;		/* a fuse that prints out a reminder every
+				 * few seconds */
+#endif
+  int starttourn;
+  int newgalaxy;
+  int nontteamlock;
+};
+
+
+/*
+ * used for the request field of status.  These are used for a client
+ * querying the queue to see if he can get in
+ */
+
+enum queue_request_type_e
+{
+  REQFREE, REQWHO, REQDEAD
+};
+
+/*
+ * This structure is used to hold various info that each team has, such as
+ * how long before a certain ship type is done with construction.
+ */
+struct team
+{
+  char nickname[32];		/* he is now a %s  */
+  char name[32];		/* come join the %s */
+  char letter;			/* 1-letter abbrev */
+  char shortname[4];		/* 3-letter abbrev */
+
+  int s_turns[NUM_TYPES];	/* turns till another ship is legal */
+  int s_surrender;		/* minutes until this team surrenders */
+  int s_plcount;		/* how many planets this team owns */
+  int s_plcountold;		/* the old planet count */
+};
+
+
+/*
+ * this is used for getting a player name and password and fetching a players
+ * stats
+ */
+struct statentry
+{
+  char name[16];		/* player's name */
+  char password[16];		/* player's password */
+  struct stats stats;		/* player's stats */
+};
+
+/* Used by the function that computes ratings */
+struct rating
+{
+  float battle;
+  float strategy;
+  float special;
+
+  float bombrat;
+  float planetrat;
+  float resrat;
+  float offrat;
+  float dooshrat;
+  float ratio;
+
+  float sbrat;
+  float wbrat;
+  float jsrat;
+};
+
+/*-------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+/*-----------------------------PLAYER STRUCTURE----------------------------*/
+
+#define MAXPORTS	6	/* maximum number of docking bays a ship type
+				 * can have */
+
+/* These are defines for the p_whydead field of the player structure */
+enum why_dead_e
+{
+  KNOREASON,
+  KQUIT,			/* Player quit */
+  KTORP,			/* killed by torp */
+  KPHASER,			/* killed by phaser */
+  KPLANET,			/* killed by planet */
+  KSHIP,			/* killed by other ship */
+  KDAEMON,			/* killed by dying daemon */
+  KWINNER,			/* killed by a winner */
+  KGHOST,			/* killed because a ghost */
+  KGENOCIDE,			/* killed by genocide */
+  KPROVIDENCE,			/* killed by a hacker */
+  KPLASMA,			/* killed by a plasma torpedo */
+  KTOURNEND,			/* killed by the end of the tourn */
+  KOVER,			/* killed by overtime */
+  KTOURNSTART,			/* killed by the start of the tournament */
+  KBINARY,			/* killed by improper client */
+  KMISSILE,			/* killed by a missile */
+  KASTEROID			/* smashed by an asteroid */
+};
+
+/* These are number defines for the player structs p_status field */
+enum player_status_e
+{
+  PFREE,			/* player slot is not filled */
+  POUTFIT,			/* player in process of being ghost busted */
+  PALIVE,			/* player is alive */
+  PEXPLODE,			/* player is in process of exploding */
+  PDEAD,			/* player is dead */
+  PTQUEUE,			/* player is on the tournament queue */
+  POBSERVE			/* player is observing the game */
+};
+
+
+struct player
+{
+  int p_no;			/* player number in player array */
+  int p_updates;		/* Number of updates ship has survived */
+  enum player_status_e p_status;/* Player status */
+  char p_observer;		/* is the player only an observer? */
+  unsigned int p_flags;		/* Player flags */
+  char p_name[16];		/* name of player */
+  char p_login[16];		/* as much of user name and site we can hold */
+  char p_monitor[16];		/* Monitor being played on */
+  struct ship p_ship;		/* Personal ship statistics */
+  int p_x;			/* players x coord in the galaxy */
+  int p_y;			/* player y coord in the galaxy */
+
+  unsigned char p_dir;		/* Real direction */
+  int p_subdir;			/* fraction direction change */
+  unsigned char p_desdir;	/* desired direction */
+
+  int p_speed;			/* Real speed */
+  int p_subspeed;		/* Fractional speed */
+  short p_desspeed;		/* Desired speed */
+  short p_warpdesspeed;		/* Desired warp speed, after prep [BDyess] */
+
+  short p_team;			/* Team I'm on */
+  enum HomeAway
+  {
+    NEITHER, HOME, AWAY
+  }   p_homeaway;
+  char p_spyable;		/* can you watch this player? */
+  char p_teamspy;		/* (mask) what teams can this player watch? */
+
+  int p_damage;			/* Current damage */
+  int p_subdamage;		/* Fractional damage repair */
+
+  int p_shield;			/* Current shield power */
+  int p_subshield;		/* Fractional shield recharge */
+
+  short p_cloakphase;		/* Drawing stage of cloaking engage/disengage */
+
+  short p_ntorp;		/* Number of torps flying */
+  short p_nplasmatorp;		/* Number of plasma torps active */
+  short p_nthingys;		/* number of thingys we own. */
+  long p_specweap;		/* which special weapons we're packing */
+
+  char p_hostile;		/* Who my torps will hurt */
+  char p_swar;			/* Who am I at sticky war with */
+
+  float p_kills;		/* Enemies killed */
+  short p_planet;		/* Planet orbiting or locked onto */
+  char p_orbitdir;		/* direction you are orbiting the planet in */
+  short p_playerl;		/* Player locked onto */
+  short p_armies;		/* armies player is carrying */
+
+  int p_fuel;			/* fuel player's ship currently has */
+  short p_explode;		/* Keeps track of final explosion */
+
+  int p_etemp;			/* player's current engine temp */
+  int p_subetemp;		/* fractional part of E-temp */
+  short p_etime;		/* timer for coming out of E-temp */
+
+  int p_wtemp;			/* current weapon temp */
+  short p_wtime;		/* timer for coming out of W-temp */
+
+  enum why_dead_e p_whydead;	/* Tells you why you died */
+  short p_whodead;		/* Tells you who killed you */
+  struct stats p_stats;		/* player statistics */
+  short p_planets;		/* planets taken this game */
+  short p_armsbomb;		/* armies bombed this game */
+  short p_resbomb;		/* resources bombed */
+  short p_dooshes;		/* armies being carried killed */
+  int p_ghostbuster;		/* ??????????????? */
+  int p_docked;			/* If SB, # docked to, else no base host */
+  int p_port[MAXPORTS];		/* If SB, pno of ship docked to that port,
+				 * else p_port[0] = port # docked to on host. */
+  short p_tractor;		/* What player is in tractor lock */
+  int p_pos;			/* My position in the player file */
+  char p_full_hostname[32];	/* full hostname 4/13/92 TC */
+#if 0
+  int p_planfrac;		/* for getting fractional credit for */
+  int p_bombfrac;		/* bombing and planet taking */
+#endif
+  int p_warptime;		/* timer for warp countdown */
+  int p_jsdock;			/* to keep track of undocking from JS */
+  int p_lastjs;			/* player number of last JS ridden on */
+  int p_lastman;		/* flag used to beam up last men */
+
+  int p_lastrefit;		/* what shipyard you last refitted at (plno) */
+  /* ping stuff */
+  int p_avrt;			/* average round trip time */
+  int p_stdv;			/* standard deviation in round trip time */
+  int p_pkls;			/* packet loss (input/output) */
+
+  /* clue checking goop */
+  int p_cluecountdown;
+  int p_cluedelay;
+
+  int p_ntspid;			/* proc ID of ntserv in control of this slot */
+  int p_zone;			/* total warp zone bonus/penalty [BDyess] */
+
+#ifdef	RC_DISTRESS
+  int gen_distress;		/* generate generic distress messages for
+				 * client */
+#endif
+};
+
+/* These are defines that used for the player struct's p_flags field */
+#define PFSHIELD	  (1<< 0)	/* shields are raised */
+#define PFREPAIR	  (1<< 1)	/* player in repair mode */
+#define PFBOMB		  (1<< 2)	/* player is bombing */
+#define PFORBIT		  (1<< 3)	/* player is orbiting */
+#define PFCLOAK		  (1<< 4)	/* player is cloaked */
+#define PFWEP		  (1<< 5)	/* player is weapon temped */
+#define PFENG		  (1<< 6)	/* player is engine temped */
+#define PFROBOT		  (1<< 7)	/* player is a robot */
+#define PFBEAMUP	  (1<< 8)	/* player is beaming up */
+#define PFBEAMDOWN	  (1<< 9)	/* player is beaming down */
+#define PFSELFDEST	  (1<<10)	/* player is self destructing */
+#define PFGREEN		  (1<<11)	/* player at green alert */
+#define PFYELLOW	  (1<<12)	/* player is at yellow alert */
+#define PFRED		  (1<<13)	/* player is at red alert */
+#define PFPLOCK		  (1<<14)	/* Locked on a player */
+#define PFPLLOCK	  (1<<15)	/* Locked on a planet */
+#define PFCOPILOT	  (1<<16)	/* Allow copilots */
+#define PFWAR		  (1<<17)	/* computer reprogramming for war */
+#define PFPRACTR	  (1<<18)	/* practice type robot (no kills) */
+#define PFDOCK            (1<<19)	/* true if docked to a starbase */
+#define PFREFIT           (1<<20)	/* true if about to refit */
+#define PFREFITTING	  (1<<21)	/* true if currently refitting */
+#define PFTRACT  	  (1<<22)	/* tractor beam activated */
+#define PFPRESS  	  (1<<23)	/* pressor beam activated */
+#define PFDOCKOK	  (1<<24)	/* docking permission */
+#define PFSEEN		  (1<<25)	/* seen by enemy on galactic map? */
+#define PFWARPPREP	  (1<<26)	/* in warp prep */
+#define PFWARP		  (1<<27)	/* ship warping */
+#define PFAFTER		  (1<<28)	/* after burners on */
+#define PFWPSUSPENDED	  (1<<29)	/* warp prep suspended [BDyess] */
+#define PFSNAKE	          (1<<30)	/* it's a space snake */
+#define PFBIRD	          (1<<31)	/* it's a space bird */
+/*-------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+/*-----------------------------TORP STRUCTURE-------------------------------*/
+
+
+/* For status field of torp structure */
+enum torp_status_e
+{
+  TFREE,			/* torp is not being fired */
+  TMOVE,			/* torp is moving with wobble */
+  TEXPLODE,			/* torp is in the process of exploding */
+  TDET,				/* torp is being detted */
+  TOFF,				/* torp is off ??? */
+  TSTRAIGHT,			/* Non-wobbling torp */
+  TRETURN,			/* torp is returning to owner (fighters) */
+  TLAND				/* torp gets recovered */
+};
+
+struct basetorp
+{
+  int bt_no;
+  enum torp_status_e bt_status;
+  int bt_owner;
+  int bt_x, bt_y;
+  unsigned char bt_dir;
+  int bt_damage;
+  int bt_speed;
+  int bt_fuse;
+  char bt_war;
+  char bt_team;
+  char bt_whodet;		/* who detonated... */
+};
+
+
+struct torp
+{
+  struct basetorp t_base;
+#define t_no		t_base.bt_no
+#define t_status	t_base.bt_status
+#define t_owner		t_base.bt_owner
+#define t_x		t_base.bt_x
+#define t_y		t_base.bt_y
+#define t_dir		t_base.bt_dir
+#define t_damage	t_base.bt_damage
+#define t_speed		t_base.bt_speed
+#define t_fuse		t_base.bt_fuse
+#define t_war		t_base.bt_war
+#define t_team		t_base.bt_team
+#define t_whodet	t_base.bt_whodet
+  short t_turns;		/* rate of change of direction if tracking */
+};
+
+/*-------------------------------------------------------------------------*/
+
+struct missile
+{
+  struct basetorp ms_base;
+#define ms_no		ms_base.bt_no
+#define ms_status	ms_base.bt_status
+#define ms_owner	ms_base.bt_owner
+#define ms_x		ms_base.bt_x
+#define ms_y		ms_base.bt_y
+#define ms_dir		ms_base.bt_dir
+#define ms_damage	ms_base.bt_damage
+#define ms_speed	ms_base.bt_speed
+#define ms_fuse		ms_base.bt_fuse
+#define ms_war		ms_base.bt_war
+#define ms_team		ms_base.bt_team
+#define ms_whodet       ms_base.bt_whodet
+  short ms_turns;
+  short ms_locked;
+  short ms_type;		/* A missile, fighter, or mine */
+  short fi_hasfired;		/* has the fighter fired a torp? */
+};
+/* defines for ms_type */
+#define MISSILETHINGY 0
+#define FIGHTERTHINGY 1
+#define MINETHINGY 2
+
+enum thingy_type
+{
+  TT_NONE,
+  TT_WARP_BEACON
+};
+
+struct warp_beacon
+{
+  int owner;
+  int x, y;
+};
+
+struct thingy
+{
+  enum thingy_type type;
+  union
+  {
+    struct warp_beacon wbeacon;
+  }   u;
+};
+
+
+
+/*---------------------------PLASMA TORP STRUCTURE-------------------------*/
+/* For the plasma status field */
+struct plasmatorp
+{
+  struct basetorp pt_base;
+#define pt_no		pt_base.bt_no
+#define pt_status	pt_base.bt_status
+#define PTFREE	TFREE
+#define PTMOVE	TMOVE
+#define PTEXPLODE	TEXPLODE
+#define PTDET	TDET
+#define pt_owner	pt_base.bt_owner
+#define pt_x		pt_base.bt_x
+#define pt_y		pt_base.bt_y
+#define pt_dir		pt_base.bt_dir
+#define pt_damage	pt_base.bt_damage
+#define pt_speed	pt_base.bt_speed
+#define pt_fuse		pt_base.bt_fuse
+#define pt_war		pt_base.bt_war
+#define pt_team		pt_base.bt_team
+#define pt_whodet	pt_base.bt_whodet
+  short pt_turns;		/* ticks turned per cycle */
+};
+
+
+/*-------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+/*-----------------------------PHASER STRUCTURE---------------------------*/
+
+struct phaser
+{
+  int ph_status;		/* What it's up to */
+  unsigned char ph_dir;		/* direction */
+  int ph_target;		/* Who's being hit (for drawing) */
+  int ph_x, ph_y;		/* For when it hits a torp */
+  int ph_fuse;			/* Life left for drawing */
+  int ph_damage;		/* Damage inflicted on victim */
+};
+
+/* for phaser's status field */
+#define PHFREE 0x00		/* phaser not being fired */
+#define PHHIT  (1<<0)		/* When it hits a person */
+#define PHMISS (1<<1)		/* phaser missed */
+#define PHHIT2 (1<<2)		/* When it hits a plasma */
+
+/*-------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+/*-----------------------------PLANET STRUCTURE---------------------------*/
+
+/* This structure is used to hold what each team knows about a planet */
+struct teaminfo
+{				/* to hold what a team knows about a planet */
+  int owner;			/* planet's owner */
+  int armies;			/* number of armies team knows about */
+  int flags;			/* flags team knows about */
+  int timestamp;		/* time info was taken */
+};
+
+struct planet
+{				/* all info about a planet */
+  int pl_no;			/* planet number */
+  int pl_flags;			/* attributes of planet */
+  int pl_owner;			/* the current owner of the planet */
+
+  int pl_x;			/* planet's coords */
+  int pl_y;			/* use the move_planet function to change
+				 * them */
+  int pl_radius;		/* distance from sun */
+  float pl_angle;		/* angular position relative to sun */
+  int pl_system;		/* planetary system number, 0 = no system */
+
+  char pl_name[16];		/* name of the planet */
+  char pl_namelen;		/* name's length--Cuts back on strlen's */
+#if 1
+  char pl_hostile;
+#else
+  char pl_torbit;		/* teams currently in orbit */
+#endif
+  int pl_tshiprepair;		/* repair and shipyard growth timer */
+  int pl_tagri;			/* agri growth timer */
+  int pl_tfuel;			/* fuel depot growth timer */
+  int pl_armies;		/* armies curently on planet */
+  int pl_warning;		/* timer so that planets don't talk too much */
+  int pl_hinfo;			/* which races have info on planet */
+  struct teaminfo pl_tinfo[MAXTEAM + 1];	/* to hold information for
+						 * races */
+  int pl_trevolt;		/* timer for planet revolting */
+  /* space grid support stuff */
+  int pl_next, pl_prev;		/* doubly linked list of planet numbers */
+  int pl_gridnum;		/* to hold grid square number */
+};
+
+/* defines for the pl_flags field of planet struct */
+#if 0
+#define PLHOME 	   0x000100	/* These 4 flags no longer are */
+#define PLCOUP     0x000200	/* used in the server */
+#define PLCHEAP    0x000400
+#define PLCORE     0x000800
+#define PLREPAIR   0x001010	/* planet can repair ships */
+#define PLFUEL     0x002020	/* planet has fuel depot */
+#define PLAGRI     0x004040	/* agricultural thingies built here */
+#define PLSHIPYARD 0x008000	/* planet has a shipyard on it */
+#define PLORESMASK 0x000070	/* mask for original resource flags */
+#define PLRESMASK  0x00F000	/* to mask off all but resource bits */
+#define PLRESSHIFT       12	/* bit to shift right by for resources */
+#define PLSTAR     0x010000	/* planet is actually a star */
+#define PLREDRAW   0x000080	/* Player close for redraw */
+#define PLPOISON   0x000000	/* poison atmosphere, no army growth */
+#define PLATYPE3   0x020000	/* slightly toxic, very slow army growth */
+#define PLATYPE2   0x040000	/* thin atmosphere, slow army growth */
+#define PLATYPE1   0x060000	/* normal human atmosphere, normal growth */
+#define PLATMASK   0x060000	/* to mask off everything but atmos bits */
+#define PLATSHIFT	 17	/* number of right bit shifts for atmos bits */
+#define PLBARREN   0X000000	/* rocky barren surface */
+#define PLDILYTH   0x080000	/* dilythium deposits on the planet */
+#define PLMETAL    0x100000	/* metal deposits on the planet */
+#define PLARABLE   0x200000	/* planet has farmland */
+#define PLSURMASK  0x380000	/* number of surface combinations */
+#define PLSURSHIFT 	 19	/* number of bit shift to surface */
+#define PLPARADISE 0x400000	/* Paradise server flag set to 1 for P server */
+#else
+
+/*
+ * pl_flags is an int of 32 bits:
+ * 
+ * bits 16 and 23 currently define the type of the planet.  The interpretation
+ * of the other bits is dependent upon the planet type.
+ * 
+ * Here is the interpretation for a planet bits 0..3
+ * n bits 4..6			planetary facilities (REPAIR,FUEL,AGRI) bit
+ * 7			redraw (archaic, recyclable?) bits 8..11
+ * ld flags (archaic, recyclable?) bits 12..15			paradise
+ * planetary facilities (REPAIR,FUEL,AGRI,SHIPY) bit  16
+ * osmic object type (also bit 23) bits 17,18			planet
+ * atmosphere type bits 19..21			planetary surface properties
+ * (DILYTH,METAL,ARABLE) bit  22			paradise planet flag
+ * (why?) bit  23			cosmic object type (also bit 16) bits
+ * 24..31	currently unallocated (8 bits to play with)
+ * 
+ * Asteroids are NYI but here is a draft standard: bits 12,15
+ * acilities (REPAIR,FUEL,SHIPY) bit  20			surface
+ * properties (DILYTH,METAL) other bits	currently unallocated
+ * 
+ */
+
+/*
+ * facilities, bits 4..6 and 12..15 valid for planets and asteroids
+ */
+#define PLREPAIR   ((1<<12) | (1<<4))	/* planet can repair ships */
+#define PLFUEL     ((1<<13) | (1<<5))	/* planet has fuel depot */
+#define PLAGRI     ((1<<14) | (1<<6))	/* agricultural thingies built here */
+#define PLSHIPYARD ((1<<15))	/* planet has a shipyard on it */
+#define PLORESMASK (0x7<<4)	/* mask for original resource flags */
+#define PLRESSHIFT       12	/* bit to shift right by for resources */
+#define PLRESMASK  (0xF<<PLRESSHIFT)	/* to mask off all but resource bits */
+
+#define PLREDRAW   (1<<7)	/* Player close for redraw */
+
+#define PLHOME 	   (1<< 8)	/* These 4 flags no longer are */
+#define PLCOUP     (1<< 9)	/* used in the server */
+#define PLCHEAP    (1<<10)
+#define PLCORE     (1<<11)
+
+/* cosmic object types, bits 16, 23, and 24 */
+#define PLPLANET	0	/* object is a planet */
+#define PLSTAR     (1<<16)	/* object is a star */
+#define PLAST	   (1<<23)	/* object is an asteroid NYI */
+#define PLNEB	   ((1<<16)|(1<<23))	/* object is a nebula NYI */
+#define PLBHOLE	                    (1<<24)	/* object is a black hole NYI */
+#define PLPULSAR   ((1<<16)|        (1<<24))	/* object is a pulsar NYI */
+#define PLUK1	   (        (1<<23)|(1<<24))	/* future expansion NYI */
+#define PLWHOLE	   ((1<<16)|(1<<23)|(1<<24))	/* object is a wormhole */
+#define PLTYPEMASK ((1<<16)|(1<<23)|(1<<24))	/* mask to extract object
+						 * type */
+#define PL_TYPE(p) ( (p).pl_flags & PLTYPEMASK )
+
+/*
+ * Atmosphere Types, bits 17 and 18. Valid for planets.
+ */
+#define PLATSHIFT	 17	/* number of right bit shifts for atmos bits */
+#define PLPOISON   (0<<PLATSHIFT)	/* poison atmosphere, no army growth */
+#define PLATYPE3   (1<<PLATSHIFT)	/* slightly toxic, very slow army
+					 * growth */
+#define PLATYPE2   (2<<PLATSHIFT)	/* thin atmosphere, slow army growth */
+#define PLATYPE1   (3<<PLATSHIFT)	/* normal human atmosphere, normal
+					 * growth */
+#define PLATMASK   (0x3<<PLATSHIFT)	/* to mask off everything but atmos
+					 * bits */
+
+/*
+ * Surface Properties, bits 19..21 Valid for planets and asteroids.
+ */
+#define PLBARREN   0		/* rocky barren surface */
+#define PLSURSHIFT 	 19	/* number of bit shift to surface */
+#define PLDILYTH   (1<<(PLSURSHIFT+0))	/* dilythium deposits on the planet */
+#define PLMETAL    (1<<(PLSURSHIFT+1))	/* metal deposits on the planet */
+#define PLARABLE   (1<<(PLSURSHIFT+2))	/* planet has farmland */
+#define PLSURMASK  (0x7<<PLSURSHIFT)	/* number of surface combinations */
+
+
+#define PLPARADISE (1<<22)	/* Paradise server flag set to 1 for P server */
+
+#endif
+/*-------------------------------------------------------------------------*/
+
+
+/*----------------------T E R R A I N   S T R U C T S----------------------*/
+/* Data */
+struct t_unit
+{
+  int alt1;			/* alt1, alt2 are currently unused in the
+				 * client */
+  int alt2;			/* according to MDM (5/16/95) */
+  char types;			/* modify the packet code as well if these
+				 * are put */
+};				/* back in, as well as the structs in
+				 * packets.h */
+
+/* Flags */
+#define T_EMPTY_SPACE 0x00
+#define T_ASTEROIDS   0x01
+#define T_NEBULA      0x02
+#define T_RADIATION   0x04
+#define T_EXPANSN1    0x08
+#define T_EXPANSN2    0x10
+#define T_EXPANSN3    0x20
+#define T_EXPANSN4    0x40
+#define T_EXPANSN5    0x80
+
+/*-------------------------------------------------------------------------*/
+
+
+/*-----------------------------MESSAGE STRUCTS-----------------------------*/
+
+struct message
+{
+  int m_no;			/* message number in array of messgs */
+  int m_flags;			/* flags for message type */
+  int m_time;			/* time message sent???? */
+  int m_recpt;			/* who it should be sent to */
+  char m_data[80];		/* the message string */
+  int m_from;			/* who it is from */
+};
+
+/*
+ * for m_flags field -- lower five bits used for what kind of group the
+ * message is sent to
+ */
+#define MVALID (1<<0)		/* the message is valid--has not been sent */
+#define MINDIV (1<<1)		/* sent to an individual */
+#define MTEAM  (1<<2)		/* sent to a team */
+#define MALL   (1<<3)		/* sent to eveyone */
+
+/* order these by importance (0x100 - 0x400) */
+/*
+ * many of these are not used by the client, so their incorrect value doesn't
+ * matter.  however we should note that the packet only has a width of 8 bits
+ * for the type field, and many of these flags are > 8 bits wide --eld
+ */
+
+#define	MGOD   ( 1<<4)		/* sent to god -- misc.c, socket.c */
+#define MGENO  ( 1<<5)		/* genocide message -- conquer.c */
+#define MCONQ  ( 2<<5)		/* conquer message -- planets.c */
+#define MTAKE  ( 1<<5)		/* planet taken message -- player.c */
+#define MDEST  ( 2<<5)		/* planet destroyed message -- player.c */
+#define MKILLA ( 5<<5)		/* a person killed -- dutil.c, snakemove.c */
+#define MBOMB  ( 3<<5)		/* bombarding planet -- planets.c */
+#define MKILLP ( 7<<5)		/* a person killed -- NOT USED */
+#define MKILL  ( 8<<5)		/* a person killed -- NOT USED */
+#define MLEAVE ( 9<<5)		/* player leaving game message -- main.c */
+#define MJOIN  (10<<5)		/* player joining game -- enter.c */
+#define MGHOST (11<<5)		/* player ghostbusted -- daemonII.c */
+#define MCOUP1 (12<<5)		/* a coup occured -- NOT USED */
+#define MCOUP2 (13<<5)		/* -- NOT USED */
+#define MDISTR (14<<5)		/* flag for a distress message */
+#define MMASK  (0xf<<5)		/* bits in the flags field should be sent --
+				 * 
+				/* message control structure */
+struct mctl
+{				/* used to keep track of position in */
+  int mc_current;		/* array we put our last message */
+};
+
+/*-------------------------------------------------------------------------*/
+
+
+
+struct rsa_key
+{
+  unsigned char client_type[KEY_SIZE];
+  unsigned char architecture[KEY_SIZE];
+  unsigned char global[KEY_SIZE];
+  unsigned char public[KEY_SIZE];
+};
+
+
+/*
+ * RCD stuff, from bronco server 2.7pl13.
+ */
+#ifdef RC_DISTRESS
+struct distress
+{
+  unsigned char sender;
+  unsigned char dam, shld, arms, wtmp, etmp, fuelp, sts;
+  unsigned char wtmpflag, etempflag, cloakflag, distype, macroflag, ttype;
+  unsigned char close_pl, close_en, target, tclose_pl, tclose_en, pre_app,
+      i;
+  unsigned char close_j, close_fr, tclose_j, tclose_fr;
+  unsigned char cclist[6];	/* CC list */
+  unsigned char preappend[80];	/* text which we pre- or append */
+};
+
+/*
+ * macro management
+ */
+struct dmacro_list
+{
+  char c;
+  char *name;
+  char *macro;
+};
+
+/*
+ * distress types
+ */
+enum dist_type
+{
+  /* help me do series */
+  take = 1, ogg, bomb, space_control, help1, help2, help3, help4,
+
+  /* doing series */
+  escorting, ogging, bombing, controlling, doing1, doing2, doing3, doing4,
+
+  /* other info series */
+  free_beer,			/* player x is totally hosed now */
+  no_gas,			/* player x has no gas */
+  crippled,			/* player x is crippled but may have fuel */
+  pickup,			/* player x picked up armies */
+  pop,				/* there was a pop somewhere */
+  carrying,			/* I am carrying */
+  other1, other2,
+
+  /* just a generic distress call */
+  generic
+};
+
+/*
+ * targets of messages
+ */
+enum target_type
+{
+  none,
+  planet,
+  player
+};
+
+/*
+ * from bronco server2.7pl3
+ */
+/*
+ * The General distress has format:
+ * 
+ * A 'E' will do byte1-8 inclusive. Macros can do more but haven't been
+ * implemented that way yet.
+ * 
+ * byte1: xxyzzzzz where zzzzz is dist_type, xx is target_type and y is 1 if
+ * this is a macro and not just a simple distress (a simple distress will
+ * ONLY send ship info like shields, armies, status, location, etc.)
+ * 
+ * byte2: 1fff ffff - f = percentage fuel remaining (0-100) byte3: 1ddd dddd - %
+ * damage byte4: 1sss ssss - % shields remaining byte5: 1eee eeee - % etemp
+ * byte6: 1www wwww - % wtemp byte7: 100a aaaa - armies carried byte8: (lsb
+ * of me->p_status) & 0x80 byte9: 1ppp pppp - planet closest to me byte10:
+ * 1eee eeee - enemy closest to me
+ * 
+ * Byte 11 and on are only sent if y (from byte 1) is = 1 although even for
+ * simplest case (y=0) we should send byte14+ = 0x80 and then a null so that
+ * in future we can send a cc list and pre/append text byte11: 1ttt tttt -
+ * target (either player number or planet number) byte12: 1ppp pppp - planet
+ * closest to target byte13: 1eee eeee - enemy closest to target byte14+: cc
+ * list (each player to cc this message to is 11pp ppp) cc list is terminated
+ * by 1000 0000 or 0100 0000 ) pre-pend     append byte15++: the text to pre
+ * or append .. depending on termination above. text is null terminated and
+ * the last thing in this distress
+ */
+
+#endif				/* RCD */
+
+struct command_handler
+{
+  char *command;
+  int tag;
+  char *desc;
+  int (*handler) ();
+};
+
+#ifdef VOTING
+struct vote_handler
+{
+  char *type;
+  int tag;
+  int minpass;
+  int start;
+  char *desc;
+  int frequency;
+  int (*handler) ();
+};
+
+#define VC_ALL     0x0001	/* Majority Vote */
+#define VC_TEAM    0x0002	/* Team Vote     */
+#define VC_GLOG    0x0010	/* Write Votes to God Log */
+#define VC_PLAYER  0x0020	/* Each player can be voted on, like eject */
+
+
+#endif
+
+/*-------------------------SOME CLIENT STRUCTURES--------------------------*/
+
+/* used to tell what planet or player mouse is pointing to */
+struct obtype
+{
+  int o_type;			/* mouse pointing to a player or planet */
+  int o_num;			/* the player or planet number */
+};
+
+/* used in the o_type structure */
+#define PLANETTYPE 1		/* mouse on planet */
+#define PLAYERTYPE 2		/* mouse on player */
+
+
+/* used to hold a players rank */
+struct rank
+{
+  int genocides;		/* minimum number of genocides */
+  float di;			/* minimum destruction inflicted */
+  float battle;			/* minimum battle ratings */
+  float strategy;		/* minimum strategy ratings */
+  float specship;		/* minimum total ratings in a specialty */
+  /* ship  SB + WB + JS */
+  char *name;			/* name of this rank */
+};
+
+
+struct royalty
+{
+  char *name;			/* name of rank */
+};
+
+/*-------------------------------------------------------------------------*/
+
+
+
+#endif
+
+/*---------END OF FILE---------*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/structdesc.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,159 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+
+#include "config.h"
+#include "structdesc.h"
+#include "struct.h"
+
+#define OFFSET_OF(field)	( (char*)(&((struct ship*)0)->field) -\
+ 			  (char*)0)
+
+static char *all_ship_flag_names[] = {
+  "UNDOCKABLE",
+  "CANORBIT",
+  "CANWARP",
+  "CANFUEL",
+  "CANREPAIR",
+  "CANREFIT",
+  "ARMYNEEDKILL",
+  "HASPHASERS",
+  "PLASMASTYLE",
+  "HASPLASMA",			/* obsolete */
+  "PLASMAARMED",
+  "HASMISSILE",
+  "HASFIGHTERS",
+  0
+};
+
+struct field_desc ship_fields[] = {
+  {"alttype", FT_SHORT, OFFSET_OF(s_alttype)},
+  {"name", FT_STRING, OFFSET_OF(s_name[0])},
+
+  {"turns", FT_INT, OFFSET_OF(s_turns)},
+
+  {"imp.acc", FT_INT, OFFSET_OF(s_imp.acc)},
+  {"imp.dec", FT_INT, OFFSET_OF(s_imp.dec)},
+  {"imp.cost", FT_INT, OFFSET_OF(s_imp.cost)},
+  {"imp.maxspeed", FT_INT, OFFSET_OF(s_imp.maxspeed)},
+  {"imp.etemp", FT_INT, OFFSET_OF(s_imp.etemp)},
+
+  {"after.acc", FT_INT, OFFSET_OF(s_after.acc)},
+  {"after.dec", FT_INT, OFFSET_OF(s_after.dec)},
+  {"after.cost", FT_INT, OFFSET_OF(s_after.cost)},
+  {"after.maxspeed", FT_INT, OFFSET_OF(s_after.maxspeed)},
+  {"after.etemp", FT_INT, OFFSET_OF(s_after.etemp)},
+
+  {"warp.acc", FT_INT, OFFSET_OF(s_warp.acc)},
+  {"warp.dec", FT_INT, OFFSET_OF(s_warp.dec)},
+  {"warp.cost", FT_INT, OFFSET_OF(s_warp.cost)},
+  {"warp.maxspeed", FT_INT, OFFSET_OF(s_warp.maxspeed)},
+  {"warp.etemp", FT_INT, OFFSET_OF(s_warp.etemp)},
+
+  {"warpinitcost", FT_INT, OFFSET_OF(s_warpinitcost)},
+  {"warpinittime", FT_INT, OFFSET_OF(s_warpinittime)},
+  {"warpprepspeed", FT_INT, OFFSET_OF(s_warpprepspeed)},
+
+  {"mass", FT_SHORT, OFFSET_OF(s_mass)},
+
+  {"tractstr", FT_SHORT, OFFSET_OF(s_tractstr)},
+  {"tractrng", FT_FLOAT, OFFSET_OF(s_tractrng)},
+  {"tractcost", FT_INT, OFFSET_OF(s_tractcost)},
+  {"tractetemp", FT_INT, OFFSET_OF(s_tractetemp)},
+
+  {"torp.damage", FT_SHORT, OFFSET_OF(s_torp.damage)},
+  {"torp.speed", FT_SHORT, OFFSET_OF(s_torp.speed)},
+  {"torp.cost", FT_SHORT, OFFSET_OF(s_torp.cost)},
+  {"torp.fuse", FT_SHORT, OFFSET_OF(s_torp.fuse)},
+  {"torp.wtemp", FT_SHORT, OFFSET_OF(s_torp.wtemp)},
+  {"torp.wtemp_halfarc", FT_SHORT, OFFSET_OF(s_torp.wtemp_halfarc)},
+  {"torp.wtemp_factor", FT_SHORT, OFFSET_OF(s_torp.wtemp_factor)},
+  {"torpturns", FT_SHORT, OFFSET_OF(s_torp.aux)},	/* name anomaly */
+
+  {"phaser.damage", FT_SHORT, OFFSET_OF(s_phaser.damage)},
+  {"phaser.range", FT_SHORT, OFFSET_OF(s_phaser.speed)},	/* name anomaly */
+  {"phaser.cost", FT_SHORT, OFFSET_OF(s_phaser.cost)},
+  {"phaser.fuse", FT_SHORT, OFFSET_OF(s_phaser.fuse)},
+  {"phaser.wtemp", FT_SHORT, OFFSET_OF(s_phaser.wtemp)},
+
+  {"missile.damage", FT_SHORT, OFFSET_OF(s_missile.damage)},
+  {"missile.speed", FT_SHORT, OFFSET_OF(s_missile.speed)},
+  {"missile.cost", FT_SHORT, OFFSET_OF(s_missile.cost)},
+  {"missile.fuse", FT_SHORT, OFFSET_OF(s_missile.fuse)},
+  {"missile.wtemp", FT_SHORT, OFFSET_OF(s_missile.wtemp)},
+  {"missile.count", FT_SHORT, OFFSET_OF(s_missile.count)},
+  {"missileturns", FT_SHORT, OFFSET_OF(s_missile.aux)},	/* name anomaly */
+  {"missilestored", FT_SHORT, OFFSET_OF(s_missilestored)},
+
+  {"plasma.damage", FT_SHORT, OFFSET_OF(s_plasma.damage)},
+  {"plasma.speed", FT_SHORT, OFFSET_OF(s_plasma.speed)},
+  {"plasma.cost", FT_SHORT, OFFSET_OF(s_plasma.cost)},
+  {"plasma.fuse", FT_SHORT, OFFSET_OF(s_plasma.fuse)},
+  {"plasma.wtemp", FT_SHORT, OFFSET_OF(s_plasma.wtemp)},
+  {"plasmaturns", FT_SHORT, OFFSET_OF(s_plasma.aux)},	/* name anomaly */
+
+  {"maxwpntemp", FT_INT, OFFSET_OF(s_maxwpntemp)},
+  {"wpncoolrate", FT_SHORT, OFFSET_OF(s_wpncoolrate)},
+
+  {"maxegntemp", FT_INT, OFFSET_OF(s_maxegntemp)},
+  {"egncoolrate", FT_SHORT, OFFSET_OF(s_egncoolrate)},
+
+  {"maxfuel", FT_INT, OFFSET_OF(s_maxfuel)},
+  {"recharge", FT_SHORT, OFFSET_OF(s_recharge)},
+  {"mingivefuel", FT_INT, OFFSET_OF(s_mingivefuel)},
+  {"takeonfuel", FT_INT, OFFSET_OF(s_takeonfuel)},
+
+  {"explodedamage", FT_SHORT, OFFSET_OF(s_expldam)},
+  {"fueldamage", FT_SHORT, OFFSET_OF(s_fueldam)},
+
+  {"armyperkill", FT_FLOAT, OFFSET_OF(s_armyperkill)},
+  {"maxarmies", FT_SHORT, OFFSET_OF(s_maxarmies)},
+  {"bomb", FT_INT, OFFSET_OF(s_bomb)},
+
+  {"repair", FT_SHORT, OFFSET_OF(s_repair)},
+  {"maxdamage", FT_INT, OFFSET_OF(s_maxdamage)},
+  {"maxshield", FT_INT, OFFSET_OF(s_maxshield)},
+  {"shieldcost", FT_INT, OFFSET_OF(s_shieldcost)},
+
+  {"detcost", FT_SHORT, OFFSET_OF(s_detcost)},
+  {"cloakcost", FT_SHORT, OFFSET_OF(s_cloakcost)},
+
+  {"scanrange", FT_SHORT, OFFSET_OF(s_scanrange)},
+
+  {"numports", FT_SHORT, OFFSET_OF(s_numports)},
+
+  {"letter", FT_CHAR, OFFSET_OF(s_letter)},
+  {"desig1", FT_CHAR, OFFSET_OF(s_desig1)},
+  {"desig2", FT_CHAR, OFFSET_OF(s_desig2)},
+
+  {"bitmap", FT_SHORT, OFFSET_OF(s_bitmap)},
+  {"width", FT_SHORT, OFFSET_OF(s_width)},
+  {"height", FT_SHORT, OFFSET_OF(s_height)},
+
+  {"timer", FT_INT, OFFSET_OF(s_timer)},
+  {"maxnum", FT_INT, OFFSET_OF(s_maxnum)},
+  {"rank", FT_INT, OFFSET_OF(s_rank)},
+  {"numdefn", FT_INT, OFFSET_OF(s_numdefn)},
+  {"numplan", FT_INT, OFFSET_OF(s_numplan)},
+
+  {"nflags", FT_LONGFLAGS, OFFSET_OF(s_nflags), (void *) all_ship_flag_names},
+
+  {0},
+};
+
+#undef OFFSET_OF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/structdesc.h	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,37 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+/*-------------------------------MODULE TYPES------------------------------*/
+
+enum field_type
+{
+  FT_CHAR, FT_BYTE, FT_SHORT, FT_INT, FT_LONG, FT_FLOAT, FT_STRING,
+  FT_LONGFLAGS
+};
+
+struct field_desc
+{
+  char *name;
+  enum field_type type;
+  int offset;
+  void *aux;
+};
+
+/*-------------------------------------------------------------------------*/
+
+extern struct field_desc ship_fields[];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sysdefaults.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,820 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+
+#include "config.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "getship.h"
+#include "shmem.h"
+#include "path.h"
+#include "structdesc.h"
+
+
+/*-----------------------------MODULE VARS--------------------------------*/
+
+static struct stat oldstat;	/* to hold info about file so we */
+/* can check whether it has changed */
+
+/* these might not match new designations provided in the sysdef.  Oh well */
+static char *shiptypes[NUM_TYPES] = {
+  "SC", "DD", "CA", "BB", "AS", "SB", "AT",
+  "JS", "FR", "WB", "CL", "CV", "UT", "PT"
+};
+
+
+static char *weapontypes[WP_MAX] = {"PLASMA", "TRACTOR", "MISSILE", "FIGHTER"};
+
+static char *systemtypes[SHIPS_SYSTEMS] = {
+  "PLASMA", "TRACTOR", "MISSILE", "FIGHTER", "PHOTON", "PHASER", "SHIELD",
+  "REPAIR", "CLOAK", "SCANNER", "SENSOR", "WARP", "IMPULSE", "DOCK",
+  "NAVIGATION", "COMMUNICATION",
+};
+
+/*--------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+/*-----------------------------INTERNAL FUNCTIONS-------------------------*/
+
+static void 
+load_clue_phrases()
+{
+  char *path;
+  FILE *fp;
+  int count;
+  int i;
+  char *s = cluephrase_storage;	/* damn, I'm tired of typing it */
+
+  path = build_path(CLUEPHRASEFILE);
+
+  fp = fopen(path, "r");
+  if (!fp)
+    return;
+
+  count = fread(s, 1, CLUEPHRASE_SIZE - 2, fp);
+  fclose(fp);
+
+  if (count < 0)
+  {
+    /* ACK, read fail */
+    s[0] = 0;
+  }
+  else
+  {
+    s[count] = 0;		/* two zeros terminates the clue phrase list */
+    s[count + 1] = 0;
+    for (i = 0; i < count; i++)
+      if (s[i] == '\n')
+	s[i] = 0;
+  }
+}
+
+/*------------------------------READSTRINGS-------------------------------*/
+/*
+ * This function reads in a list of strings.  An array of strings contains
+ * the name of the possible strings in the list.  If the string is read in
+ * from the file and matches one of the strings in the array, then the
+ * corresponding element in the parameter 'array' is set to 1.  All keys must
+ * be of the same length.
+ */
+
+
+#ifndef SYSV			/* HP's have a problem with this */
+extern int fprintf();
+#endif
+#ifndef	IRIX
+extern int sscanf();
+#endif
+#ifndef linux
+extern int atoi();
+#endif				/* linux */
+extern int fclose();
+
+void
+readstrings(type, string, keys, array, max)
+  char *type;			/* Used to specify the type for err messages */
+  char *string;			/* the string to parse. */
+  char **keys;			/* the array of key strings */
+  int *array;			/* the array tofill with 1's */
+  int max;			/* the size of the array */
+{
+  int i;			/* looping var */
+
+  while (*string != '\0')
+  {				/* go until end of string */
+    while ((*string == '\n') || (*string == ' ') || (*string == ',')
+	   || (*string == '\t'))
+      string++;			/* go to next char if white space */
+    if (*string == '\0')	/* if end of string found */
+      break;
+    for (i = 0; i < max; i++)
+    {				/* search through keys */
+      if (strncmp(keys[i], string, strlen(keys[i])) == 0)
+      {
+	string += strlen(keys[i]);	/* go to next key */
+	array[i] = 1;		/* set array element to 1 */
+	break;			/* found it, break out of for loop */
+      }
+    }
+    if (i == max)
+    {				/* if unknown key then */
+      fprintf(stderr, "%s type %s unknown!\n", type, string);
+      string++;			/* print error */
+    }
+  }
+}
+
+
+/* modifies flagp to return result */
+void
+read_longflags(flagp, str, names)
+  long *flagp;
+  char *str;
+  char **names;
+{
+  char buf[80];
+
+  *flagp = 0;
+
+  while (*str)
+  {
+    int i;
+    i = 0;
+    while (*str != 0 && *str != ',')
+      buf[i++] = *(str++);
+    if (*str == ',')
+      str++;
+    buf[i] = 0;
+
+    for (i = 0; names[i]; i++)
+      if (0 == strcasecmp(buf, names[i]))
+	break;
+
+    if (!names[i])
+    {
+      fprintf(stderr, "unknown flag %s\n", buf);
+      continue;
+    }
+    *flagp |= 1 << i;
+  }
+}
+
+
+/*--------------------------------SHIPDEFS---------------------------------*/
+/*
+ * This function gets all of the field values for a ship.  Each line of input
+ * for the ship fields has a single ship field on it.  The name of the ship
+ * field is followed by the value to place in that field.  The function stops
+ * when it encounters a line with "end" on it.   It places the values into
+ * the shipvals so that the next time getship is called, the new values will
+ * be used.
+ */
+
+void
+shipdefs(s, f)
+  int s;			/* ship number */
+  FILE *f;			/* file to load from */
+{
+  struct ship *currship = shipvals + s;
+  char buf[256];		/* to get a string from file */
+  char field_name[64];		/* to get name of field */
+  char value[256];		/* to get name */
+  char sdesig[64];		/* to get ship letters */
+  int len;			/* to hold length of read in string */
+  int i;			/* looping var */
+  int offset;			/* to offset into ship structure */
+
+  if ((s < 0) || (s >= NUM_TYPES))
+  {				/* invalid ship number? */
+    fprintf(stderr, "invalid ship number in .sysdef file\n");
+    return;
+  }
+  while (1)
+  {				/* loop until break */
+    if (0 == fgets(buf, sizeof(buf), f))	/* get a string of input */
+      break;			/* if end of file then break */
+    if (buf[0] == '!')
+      continue;			/* skip lines that begin with ! */
+    len = strlen(buf);
+    if (buf[len - 1] == '\n')	/* blast trailing newline */
+      buf[--len] = 0;
+    if (strncmp(buf, "end", 3) == 0)
+    {				/* if end of ship then break */
+      return;
+    }
+    if (shipvals == 0)
+      continue;
+
+    /* get field name and value */
+    sscanf(buf, "%s %s %s", sdesig, field_name, value);
+
+    for (i = 0; ship_fields[i].name; i++)
+    {				/* loop through field names */
+      if (strcmp(field_name, ship_fields[i].name) == 0 ||	/* found field? */
+	  (strncmp(field_name, "s_", 2) == 0 &&
+	   strcmp(field_name + 2, ship_fields[i].name) == 0))
+	break;
+    }
+    if (ship_fields[i].name == 0)
+    {				/* if we did not find name */
+      fprintf(stderr, "invalid field name in ship description `%s'\n",
+	      field_name);
+      continue;			/* print error, get next */
+    }
+    offset = ship_fields[i].offset;	/* get offset into struct */
+    switch (ship_fields[i].type)
+    {				/* parse the right type */
+     case FT_CHAR:
+      sscanf(value, "%c", offset + (char *) currship);
+      break;
+     case FT_SHORT:
+      sscanf(value, "%hi", (short *) (offset + (char *) currship));
+      break;
+     case FT_INT:
+      sscanf(value, "%i", (int *) (offset + (char *) currship));
+      break;
+     case FT_LONG:
+      sscanf(value, "%li", (long *) (offset + (char *) currship));
+      break;
+     case FT_FLOAT:
+      sscanf(value, "%f", (float *) (offset + (char *) currship));
+      break;
+     case FT_STRING:
+      sscanf(value, "%s", offset + (char *) currship);
+      break;
+     case FT_LONGFLAGS:
+      read_longflags((long *) (offset + (char *) currship), value,
+		     (char **) ship_fields[i].aux);
+      break;
+     default:
+      fprintf(stderr, "Internal error, unknown field type %d\n",
+	      ship_fields[i].type);
+    }
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+void
+initteamvals()
+{
+  strcpy(teams[NOBODY].nickname, "Independent");
+  strcpy(teams[NOBODY].name, "Independents");
+  teams[NOBODY].letter = 'I';
+  strcpy(teams[NOBODY].shortname, "IND");
+
+  strcpy(teams[FED].nickname, "Fed");
+  strcpy(teams[FED].name, "Federation");
+  teams[FED].letter = 'F';
+  strcpy(teams[FED].shortname, "FED");
+
+  strcpy(teams[ROM].nickname, "Romulan");
+  strcpy(teams[ROM].name, "Romulans");
+  teams[ROM].letter = 'R';
+  strcpy(teams[ROM].shortname, "ROM");
+
+  strcpy(teams[KLI].nickname, "Klingon");
+  strcpy(teams[KLI].name, "Klingons");
+  teams[KLI].letter = 'K';
+  strcpy(teams[KLI].shortname, "KLI");
+
+  strcpy(teams[ORI].nickname, "Orion");
+  strcpy(teams[ORI].name, "Orions");
+  teams[ORI].letter = 'O';
+  strcpy(teams[ORI].shortname, "ORI");
+}
+
+/*--------------------------------------------------------------------------*/
+
+
+
+#define OFFSET_OF(field)	( (char*)(&((struct configuration*)0)->field) -\
+ 			  (char*)0)
+
+static struct field_desc config_fields[] = {
+  {"TOURN", FT_INT, OFFSET_OF(tournplayers)},
+  {"TESTERS", FT_INT, OFFSET_OF(ntesters)},
+
+  {"CONFIRM", FT_BYTE, OFFSET_OF(binconfirm)},
+  {"MAXLOAD", FT_FLOAT, OFFSET_OF(maxload)},
+  {"UDP", FT_BYTE, OFFSET_OF(udpAllowed)},
+  {"MINUPDDELAY", FT_INT, OFFSET_OF(min_upd_delay)},
+  {"MINOBSUPDDELAY", FT_INT, OFFSET_OF(min_observer_upd_delay)},
+
+  {"PLKILLS", FT_FLOAT, OFFSET_OF(plkills)},
+  {"MSKILLS", FT_FLOAT, OFFSET_OF(mskills)},
+  {"EROSION", FT_FLOAT, OFFSET_OF(erosion)},
+  {"PENETRATION", FT_FLOAT, OFFSET_OF(penetration)},
+  {"NEWTURN", FT_INT, OFFSET_OF(newturn)},
+  {"HIDDEN", FT_INT, OFFSET_OF(hiddenenemy)},
+  {"PLANUPDSPD", FT_FLOAT, OFFSET_OF(planupdspd)},
+  {"GALAXYGENERATOR", FT_INT, OFFSET_OF(galaxygenerator)},
+  {"NUMWORMPAIRS", FT_INT, OFFSET_OF(num_wormpairs)},
+  {"NUMNEBULA", FT_INT, OFFSET_OF(num_nebula)},
+  {"NEBULADENSITY", FT_INT, OFFSET_OF(nebula_density)},
+  {"NEBULASUBCLOUDS", FT_INT, OFFSET_OF(nebula_subclouds)},
+  {"NUMASTEROID", FT_INT, OFFSET_OF(num_asteroid)},
+  {"ASTEROIDTHICKNESS", FT_FLOAT, OFFSET_OF(asteroid_thickness)},
+  {"ASTEROIDDENSITY", FT_INT, OFFSET_OF(asteroid_density)},
+  {"ASTEROIDRADIUS", FT_INT, OFFSET_OF(asteroid_radius)},
+  {"ASTEROIDTHICKVAR", FT_FLOAT, OFFSET_OF(asteroid_thick_variance)},
+  {"ASTEROIDDENSVAR", FT_INT, OFFSET_OF(asteroid_dens_variance)},
+  {"ASTEROIDRADVAR", FT_INT, OFFSET_OF(asteroid_rad_variance)},
+  {"POPSCHEME", FT_BYTE, OFFSET_OF(popscheme)},
+  {"POPCHOICE", FT_BYTE, OFFSET_OF(popchoice)},
+  {"POPSPEED%", FT_INT, OFFSET_OF(popspeed)},
+  {"RESOURCEBOMBING", FT_BYTE, OFFSET_OF(resource_bombing)},
+  {"REVOLTS", FT_BYTE, OFFSET_OF(revolts)},
+  {"BRONCOSHIPVALS", FT_BYTE, OFFSET_OF(bronco_shipvals)},
+  {"EVACUATION", FT_BYTE, OFFSET_OF(evacuation)},
+  {"JUSTIFY_GALAXY", FT_BYTE, OFFSET_OF(justify_galaxy)},
+  {"AFTERBURNERS", FT_BYTE, OFFSET_OF(afterburners)},
+  {"WARPDRIVE", FT_BYTE, OFFSET_OF(warpdrive)},
+  {"FUELEXPLOSIONS", FT_BYTE, OFFSET_OF(fuel_explosions)},
+  {"NEWCLOAK", FT_BYTE, OFFSET_OF(newcloak)},
+  {"BRONCORANKS", FT_BYTE, OFFSET_OF(bronco_ranks)},
+  {"NEWARMYGROWTH", FT_BYTE, OFFSET_OF(new_army_growth)},
+  {"WARPDECEL", FT_BYTE, OFFSET_OF(warpdecel)},
+  {"AFFECTSHIPTIMERSOUTSIDET", FT_BYTE, OFFSET_OF(affect_shiptimers_outside_T)},
+  {"DURABLESCOUTING", FT_BYTE, OFFSET_OF(durablescouting)},
+  {"FACILITYGROWTH", FT_BYTE, OFFSET_OF(facilitygrowth)},
+  {"FIREDURINGWARPPREP", FT_BYTE, OFFSET_OF(fireduringwarpprep)},
+  {"FIREDURINGWARP", FT_BYTE, OFFSET_OF(fireduringwarp)},
+  {"FIREWHILEDOCKED", FT_BYTE, OFFSET_OF(firewhiledocked)},
+  {"WARPPREPSTYLE", FT_BYTE, OFFSET_OF(warpprepstyle)},
+  {"BASERANKSTYLE", FT_BYTE, OFFSET_OF(baserankstyle)},
+  {"CLOAKDURINGWARPPREP", FT_BYTE, OFFSET_OF(cloakduringwarpprep)},
+  {"CLOAKWHILEWARPING", FT_BYTE, OFFSET_OF(cloakwhilewarping)},
+  {"TRACTABORTWARP", FT_BYTE, OFFSET_OF(tractabortwarp)},
+  {"ORBITDIRPROB", FT_FLOAT, OFFSET_OF(orbitdirprob)},
+  {"NEWORBITS", FT_BYTE, OFFSET_OF(neworbits)},
+  {"PLANETSINPLAY", FT_INT, OFFSET_OF(planetsinplay)},
+  {"PLANETLIMITTYPE", FT_INT, OFFSET_OF(planetlimittype)},
+  {"BEAMLASTARMIES", FT_BYTE, OFFSET_OF(beamlastarmies)},
+#ifdef LEAGUE_SUPPORT
+  {"TIMEOUTS", FT_INT, OFFSET_OF(timeouts)},
+  {"REGULATIONMINUTES", FT_INT, OFFSET_OF(regulation_minutes)},
+  {"OVERTIMEMINUTES", FT_INT, OFFSET_OF(overtime_minutes)},
+#endif
+  {"PING_PERIOD", FT_INT, OFFSET_OF(ping_period)},
+  {"PING_ILOSS_INTERVAL", FT_INT, OFFSET_OF(ping_iloss_interval)},
+  {"PING_GHOSTBUST", FT_INT, OFFSET_OF(ping_allow_ghostbust)},
+  {"PING_GHOSTBUST_INTERVAL", FT_INT, OFFSET_OF(ping_ghostbust_interval)},
+  {"CLUECHECK", FT_BYTE, OFFSET_OF(cluecheck)},
+  {"CLUEDELAY", FT_INT, OFFSET_OF(cluedelay)},
+  {"CLUETIME", FT_INT, OFFSET_OF(cluetime)},
+  {"CLUESOURCE", FT_INT, OFFSET_OF(cluesource)},
+  {"VARIABLE_WARP", FT_INT, OFFSET_OF(variable_warp)},
+  {"WARPPREP_SUSPENDABLE", FT_INT, OFFSET_OF(warpprep_suspendable)},
+  {"NOPREGAMEBEAMUP", FT_INT, OFFSET_OF(nopregamebeamup)},
+  {"GAMESTARTNUKE", FT_INT, OFFSET_OF(gamestartnuke)},
+  {"NOTTIMEOUT", FT_INT, OFFSET_OF(nottimeout)},
+  {"WARPZONE", FT_INT, OFFSET_OF(warpzone)},
+  {"HELPFULPLANETS", FT_INT, OFFSET_OF(helpfulplanets)},
+  {0}
+};
+
+#undef OFFSET_OF
+
+
+
+/*----------------------------VISIBLE FUNCTIONS----------------------------*/
+
+/*------------------------------READSYSDEFAULTS----------------------------*/
+/*
+ * This function reads in the system defaults from a file.  A number of
+ * defaults are set and if the file contains keywords with different settings
+ * then they are changed.
+ */
+
+void
+readsysdefaults()
+{
+  int i;			/* looping var */
+  FILE *f;			/* to open sysdefaults file */
+  char buf[200];		/* to get a line of text */
+  char *s;			/* to point to fields in text */
+  char *paths;			/* to hold path name of dot dir */
+
+  load_clue_phrases();
+
+  /*
+   * put default values in the configuration values for readsysdefaults() to
+   * override
+   */
+  configvals->tournplayers = 5;
+  configvals->ntesters =
+#ifdef LEAGUE_SUPPORT
+    status2->league ? 2 :
+#endif
+    12;
+
+  configvals->binconfirm = 0;
+  configvals->maxload = 100.0;
+  configvals->udpAllowed = 1;
+  configvals->min_upd_delay = 200000;	/* 5 updates/sec */
+  configvals->min_observer_upd_delay = 333000;	/* 3 updates/sec */
+
+  configvals->plkills = 2;
+  configvals->mskills = 2;	/* was 2.5, changed 5-Nov-94 by PLC */
+  configvals->erosion = 0.0;
+  configvals->penetration = 0.0;
+  configvals->newturn = 0;
+  configvals->hiddenenemy = 1;
+  configvals->planupdspd = 0;
+  configvals->justify_galaxy = 1;	/* changed 5-Nov-94 by PLC */
+
+#ifdef BRONCO
+  configvals->galaxygenerator = 4;	/* Bronco emulator */
+  configvals->resource_bombing = 0;
+  configvals->revolts = 0;
+  configvals->afterburners = 0;
+  configvals->warpdrive = 0;
+  configvals->fuel_explosions = 0;
+  configvals->bronco_shipvals = 1;
+  configvals->evacuation = 0;	/* evacuation is allowed in paradise */
+  configvals->newcloak = 0;	/* old formula is not based on speed */
+  configvals->new_army_growth = 0;	/* WAY faster than bronco in many
+					 * cases */
+  configvals->warpdecel = 0;
+  configvals->affect_shiptimers_outside_T = 0;
+
+  configvals->durablescouting = 1;
+  configvals->facilitygrowth = 0;
+  configvals->orbitdirprob = 1.0;
+  configvals->planetsinplay = 40;
+#else
+  configvals->galaxygenerator = 3;	/* Heath's galaxy generator */
+  /* changed 5-Nov-94 by PLC */
+  configvals->num_wormpairs = 0;
+  configvals->resource_bombing = 1;
+  configvals->revolts = 1;
+  configvals->afterburners = 1;
+  configvals->warpdrive = 1;
+  configvals->fuel_explosions = 1;
+  configvals->bronco_shipvals = 0;
+  configvals->evacuation = 1;	/* evacuation is allowed in paradise */
+  configvals->newcloak = 1;
+  configvals->new_army_growth = 1;	/* WAY faster than bronco in many
+					 * cases */
+  configvals->warpdecel = 0;
+  configvals->affect_shiptimers_outside_T = 0;
+
+  configvals->durablescouting = 0;
+  configvals->facilitygrowth = 1;
+  configvals->orbitdirprob = 1;	/* changed 5-Nov-94 by PLC */
+  configvals->neworbits = 1;
+  configvals->planetsinplay = 17;	/* changed 5-Nov-94 by PLC */
+  configvals->planetlimittype = 0;
+  configvals->popscheme = 1;
+  configvals->popchoice = 1;
+  configvals->popspeed = 14;	/* was 9, changed 5-Nov-94 by PLC */
+#endif
+  configvals->fireduringwarpprep = 0;
+  configvals->fireduringwarp = 0;
+  configvals->firewhiledocked = 0;
+  configvals->tractabortwarp = 0;	/* changed 5-Nov-94 by PLC */
+
+  configvals->warpprepstyle = WPS_TABORT;
+  configvals->baserankstyle = 0;
+  configvals->cloakduringwarpprep = 0;
+  configvals->cloakwhilewarping = 1;
+
+  configvals->num_nebula = 0;
+  configvals->nebula_density = 240;	/* temporily used as size */
+  configvals->nebula_subclouds = 0;
+  configvals->num_asteroid = 0;
+  configvals->asteroid_thickness = 1.0;	/* small to medium sized */
+  configvals->asteroid_radius = 12;	/* the distance from the "owning"
+					 * star */
+  configvals->asteroid_density = 60;	/* density is % chance an eligible
+					 * tgrid locale will have asteroids */
+  configvals->asteroid_thick_variance = 3.0;
+  configvals->asteroid_rad_variance = 8;
+  configvals->asteroid_dens_variance = 40;
+
+  configvals->beamlastarmies = 0;
+
+  for (i = 0; i < SHIPS_SYSTEMS; i++)
+    configvals->sun_effect[i] = (i == SS_PHOTON ||
+				 i == SS_PLASMA ||
+				 i == SS_MISSILE ||
+				 i == SS_FIGHTER);
+  for (i = 0; i < SHIPS_SYSTEMS; i++)
+    configvals->ast_effect[i] = (i == SS_PHOTON ||
+				 i == SS_PLASMA ||
+				 i == SS_MISSILE ||
+				 i == SS_FIGHTER ||
+				 i == SS_IMPULSE);
+  for (i = 0; i < SHIPS_SYSTEMS; i++)
+    configvals->neb_effect[i] = 0;
+  for (i = 0; i < SHIPS_SYSTEMS; i++)
+    configvals->wh_effect[i] = (i == SS_PHOTON ||
+				i == SS_PLASMA ||
+				i == SS_MISSILE ||
+				i == SS_FIGHTER ||
+				i == SS_WARP ||
+				i == SS_IMPULSE);
+
+  for (i = 0; i < SHIPS_SYSTEMS; i++)
+    configvals->improved_tracking[i] =
+      (
+#if 0
+    /* I recommend improved tracking for these - RF */
+       i == SS_MISSILE ||
+       i == SS_FIGHTER ||	/* except this doesn't work just yet */
+    /* fighter torps REALLY need this - MDM */
+       i == SS_PHOTON ||
+#endif
+       0);
+
+  for (i = 0; i < NUM_TYPES; i++)
+    configvals->shipsallowed[i] = (i == SCOUT ||
+				   i == DESTROYER ||
+				   i == CRUISER ||
+				   i == BATTLESHIP ||
+				   i == ASSAULT ||
+				   i == STARBASE ||
+				   i == JUMPSHIP ||
+				   i == FRIGATE ||
+				   i == WARBASE);
+  for (i = 0; i < WP_MAX; i++)
+    configvals->weaponsallowed[i] = (i == WP_PLASMA ||
+				     i == WP_TRACTOR ||
+#ifndef BRONCO
+				     i == WP_MISSILE ||
+#endif
+				     0);
+
+#ifdef LEAGUE_SUPPORT
+  configvals->timeouts = 0;	/* NYI */
+  configvals->regulation_minutes = 60;
+  configvals->overtime_minutes = 0;	/* NYI */
+  configvals->playersperteam = 8;
+#endif
+
+  configvals->nopregamebeamup = 0;
+  configvals->gamestartnuke = 0;
+  configvals->nottimeout = 0;
+
+  configvals->ping_period = 2;	/* every 2 seconds */
+  configvals->ping_iloss_interval = 10;
+  configvals->ping_allow_ghostbust = 0;
+  configvals->ping_ghostbust_interval = 10;
+
+  configvals->cluecheck = 0;	/* don't check clue */
+  configvals->cluetime = 5 * 60;/* 5 minutes */
+  configvals->cluedelay = 2 * 60 * 60;	/* 2 hours */
+  configvals->cluesource = CC_PHRASE_LIST_FILE;
+  configvals->variable_warp = 1;/* warp speed is variable [BDyess] */
+  /* changed 5-Nov-94 by PLC */
+  configvals->warpprep_suspendable = 1;	/* warp prep is suspendable [BDyess] */
+  /* changed 5-Nov-94 by PLC */
+  configvals->warpzone = 0;	/* warp zone default off [BDyess] */
+
+  configvals->plgrow.fuel = 100;
+  configvals->plgrow.agri = 350;
+  configvals->plgrow.repair = 150;
+  configvals->plgrow.shipyard = 400;
+
+  getshipdefaults();
+  initteamvals();
+
+  /* set server defaults */
+  testtime = -1;		/* not in testing mode */
+
+#ifdef LEAGUE_SUPPORT
+  if (status2->league)
+    return;			/* don't read .sysdef during league game */
+#endif
+  paths = build_path(SYSDEF_FILE);	/* cat on sysdef filename */
+  f = fopen(paths, "r");	/* attempt to open file */
+  if (f == NULL)
+  {				/* if failure to open file */
+    fprintf(stderr, "No system defaults file!\n");
+    return;			/* error message then out of here */
+  }
+  stat(paths, &oldstat);	/* record info about file */
+
+  while (fgets(buf, 199, f) != NULL)
+  {				/* read strings until end of file */
+    if (buf[0] == '!')
+      continue;			/* skip lines that begin with ! */
+    s = strchr(buf, '=');	/* find the equals sign in string */
+    if (s == NULL)		/* if no equals sign then */
+      continue;			/* go to next string */
+    *s = '\0';			/* break buf into rhs and lhs */
+    s++;
+    if (strcmp(buf, "SHIPS") == 0)
+    {				/* if ship enabling then */
+      for (i = 0; i < NUM_TYPES; i++)	/* go through ships */
+	shipsallowed[i] = 0;	/* turn off all ships */
+      readstrings("SHIPS", s, shiptypes, shipsallowed, NUM_TYPES);
+    }
+    else if (strcmp(buf, "WEAPONS") == 0)
+    {				/* if weapon enabling */
+      for (i = 0; i < WP_MAX; i++)	/* set all weapons as off */
+	weaponsallowed[i] = 0;	/* then read in weapons */
+      readstrings("WEAPONS", s, weapontypes, weaponsallowed, WP_MAX);
+    }
+    else if (strcmp(buf, "SUN_EFFECT") == 0)
+    {
+      for (i = 0; i < SHIPS_SYSTEMS; i++)
+	sun_effect[i] = 0;
+      readstrings("SUN_EFFECT", s, systemtypes, sun_effect, SHIPS_SYSTEMS);
+    }
+    else if (strcmp(buf, "ASTEROID_EFFECT") == 0)
+    {
+      for (i = 0; i < SHIPS_SYSTEMS; i++)
+	ast_effect[i] = 0;
+      readstrings("ASTEROID_EFFECT", s, systemtypes, ast_effect, SHIPS_SYSTEMS);
+    }
+    else if (strcmp(buf, "NEBULA_EFFECT") == 0)
+    {
+      for (i = 0; i < SHIPS_SYSTEMS; i++)
+	neb_effect[i] = 0;
+      readstrings("NEBULA_EFFECT", s, systemtypes, neb_effect, SHIPS_SYSTEMS);
+    }
+    else if (strcmp(buf, "WORMHOLE_EFFECT") == 0)
+    {
+      for (i = 0; i < SHIPS_SYSTEMS; i++)
+	wh_effect[i] = 0;
+      readstrings("WORMHOLE_EFFECT", s, systemtypes, wh_effect, SHIPS_SYSTEMS);
+    }
+    else if (strcmp(buf, "IMPROVED_TRACKING") == 0)
+    {
+      for (i = 0; i < SHIPS_SYSTEMS; i++)
+	improved_tracking[i] = 0;
+      readstrings("IMPROVED_TRACKING", s, systemtypes, improved_tracking, SHIPS_SYSTEMS);
+#if 0
+    }
+    else if (strcmp(buf, "PING_FREQ") == 0)
+    {
+      ping_freq = atoi(s);
+    }
+    else if (strcmp(buf, "PING_ILOSS_INTERVAL") == 0)
+    {
+      ping_iloss_interval = atoi(s);
+    }
+    else if (strcmp(buf, "PING_GHOSTBUST") == 0)
+    {
+      ping_allow_ghostbust = atoi(s);
+    }
+    else if (strcmp(buf, "PING_GHOSTBUST_INTERVAL") == 0)
+    {
+      ping_ghostbust_interval = atoi(s);
+#endif
+    }
+    else if (strcmp(buf, "SHIP") == 0)
+    {				/* if ship being entered */
+      shipdefs(atoi(s), f);
+    }
+    else if (strcmp(buf, "RELOAD_SHIPDEFAULTS") == 0)
+    {
+      getshipdefaults();
+    }
+    else
+    {
+      for (i = 0; config_fields[i].name; i++)
+      {
+	if (strcmp(buf, config_fields[i].name) == 0)
+	  break;
+      }
+      if (!config_fields[i].name)
+      {
+	fprintf(stderr, "System default %s unknown\n", buf);
+      }
+      else
+      {
+	int offset = config_fields[i].offset;
+	char *curr = (char *) configvals;
+	switch (config_fields[i].type)
+	{			/* parse the right type */
+	 case FT_BYTE:
+	  *(offset + curr) = atoi(s);
+	  break;
+	 case FT_SHORT:
+	  sscanf(s, "%hi", (short *) (offset + curr));
+	  break;
+	 case FT_INT:
+	  sscanf(s, "%i", (int *) (offset + curr));
+	  break;
+	 case FT_LONG:
+	  sscanf(s, "%li", (long *) (offset + curr));
+	  break;
+	 case FT_FLOAT:
+	  sscanf(s, "%f", (float *) (offset + curr));
+	  break;
+	 case FT_STRING:
+	  sscanf(s, "%s", offset + curr);
+	  break;
+	 case FT_LONGFLAGS:
+	  read_longflags((long *) (offset + curr), s,
+			 (char **) config_fields[i].aux);
+	  break;
+	 default:
+	  fprintf(stderr, "Internal error, unknown config field type %d\n",
+		  config_fields[i].type);
+	}
+      }
+    }
+  }
+
+  if (configvals->tournplayers < 1)	/* get number of players needed */
+    configvals->tournplayers = 5;	/* cannot set tournplayers to 0 */
+
+  if (configvals->erosion > 1)
+    configvals->erosion = 1;
+  if (configvals->penetration > 1)
+    configvals->penetration = 1;
+  if (configvals->penetration < 0)
+    configvals->penetration = 0;
+
+  if (configvals->ping_period <= 0)
+    configvals->ping_period = 1;
+  if (configvals->ping_iloss_interval <= 0)
+    configvals->ping_iloss_interval = 1;
+  if (configvals->ping_ghostbust_interval <= 0)
+    configvals->ping_ghostbust_interval = 1;
+
+  fclose(f);			/* close sysdefaults file */
+}
+
+
+
+
+/*--------------------------UPDATE_SYS_DEFAULTS---------------------------*/
+/*
+ * This function will update all of the defaults if the default file changed.
+ * It is called often, and assuming the OS caches the file inode info well,
+ * this isn't a problem. This function returns a 1 if new sysdefaults were
+ * loaded.  Otherwise a zero is returned.
+ */
+
+int
+update_sys_defaults()
+{
+  struct stat newstat;
+  static char *paths = NULL;	/* to hold full pathname */
+
+#ifdef LEAGUE_SUPPORT
+  if (status2->league)
+    return 0;			/* don't read .sysdef during league game */
+#endif
+
+  if (!paths)			/* just do the build_path once */
+    paths = strdup(build_path(SYSDEF_FILE));
+
+  if (stat(paths, &newstat) == 0)
+  {				/* get info about sysdef file */
+    if (newstat.st_ino != oldstat.st_ino ||	/* if the file has */
+	newstat.st_mtime != oldstat.st_mtime)
+    {				/* changed then */
+      readsysdefaults();	/* load new defaults and */
+
+      /*
+       * touch the motd file so the clients will re-load the sysdef screen
+       */
+      touch(build_path(MOTD));
+
+      return (1);		/* return that they were loaded */
+    }
+  }
+  return (0);			/* return 0 for no new stats */
+}
+
+/*--------------------------------------------------------------------------*/
+
+
+
+
+
+/*--------END OF FILE-------*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/terrain.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,365 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any NON-COMMERCIAL purpose (following the terms of
+the GNU General Public License (read the file 'COPYING')) and without
+fee is hereby granted, provided that this copyright notice appear in all
+copies.  No representations are made about the suitability of this
+software for any purpose.  This software is provided "as is" without
+express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+
+    Comprehensive credits are available in the file "CREDITS"
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "struct.h"
+#include "data.h"
+#include "shmem.h"
+#include "terrain.h"
+
+#define MAXALTITUDE 255
+#define MAXSTARS 20
+#define X 0
+#define Y 1
+
+void 
+generate_terrain()
+/*
+ * Generates terrain based on specs in the system configuration. Places a
+ * number of "seeds" into the terrain grid, and then generates an "altitude"
+ * map based on those seeds' positions (which correspond to star positions).
+ * Place_nebula generates another altitude map for nebulae -- the first map
+ * is used for asteroids and generating the second map.
+ * 
+ * This function is called within the galaxy generation stuff.
+ * 
+ * 10/26/94 MM
+ */
+{
+  int i, j, k;			/* counters */
+  int x, y;			/* more counters, different purpose */
+  double dist, val;		/* for distance calculations */
+  int num_seeds = 0;
+  int seed_xy[MAXSTARS][2];
+  int qx[4] = {-1, 1, -1, 1}, qy[4] = {1, 1, -1, -1};	/* quadrant multipliers */
+
+  /*
+   * place seeds -- this would be easy to change if you just had a number of
+   * seeds you wanted to place, instead of basing it on stars.  I won't
+   * bother doing it, even though it might be cool to see it work in a bronco
+   * game...  MM
+   */
+
+  for (i = 0; i < NUMPLANETS; i++)
+    if (PL_TYPE(planets[i]) == PLSTAR)
+    {
+      terrain_grid[(planets[i].pl_x / TGRID_GRANULARITY) * TGRID_SIZE +
+		   planets[i].pl_y / TGRID_GRANULARITY].alt1 = MAXALTITUDE;
+
+      seed_xy[num_seeds][X] = planets[i].pl_x / TGRID_GRANULARITY;
+      seed_xy[num_seeds][Y] = planets[i].pl_y / TGRID_GRANULARITY;
+      num_seeds++;
+    }
+
+  /* generate terrain -- simple, stupid version. */
+
+
+  for (x = 0; x < TGRID_SIZE; x++)
+    for (y = 0; y < TGRID_SIZE; y++)
+      if (terrain_grid[x * TGRID_SIZE + y].alt1 != MAXALTITUDE)
+      {
+	val = 0.0;
+	for (i = 0; i < num_seeds; i++)
+	{
+	  dist = (double) MAXALTITUDE -
+	    sqrt((double) ((x - seed_xy[i][X]) * (x - seed_xy[i][X]) +
+			   (y - seed_xy[i][Y]) * (y - seed_xy[i][Y])));
+	  if (dist > val)
+	    val = dist;
+	}
+	/* reset any previous terrain values */
+	terrain_grid[x * TGRID_SIZE + y].types = 0x00;
+
+	terrain_grid[x * TGRID_SIZE + y].alt1 = (int) val;
+	terrain_grid[x * TGRID_SIZE + y].alt2 = 0;
+      }
+
+  /* place nebula */
+  if (num_nebula)
+    place_nebula(*num_nebula, *nebula_subclouds, *nebula_density);
+  /* place asteroids */
+  if (num_asteroid)
+    place_asteroids(MAXALTITUDE - (*asteroid_radius));
+}
+
+void 
+place_nebula(int num_nebula, int num_seeds, int minalt)
+/*
+ * Values inbetween MAXALTITUDE and minalt are considered nebulous terrain.
+ * Tries to cluster seeds in groups based on num_nebula and num_seeds. ...the
+ * number of seeds per nebula being num_seeds. 10/26/94 MM
+ */
+{
+  int i = 0, j = 0, x, y, dx, dy, dist, lowdist = 2 * TGRID_SIZE;
+  int *seeds1, *seeds2;
+
+  seeds1 = (int *) malloc(num_nebula * sizeof(int));
+  if (num_seeds)
+    seeds2 = (int *) malloc(num_seeds * sizeof(int) * num_nebula);
+
+  /* find a local minimum, and place a "seed" */
+  while (i < num_nebula)
+  {
+    j = (int) lrand48() % (TGRID_SIZE * TGRID_SIZE);
+    if (j == 0)
+      j = 1;
+    while ((j < (TGRID_SIZE * TGRID_SIZE)) &&
+	   ((terrain_grid[j - 1].alt1 < terrain_grid[j].alt1) ||
+	    (terrain_grid[j + 1].alt1 < terrain_grid[j].alt1)))
+      j++;
+    seeds1[i] = j;
+    terrain_grid[seeds1[i]].alt2 = MAXALTITUDE;
+    i++;
+  }
+  /* group num_seeds more "sub seeds" around each seed */
+  /*
+   * (there are a couple bugs in this algorithm yet -- theres a wierd
+   * wraparound occasionally.  MDM, 8/23/95)
+   */
+
+  for (i = 0; i < num_nebula; i++)
+    for (j = 0; j < num_seeds; j++)
+    {
+      dx = (int) (lrand48() % ((MAXALTITUDE - minalt) * 3)) -
+	(int) (lrand48() % (int) ((MAXALTITUDE - minalt) * (1.5)));
+      dy = (int) (lrand48() % ((MAXALTITUDE - minalt) * 3)) -
+	(int) (lrand48() % (int) ((MAXALTITUDE - minalt) * (1.5)));
+      if (seeds1[i] / TGRID_SIZE + dx < 0)
+	dx -= (seeds1[i] / TGRID_SIZE + dx);
+      if (seeds1[i] / TGRID_SIZE + dx >= TGRID_SIZE)
+	dx -= (seeds1[i] / TGRID_SIZE + dx) - (TGRID_SIZE - 1);
+      if (seeds1[i] / TGRID_SIZE + dy < 0)
+	dy -= (seeds1[i] / TGRID_SIZE + dy);
+      if (seeds1[i] / TGRID_SIZE + dy >= TGRID_SIZE)
+	dy -= (seeds1[i] / TGRID_SIZE + dy) - (TGRID_SIZE - 1);
+      seeds2[i * num_seeds + j] = (seeds1[i] / TGRID_SIZE + dx) * TGRID_SIZE +
+	(seeds1[i] % TGRID_SIZE + dy);
+      terrain_grid[seeds2[i * num_seeds + j]].alt2 = MAXALTITUDE;
+    }
+
+  /*
+   * assign random-ish values, from a distance-from-seed base value (density
+   * is the randomness -- low density values are smooth, high are rough)
+   */
+  /* randomness NYI */
+  /*
+   * these values could be used in combination with the alt1 values to do
+   * other funky terrain "shapes, but I'm putting in the ABS() speedup stuff
+   * in for now anyway.  It'll result in alt2 values of 0 for any spot
+   * outside a nebulous radius -- MDM
+   */
+  for (x = 0; x < TGRID_SIZE; x++)
+    for (y = 0; y < TGRID_SIZE; y++)
+    {
+      for (i = 0; i < num_nebula; i++)
+      {
+	dx = (seeds1[i] / TGRID_SIZE) - x;
+	dy = (seeds1[i] % TGRID_SIZE) - y;
+	/* loop speedup */
+	if ((ABS(dx) <= MAXALTITUDE - minalt) &&
+	    (ABS(dy) <= MAXALTITUDE - minalt))
+	{
+	  dist = (int) sqrt(dx * dx + dy * dy);
+	  if (dist < lowdist)
+	    lowdist = dist;
+	}
+	if (num_seeds)
+	  for (j = 0; j < num_seeds; j++)
+	  {
+	    dx = seeds2[i * num_seeds + j] / TGRID_SIZE - x;
+	    dy = seeds2[i * num_seeds + j] % TGRID_SIZE - y;
+	    /* loop speedup */
+	    if ((ABS(dx) <= MAXALTITUDE - minalt) &&
+		(ABS(dy) <= MAXALTITUDE - minalt))
+	    {
+	      dist = (int) sqrt(dx * dx + dy * dy);
+	      if (dist < lowdist)
+		lowdist = dist;
+	    }
+	  }
+      }
+      terrain_grid[x * TGRID_SIZE + y].alt2 = MAXALTITUDE - lowdist;
+      lowdist = 2 * TGRID_SIZE;
+    }
+
+  /* give each spot with a high enuf alt value the nebulous terrain flag. */
+  for (i = 0; i < TGRID_SIZE; i++)
+    for (j = 0; j < TGRID_SIZE; j++)
+      if (terrain_grid[i * TGRID_SIZE + j].alt2 >= minalt)
+	terrain_grid[i * TGRID_SIZE + j].types |= T_NEBULA;
+
+  free(seeds1);
+  free(seeds2);
+}
+
+void 
+place_asteroids(int altitude)
+/*
+ * Marks terrain grid locations within density of altitude as asteroid
+ * fields.  I may make the chance of such a grid location becoming a field
+ * random (like 90% or something), so that fields will appear less uniform,
+ * and holes may exist in them.  Makes for interesting terrain, IMO. 10/26/94
+ * MM
+ */
+{
+  int x, y, i, j, numstars = 0, attempts = 0;
+  int *systems_with_asteroids;
+  int *star_numbers;
+  int *varied_rad;
+  int *varied_dens;
+  float *varied_thick;
+	
+  printf("placing asteroids\n");
+  star_numbers = (int *) malloc((NUMPLANETS) * sizeof(int));
+  for (i = 0; i < NUMPLANETS; i++)
+    if (PL_TYPE(planets[i]) == PLSTAR)
+    {
+      star_numbers[numstars] = i;
+      numstars++;
+    }
+  systems_with_asteroids = (int *) malloc(numstars * sizeof(int));
+  varied_rad = (int *) malloc(numstars * sizeof(int));
+  varied_dens = (int *) malloc(numstars * sizeof(int));
+  varied_thick = (float *) malloc(numstars * sizeof(float));
+  for (i = 0; i < numstars; i++)
+    systems_with_asteroids[i] = 0;
+	
+  /*
+   * assign what stars have asteroid belts -- I could just start with system
+   * #1, since systems are placed randomly, but I might as well pick a random
+   * system to start with.  The only prereq is that the system does NOT
+   * belong to a race. (prereq NYI)
+   */
+  if (*num_asteroid > (numstars - 4))
+    *num_asteroid = numstars - 4;
+
+  i = 0;
+  while (i < *num_asteroid)
+  {
+    j = lrand48() % numstars;
+   
+		if (((planets[j].pl_system < 1) || (planets[j].pl_system > 4))
+				&& (systems_with_asteroids[j] == 0))
+      systems_with_asteroids[j] = 1;
+		else
+			continue;
+		
+    i++;
+		
+    if ((*asteroid_rad_variance) == 0)
+      varied_rad[j] = altitude;
+    else
+      varied_rad[j] = altitude - ((*asteroid_rad_variance) / 2) +
+			lrand48() % (*asteroid_rad_variance);
+		
+    if ((*asteroid_dens_variance) == 0)
+      varied_dens[j] = *asteroid_density;
+    else
+      varied_dens[j] = (*asteroid_density) - ((*asteroid_dens_variance) / 2) +
+			lrand48() % (*asteroid_dens_variance);
+		
+    varied_thick[j] = (*asteroid_thickness) - ((*asteroid_thick_variance) / 2.0)
+		+ drand48() * (*asteroid_thick_variance);
+
+    attempts++;
+		
+    if (attempts > 1000)
+    {
+      printf("Too many attempts - giving up\n");
+      break;
+    }
+  }
+	
+	for (i = 0; i < numstars; i++)
+		if (systems_with_asteroids[i])
+			printf("System %s has an asteroid belt\n", planets[star_numbers[i]].pl_name);
+	
+	for (x = 0; x < TGRID_SIZE; x++)
+	{
+		for (y = 0; y < TGRID_SIZE; y++)
+		{
+      for (i = 0; i < numstars; i++)
+      {
+				/*
+				 * if the tgrid locale is within a certain distance of a system that
+				 * is supposed to have an asteroid belt, then, AST_CHANCE percent of
+				 * the time, mark that locale as having asteroids
+				 */
+				if (systems_with_asteroids[i] &&
+						terrain_grid[x * TGRID_SIZE + y].alt1 >= varied_rad[i] - 
+						(varied_thick[i]) && terrain_grid[x * TGRID_SIZE + y].alt1 
+						<= varied_rad[i] + (varied_thick[i]) &&	(ABS(x * TGRID_GRANULARITY - 
+																												 planets[star_numbers[i]].pl_x) <
+																										 (MAXALTITUDE - (varied_rad[i] - 
+																																		 (varied_thick[i] + 1.0)))
+																										 * TGRID_GRANULARITY) &&
+						(ABS(y * TGRID_GRANULARITY - planets[star_numbers[i]].pl_y) <
+						 (MAXALTITUDE - (varied_rad[i] - (varied_thick[i] + 1.0))) * TGRID_GRANULARITY) &&
+						lrand48() % 100 < varied_dens[i])
+				{
+					printf("terrain grid %d has asteroids\n", x * TGRID_SIZE + y);
+					terrain_grid[x * TGRID_SIZE + y].types |= T_ASTEROIDS;
+				}
+      }
+		}
+	}
+}
+
+void 
+doTerrainEffects()
+/*
+ * apply terrain effects to players
+ * 
+ * I REALLY wish I could add a "skill" element to many of the effects, but its
+ * tough. Asteroid damage is the most notable example where skill *should* be
+ * a factor, but isn't. MDM
+ */
+{
+  struct player *p;
+  int i, j, dam;
+
+  for (i = 0; i < MAXPLAYER; i++)
+  {
+    p = &(players[i]);
+    if (p->p_status != PALIVE)
+      continue;
+    if (TERRAIN_TYPE((p->p_x) / TGRID_GRANULARITY, (p->p_y) / TGRID_GRANULARITY) &
+	T_ASTEROIDS)
+    {
+      j = lrand48() % 100;
+      /* the player is in an asteroid location */
+      if (p->p_speed != 0)
+      {
+	if (ast_effect[SS_IMPULSE] &&
+	    (j < (100 - ((p->p_ship.s_turns / (p->p_speed * p->p_speed)) / 200)) ||
+	     (j < MIN_AST_HIT)))
+	{
+	  dam = lrand48() % (VAR_AST_DAMAGE * p->p_speed) + MIN_AST_DAMAGE;
+	  if (inflict_damage(0, 0, p, dam, KASTEROID) == 1)
+	    p->p_whydead = KASTEROID;
+	}
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/terrain.h	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,6 @@
+#define TERRAIN_TYPE(X,Y) terrain_grid[X*TGRID_SIZE + Y].types
+
+extern void generate_terrain();
+extern void place_nebula(int num_nebula, int num_seeds, int minalt);
+extern void place_asteroids(int altitude);
+extern void doTerrainEffects();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/timecheck.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,177 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "path.h"
+#include "config.h"
+
+
+
+/*--------------------------------DESCRIPTION-------------------------------
+  This module contains the code to see if players are allowed to play
+depending on the time of day.  This is done with a matrix that contains
+an element for each hour in each day of the week.  If the element is zero,
+access is not allow.  If it is not, then access is allowed.  The time_access
+function is called to check the time and look up the time in the access
+matrix.
+  Before the time_access function is called, the load_time_access function
+needs to be called.  This function loads the access matrix from a file.
+The format of the file is:
+udfgaergfhggdfhg		--These are three garbage lines
+sdjkhgfsadhghsdghdgh		--They are ignored
+fjishgfsdhgdfhjghdahgdtu
+SUN 0 0 0 0 1 1 1 ...		--name of day followed by 24 0's or 1's
+MON 0 1 1 1 1 ...		-- 0 = closed  1 = open
+  The time_access function checks the time access matrix to see if access
+should be allowed.  The function makes a provision for overriding the
+access matrix.  If the file OVERRIDE exists, then access is automaticly
+allowed.  If the file DENY exists then access is disallowed.  If they both
+exists then access is allowed.
+---------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+/*-------------------------------NUMBER DEFINES----------------------------*/
+#define HOURS	 "etc/conf.hours"
+#define OVERRIDE "etc/ALLOW"
+#define DENY     "etc/DENY"
+/*------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+/*-------------------------------MODULE VARIABLES--------------------------*/
+
+/*
+ * The access matrix that is looked up to see if the server is open. 0 =
+ * closed  1 = open
+ */
+int timematrix[7][24];
+
+/*-------------------------------------------------------------------------*/
+
+
+
+
+
+
+/*------------------------------VISIBLE FUNCTIONS--------------------------*/
+
+/*---------------------------------LOAD_TIME_ACCESS------------------------*/
+/*
+ * This function loads the time access matrix from the time access file. If
+ * the file cannot be opened, a warning is printed out and the access matrix
+ * is filled with 1's, allowing access at all times.
+ */
+
+
+extern int fclose();
+#ifndef IRIX
+extern int fscanf();
+extern int fprintf();
+#endif
+extern time_t time();
+
+void
+load_time_access()
+{
+  FILE *f;			/* to open time access file with */
+  char *filename;		/* to hold full path plus filename */
+  int i, j;			/* looping vars */
+
+  filename = build_path(HOURS);
+
+  if ((f = fopen(filename, "r")) != NULL)
+  {				/* file opened correctly? */
+    fgets(filename, 256, f);	/* get rid of first three lines */
+    fgets(filename, 256, f);
+    fgets(filename, 256, f);
+    for (i = 0; i < 7; i++)
+    {				/* go through each day */
+      fscanf(f, "%s", filename);/* get day name */
+      for (j = 0; j < 24; j++)	/* go through each hour */
+	fscanf(f, "%d", &(timematrix[i][j]));	/* get access for that hour */
+    }
+    fclose(f);			/* clsoe time access file */
+  }
+  else
+  {				/* else no timecheck file */
+    fprintf(stderr, "Warning, no .hours file found.");
+    fprintf(stderr, "  Allowing access at all hours, all days.\n");
+    for (i = 0; i < 7; i++)	/* go through all days */
+      for (j = 0; j < 24; j++)	/* go through all hours */
+	timematrix[i][j] = 1;	/* set access okay at this day,hour */
+  }
+}
+
+
+
+
+/*---------------------------------TIME_ACCESS-----------------------------*/
+/*
+ * This function checks to see if the server is open.  It returns a 1 if the
+ * server is open at the current time of day and day of the week.  It returns
+ * a 0 otherwise.
+ */
+
+int
+time_access()
+{
+  struct tm *tm;		/* points to structure containing local time */
+  time_t secs;			/* to get number of seconds */
+  FILE *fd;			/* to open override file with */
+  char *filename;		/* to hold full path and filename */
+
+  filename = build_path(OVERRIDE);
+  if ((fd = fopen(filename, "r")) != NULL)
+  {				/* if override open file */
+    fclose(fd);			/* exists then */
+    return 1;			/* return server is open */
+  }
+  filename = build_path(DENY);
+  if ((fd = fopen(filename, "r")) != NULL)
+  {				/* if override close file */
+    fclose(fd);			/* exists then */
+    return 0;			/* return server is closed */
+  }
+  time(&secs);			/* get calendar time */
+  tm = localtime(&secs);	/* convert it to local time */
+  return (timematrix[tm->tm_wday][tm->tm_hour]);	/* check time access
+							 * matrix */
+}
+
+/*------------------------------------------------------------------------*/
+
+
+
+
+
+/*--------END OF FILE----------*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-ds.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,352 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+#include "shmem.h"
+#include "structdesc.h"
+#include "data.h"
+
+/* ----------------[ prototypes because I like main first ]---------------- */
+void dump_ship_sysdef(void);
+void dump_ship_Ccode(void);
+void dump_ships_to_table(void);
+void describe_ship(int ship);
+void usage(char name[]);
+
+/* --[ rather than duplicate it 3 times make the macro from hell (shrug) ]-- */
+#define Print_value(place) { \
+    switch (ship_fields[place].type) { \
+        case FT_CHAR: \
+            printf("%c", *(char *) temp); \
+            break; \
+        case FT_SHORT: \
+            printf("%d", *(short *) temp); \
+            break; \
+        case FT_INT: \
+            printf("%d", *(int *) temp); \
+            break; \
+        case FT_LONG: \
+            printf("%ld", *(long *) temp); \
+            break; \
+        case FT_FLOAT: \
+            printf("%g", *(float *) temp); \
+            break; \
+        case FT_STRING: \
+            printf("%s", (char *) temp); \
+            break; \
+        case FT_LONGFLAGS: \
+            { \
+                int     zz = 0; \
+                char  **names = (char **) ship_fields[place].aux; \
+                long    flag = *(long *) temp; \
+                int     first = 1; \
+                for (zz = 0; names[zz]; zz++) { \
+                    if (flag & (1 << zz)) { \
+                        printf("%s%s", first ? "" : ",", names[zz]); \
+                        first = 0; \
+                    } \
+                } \
+            } \
+            break; \
+        default: \
+            printf("unknown type"); \
+            break; \
+    } \
+}
+
+char *shipTYPES[] = {
+  "SCOUT",
+  "DESTROYER",
+  "CRUISER",
+  "BATTLESHIP",
+  "ASSAULT",
+  "STARBASE",
+  "ATT",
+  "JUMPSHIP",
+  "FRIGATE",
+  "WARBASE",
+  "LIGHTCRUISER",
+  "CARRIER"
+};
+
+struct nflags_desc_
+{
+  int flag;
+  char *meaning;
+}   nflags_desc[] =
+{
+  {
+    SFNUNDOCKABLE, "can not dock with another ship"
+  },
+  {
+    SFNCANORBIT, "can orbit hostile worlds"
+  },
+  {
+    SFNCANWARP, "has warp engines"
+  },
+  {
+    SFNCANFUEL, "can transfer fuel to docked ships"
+  },
+  {
+    SFNCANREPAIR, "can speed repair of docked ships"
+  },
+  {
+    SFNCANREFIT, "can let docked ships refit"
+  },
+  {
+    SFNARMYNEEDKILL, "needs kills to carry armies"
+  },
+  {
+    SFNHASPHASERS, "is armed with phasers"
+  },
+  {
+    SFNPLASMASTYLE, "360 arc of fire for plasmas"
+  },
+  {
+    SFNPLASMAARMED, "is armed with plasmas by default"
+  },
+  {
+    SFNHASMISSILE, "is armed with missiles by default"
+  },
+  {
+    SFNHASFIGHTERS, "has a fighter bay"
+  },
+  {
+    0, 0
+  }
+};
+
+/* ==============================[ Functions ]============================== */
+
+int 
+main(int argc, char **argv)
+{
+  int i, droutine = 0;
+  char *name;
+
+  name = *argv++;
+  argc--;
+
+  if (argc != 1)
+    usage(name);
+
+  while (*argv)
+  {
+    if (**argv == '-')
+      ++* argv;
+    else
+      break;
+    switch (**argv)
+    {
+     case 's':			/* sysdef */
+      droutine = 1;
+      break;
+     case 'c':			/* C Code */
+      droutine = 2;
+      break;
+     case 't':			/* table */
+      droutine = 3;
+      break;
+     case 'v':			/* verbose */
+      droutine = 4;
+      break;
+     default:
+      printf("!  %s: Unknown option '-%c'\n", name, **argv);
+      usage(name);
+    }
+  }
+
+  /* start up a daemon if we need to */
+  openmem(1, 0);
+
+  /*
+   * do this with two switches because we don't want to fire up the daemon if
+   * we don't need to
+   */
+  switch (droutine)
+  {
+   case 1:			/* Sysdef */
+    dump_ship_sysdef();
+    break;
+   case 2:			/* C Code */
+    dump_ship_Ccode();
+    break;
+   case 3:			/* Table */
+    dump_ships_to_table();
+    break;
+   case 4:
+    {				/* Verbose */
+      ++*argv;
+      if (!**argv)
+      {
+	for (i = 0; i < NUM_TYPES; i++)
+	  describe_ship(i);
+      }
+      else
+      {
+	describe_ship(atoi(*argv));
+      }
+      break;			/* for old times sake */
+    }				/* case 4 (Braces on this one because it
+				 * looks nice, thats all */
+  }				/* switch */
+}
+
+/* ------------------[ Print ship stats in sysdef format ]------------------ */
+void 
+dump_ship_sysdef(void)
+{
+  int j, i;
+
+  for (i = 0; i < NUM_TYPES; i++)
+  {
+    struct ship *shp = &shipvals[i];
+    printf("SHIP=%d\n", i);
+    for (j = 0; ship_fields[j].name; j++)
+    {
+      void *temp = ship_fields[j].offset + (char *) shp;
+
+      printf("%c%c %-24s",
+	     shp->s_desig1, shp->s_desig2, ship_fields[j].name);
+      Print_value(j);
+      printf("\n");
+    }
+    printf("end\n");
+  }
+}
+
+/* ----------------[ Print ship stats in a C syntax format ]---------------- */
+void 
+dump_ship_Ccode(void)
+{
+  int j, i;
+
+  for (i = 0; i < NUM_TYPES; i++)
+  {
+    struct ship *shp = &shipvals[i];
+    printf("  /* comprehensive definition of %s */\n", shipTYPES[i]);
+    for (j = 0; ship_fields[j].name; j++)
+    {
+      void *temp = ship_fields[j].offset + (char *) shp;
+
+      if (ship_fields[j].type == FT_STRING)
+      {
+	printf("  strcpy(shipvals[%s].s_%s, \"%s\")", shipTYPES[i],
+	       ship_fields[j].name, (char *) temp);
+      }
+      else
+      {
+	printf("  shipvals[%s].s_%s = ",
+	       shipTYPES[i], ship_fields[j].name);
+	Print_value(j);
+      }
+      printf(";\n");
+    }
+    printf("\n");
+  }
+}
+
+/* -----------------[ Print ship stats in a table format ]----------------- */
+void 
+dump_ships_to_table(void)
+{
+  int x, j, i;
+
+  /*
+   * we have to find the max element of the ship fields, this is the only way
+   * I know of so far (BG)
+   */
+
+  printf("Ship Statistics:\n");
+  for (i = 0; ship_fields[i].name; i++)
+  {
+    printf("%-13s ", ship_fields[i].name);
+    for (j = 0; j < NUM_TYPES; j++)
+    {
+      struct ship *shp = &shipvals[j];
+      void *temp = (ship_fields[i].offset + (char *) shp);
+
+      /* we do this one differently so don't use Print_value() */
+      switch (ship_fields[i].type)
+      {
+       case FT_CHAR:
+	printf("%6c ", *(char *) temp);
+	break;
+       case FT_SHORT:
+	printf("%6d ", *(short *) temp);
+	break;
+       case FT_INT:
+	printf("%6d ", *(int *) temp);
+	break;
+       case FT_LONG:
+	printf("%6ld ", *(long *) temp);
+	break;
+       case FT_FLOAT:
+	printf("%6g ", *(float *) temp);
+	break;
+       case FT_STRING:
+	printf("%6s ", (char *) temp);
+	break;
+       default:
+	break;
+      }
+    }
+    printf("\n");
+  }
+}
+
+
+/* -------------------------[ Verbose description ]------------------------- */
+void 
+describe_ship(int s_no)
+{
+  struct ship *sp = &shipvals[s_no];
+  int i;
+
+  printf("The %s\n", sp->s_name);
+  for (i = 0; nflags_desc[i].flag; i++)
+  {
+    if ((sp->s_nflags & nflags_desc[i].flag) != nflags_desc[i].flag)
+      continue;
+    printf("\t%s\n", nflags_desc[i].meaning);
+  }
+}
+
+
+/* ----------------------------[ Prints usage ]---------------------------- */
+void 
+usage(char name[])
+{
+  int x;
+
+  char errmsg[][255] = {
+    "\n\t'%s <format option>'\n\n",
+    "This tool will dump all ship values, configurable to 3 formats:\n",
+    "\t-s     -- .sysdef Format\n",
+    "\t-c     -- C code Format\n",
+    "\t-t     -- Table Format (best printed with 8 point font)\n",
+    "\t-v#    -- Verbose Format (optional ship number)\n",
+    ""
+  };
+
+  printf("-- NetrekII (Paradise), %s --\n", PARAVERS);
+  for (x = 0; *errmsg[x] != NULL; x++)
+    printf(errmsg[x], name);
+
+  exit(1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-heraldry.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,100 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+/*
+ * Robert Forsman
+ * 
+ * Scans the score file for royalty.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <pwd.h>
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+
+
+struct person
+{
+  int royal;
+  char name[16];
+  struct person *next;
+};
+
+int 
+compare_people(a, b)
+  struct person *a, *b;
+{
+  if (a->royal > b->royal)
+    return 1;
+  else
+    return -1;
+}
+
+int
+main(argc, argv)
+  int argc;
+  char **argv;
+{
+  struct statentry plstats;
+  struct person *head = 0;
+  int royalty;
+
+  printf("Reading players file from stdin...");
+  while (1 == fread(&plstats, sizeof(plstats), 1, stdin))
+  {
+    if (plstats.stats.st_royal > 0)
+    {
+      /* royalty!  insert into linked list. */
+      struct person **scan;
+      struct person *dude;
+      dude = (struct person *) malloc(sizeof(*dude));
+      dude->royal = plstats.stats.st_royal;
+      strncpy(dude->name, plstats.name, sizeof(dude->name));
+      for (scan = &head;
+	   *scan && 0 > compare_people(dude, *scan);
+	   scan = &(*scan)->next)
+	;
+      dude->next = *scan;
+      *scan = dude;
+    }
+  }
+  printf("done.\n");
+
+
+  royalty = -1;
+  while (head)
+  {
+    struct person *temp;
+    if (royalty != head->royal)
+    {
+      royalty = head->royal;
+      printf("%s:\n", royal[royalty].name);
+    }
+    printf("  %s\n", head->name);
+    temp = head;
+    head = head->next;
+    free(temp);
+  }
+
+  exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-hr.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,222 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "defs.h"
+#include "data.h"
+#include "struct.h"
+#include "shmem.h"
+#include "path.h"
+
+#ifdef sparc
+extern char *sys_errlist[];
+#define strerror(EN)	sys_errlist[(EN)]
+#endif
+
+#define LINESPERPAGE 38
+
+struct statentry *database;
+struct statentry **playertab;
+int topn, motd = 0;
+
+void header();
+
+void
+printUsage(me)
+  char *me;
+{
+  int x;
+  char message[][255] = {
+    "\nHonor Roll of players in the current database.\n",
+    "\n\t'%s n [options]'\n\n",
+    "Where n is the number of scores to print (top n)\n",
+    "\nOptions:\n",
+    "\t-f file   Use \"file\" as player file (default: $NETREKDIR/etc/db.players)\n",
+    "\t-m        Format output for use in server MOTD\n\n",
+    ""
+  };
+
+  fprintf(stderr, "--- Netrek II (Paradise), %s ---\n", PARAVERS);
+  for (x = 0; *message[x] != '\0'; x++)
+    fprintf(stderr, message[x], me);
+
+  exit(1);
+}
+
+int
+cmp_func(a, b)
+  struct statentry **a, **b;
+{
+  float di_diff = (*a)->stats.st_di - (*b)->stats.st_di;
+  int rk_diff = (*a)->stats.st_rank - (*b)->stats.st_rank;
+
+  /* rank takes precedent over DI */
+  if (rk_diff < 0)
+    return 1;
+  else if (rk_diff > 0)
+    return -1;
+
+  if (di_diff < 0)
+    return 1;
+  else if (di_diff > 0)
+    return -1;
+
+  return strcmp((*a)->name, (*b)->name);
+}
+
+#if 0
+static char *rankh[] = {
+  "Recruits:",
+  "Specialists:",
+  "Cadets:",
+  "Midshipmen:",
+  "Ensigns, Junior Grade:",
+  "Ensigns:",
+  "Lieutenants, Junior Grade:",
+  "Lieutenants:",
+  "Lieutenant Commanders:",
+  "Commanders:",
+  "Captains:",
+  "Fleet Captains:",
+  "Commodores:",
+  "Moffs:",
+  "Grand Moffs:",
+  "Rear Admirals:",
+  "Admirals:",
+  "Grand Admirals:",
+};
+#endif
+
+int
+main(argc, argv)
+  int argc;
+  char *argv[];
+{
+  int i, nplayers, j, count = 0;
+  FILE *fp;
+  struct stat fstats;
+  char *fn;
+  struct stats *s;
+
+  if (argc < 2)
+    printUsage(argv[0]);
+
+  if (!(topn = atoi(argv[1])))
+    printUsage(argv[0]);
+
+  fn = build_path(PLAYERFILE);
+
+  for (i = 2; i < argc; i++)
+  {
+    if (!strcmp(argv[i], "-f"))
+    {
+      if (i + 1 == argc)
+	printUsage(argv[0]);
+      fn = argv[++i];
+    }
+    else if (!strcmp(argv[i], "-m"))
+    {
+      motd = 1;
+    }
+  }
+
+  if (!(fp = fopen(fn, "r")))
+  {
+    fprintf(stderr, "Couldn't open file %s: %s\n", fn, strerror(errno));
+    exit(1);
+  }
+
+  if (fstat(fileno(fp), &fstats) < 0)
+  {
+    fprintf(stderr, "Couldn't fstat file %s: %s\n", fn, strerror(errno));
+    exit(1);
+  }
+
+  nplayers = fstats.st_size / sizeof(*database);
+  database = malloc(sizeof(*database) * nplayers);
+
+  i = fread(database, sizeof(*database), nplayers, fp);
+  if (i != nplayers)
+  {
+    fprintf(stderr, "failed to read all player records from file %s (%d of %d)\n", fn, i, nplayers);
+    nplayers = i;
+  }
+
+  fclose(fp);
+
+  if (topn < 0 || topn > nplayers)
+    topn = nplayers;
+
+  /* Make an array of pointers to the database. */
+  playertab = malloc(sizeof(playertab) * nplayers);
+
+  for (i = 0; i < nplayers; i++)
+    playertab[i] = &(database[i]);
+
+  /* sort the pointers */
+  qsort(playertab, nplayers, sizeof(playertab), cmp_func);
+
+  header();
+  count = 1;
+
+  j = 18;
+  for (i = 0; i < topn; i++)
+  {
+    s = &(playertab[i]->stats);
+    if (j > s->st_rank)
+    {
+      j = s->st_rank;
+      if (motd)
+      {
+	count += 2;
+	if (count >= LINESPERPAGE)
+	{
+	  header();
+	  count = 3;
+	}
+      }
+      printf("\n%s\n", ranks[j].name);
+    }
+    if (motd && (++count > LINESPERPAGE))
+    {
+      header();
+      printf("\n");
+      count = 3;
+    }
+    printf("%4d. %15s %8.2f %6d %6d %6d  %4d  %5d %5d %7.2f\n", i + 1,
+	   playertab[i]->name, s->st_di, s->st_tkills, s->st_tlosses,
+	   s->st_tarmsbomb, s->st_tresbomb, s->st_tplanets,
+	   s->st_tdooshes, (float) (s->st_tticks / 36000.0));
+  }
+  exit(1);
+}
+
+void
+header()
+{
+  if (motd)
+    printf("\t@@b\n");
+  printf("TOP %-4d         Name     DI     Wins  Losses Armies Rsrcs  Plnts  Dshs  Hours\n", topn);
+  printf("-------------------------------------------------------------------------------");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-hs.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,559 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+/*
+ * This is probably broken in anything but the default config
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "struct.h"
+#include "data.h"
+
+int topn = 1;
+char name[40] = "";		/* if we want stats for a particular name */
+int nplayers;
+struct statentry *database;
+
+struct highscore
+{
+  char name[32];
+  int di, tkills, tlosses, tarmsbomb, tresbomb, tdooshes, tplanets;
+  int ticks;
+  struct highscore *next;
+};
+
+struct highscore *scores;
+int scoresize, nscores;
+
+void
+subbrag(name, stuff, time, title, descr, num)
+  char *name;
+  int stuff, time;
+  char *title;
+  char *descr;
+  int num;
+{
+  char full[64];
+  char line[80];
+  int len, tlen;
+  int i;
+  double rate;
+
+  if (title)
+  {
+    sprintf(full, "%s: %s", title, name);
+
+    len = strlen(full);
+    tlen = title ? strlen(title) : 0;
+
+    for (i = len; i - tlen < 10; i++)
+      full[i] = ' ';
+    full[i] = 0;
+  }
+  else
+  {
+    strcpy(full, name);
+  }
+
+  if (topn != 1)
+    sprintf(line, "%15s %3d over ", full, stuff);
+  else
+    sprintf(line, "%-30s (%2d) %3d %s, over ", full, num, stuff, descr);
+
+  if (time / 10.0 > 3600)
+    sprintf(line, "%s%1.2f hours ", line, time / 36000.0);
+  else
+    sprintf(line, "%s%1.2f minutes ", line, time / 600.0);
+
+  if (topn == 1)
+    sprintf(line, "%s\n%40s", line, "");
+
+  rate = stuff / (time / 600.0);
+
+  if (rate < 1)
+  {
+    printf(line);
+    printf("(%1.2f minutes per)\n", 1 / rate);
+  }
+  else if (rate > 60)
+  {
+    printf(line);
+    printf("(%1.2f per hour)\n", rate / 60);
+  }
+  else
+  {
+    printf(line);
+    printf("(%1.2f per minute)\n", rate);
+  }
+}
+
+void
+brag(title, descr, offset)
+  char *title, *descr;
+{
+  int i;
+  if (name[0] != 0)
+  {
+    for (i = 0; i < nscores; i++)
+    {
+      if (0 == strcmp(scores[i].name, name))
+      {
+	printf("#%5d: ", i + 1);
+	subbrag("", *(int *) (offset + (char *) &scores[i]),
+		scores[i].ticks, title, descr, i);
+	break;
+      }
+    }
+  }
+  else
+  {
+    if (topn != 1)
+      printf("\n%s (%s)\n", title, descr);
+    for (i = 0; i < topn && i < nscores; i++)
+    {
+      printf("%10s", "");
+      subbrag(scores[i].name, *(int *) (offset + (char *) &scores[i]),
+	      scores[i].ticks, topn == 1 ? title : (char *) 0, descr, i);
+    }
+  }
+}
+
+#if __STDC__
+#define COMPUTE(STN) \
+    do { \
+      currscore->STN = currplayer.stats.st_ ## STN - \
+	   prevplayer->stats.st_ ## STN; \
+    } while (0)
+
+
+#define COMPARE(STN) \
+int cmp_raw ## STN(a,b) \
+     struct highscore *a, *b; \
+{ \
+  int	diff = a->STN - b->STN; \
+ \
+  if (diff<0) \
+    return 1; \
+  else if (diff==0) \
+    return 0; \
+  else \
+    return -1; \
+} \
+ \
+int cmp_per ## STN(a,b) \
+     struct highscore *a, *b; \
+{ \
+  double	diff = a->STN/(double)a->ticks - b->STN/(double)b->ticks; \
+ \
+  if (diff<0) \
+    return 1; \
+  else if (diff==0) \
+    return 0; \
+  else \
+    return -1; \
+}
+#else
+#define COMPUTE(STN) \
+    do { \
+      currscore->STN = currplayer.stats.st_/**/STN - \
+	   prevplayer->stats.st_/**/STN; \
+    } while (0)
+
+
+#define COMPARE(STN) \
+int cmp_raw/**/STN(a,b) \
+     struct highscore *a, *b; \
+{ \
+  int	diff = a->STN - b->STN; \
+ \
+  if (diff<0) \
+    return 1; \
+  else if (diff==0) \
+    return 0; \
+  else \
+    return -1; \
+} \
+ \
+int cmp_per/**/STN(a,b) \
+     struct highscore *a, *b; \
+{ \
+  double	diff = a->STN/(double)a->ticks - b->STN/(double)b->ticks; \
+ \
+  if (diff<0) \
+    return 1; \
+  else if (diff==0) \
+    return 0; \
+  else \
+    return -1; \
+}
+#endif
+
+COMPARE(di)
+COMPARE(tkills)
+COMPARE(tlosses)
+COMPARE(tarmsbomb)
+COMPARE(tresbomb)
+COMPARE(tdooshes)
+COMPARE(tplanets)
+  int cmp_ticks(a, b)
+  struct highscore *a, *b;
+{
+  int diff = a->ticks - b->ticks;
+
+  if (diff < 0)
+    return 1;
+  else if (diff == 0)
+    return 0;
+  else
+    return -1;
+}
+
+struct statentry zeroplayer;
+
+int
+different(one, two)
+  struct highscore *one, *two;
+{
+  return 0 != strcmp(one->name, two->name);
+}
+
+double atof();
+
+int
+main(argc, argv)
+  int argc;
+  char **argv;
+{
+  struct stat fstats;
+  FILE *fp;
+  int i;
+  int code = 0;
+  struct statentry currplayer;
+  char **av;
+  int usage = 0;
+  float mintime = 30.0;
+
+  for (av = &argv[1]; *av && (*av)[0] == '-'; av++)
+  {
+    if (0 == strcmp(*av, "-n") && av[1])
+    {
+      topn = atoi(*++av);
+    }
+    else if (0 == strcmp(*av, "-c") && av[1])
+    {
+      code = atoi(*++av);
+    }
+    else if (0 == strcmp(*av, "-name") && av[1])
+    {
+      strcpy(name, *++av);
+    }
+    else if (0 == strcmp(*av, "-time") && av[1])
+    {
+      mintime = atof(*++av);
+    }
+    else
+    {
+      usage = 1;
+      break;
+    }
+  }
+  if (argc - (av - argv) != 2)
+  {
+    usage = 1;
+  }
+
+  if (usage)
+  {
+    int x;
+    char message[][255] = {
+      "\nHigh Scores, created by comparing two databases.\n",
+      "\n\t'%s -n <num> -c <num> [-name <name>] <old db> <new db>'\n\n",
+      "Options:\n",
+      "\t-n num        How many high scores to print\n",
+      "\t-c num        Which category (0 is all, max available is 15)\n",
+      "\t-name string  print ranking for a particular player\n",
+      "\nExample:\t'%s -n 5 -c 1 .players.bak .players'\n\n",
+      "\0"
+    };
+
+    fprintf(stderr, "--- %s ---\n", PARAVERS);
+    for (x = 0; *message[x] != '\0'; x++)
+      fprintf(stderr, message[x], argv[0]);
+
+    exit(1);
+  }
+
+  fp = fopen(av[0], "r");
+  if (fp == 0)
+  {
+    fprintf(stderr, "Couldn't open file %s for read", av[0]);
+    perror("");
+    exit(1);
+  }
+
+  if (fstat(fileno(fp), &fstats) < 0)
+  {
+    fprintf(stderr, "Couldn't fstat file %s", av[0]);
+    perror("");
+    exit(1);
+  }
+
+  nplayers = fstats.st_size / sizeof(*database);
+  database = (struct statentry *) malloc(sizeof(*database) * nplayers);
+
+  i = fread(database, sizeof(*database), nplayers, fp);
+
+  if (i == 0)
+  {
+    fprintf(stderr, "failed to read any player records from file %s\n", av[0]);
+    exit(1);
+  }
+  if (i != nplayers)
+  {
+    fprintf(stderr, "failed to read all player records from file %s (%d of %d)\n", av[0], i, nplayers);
+    nplayers = i;
+  }
+
+  fclose(fp);
+
+  fp = fopen(av[1], "r");
+  if (fp == 0)
+  {
+    fprintf(stderr, "Couldn't open file %s for read", av[1]);
+    perror("");
+    exit(1);
+  }
+
+
+  scores = (struct highscore *) malloc(sizeof(*scores) * (scoresize = 256));
+  nscores = 0;
+
+  while (1)
+  {
+    int delta;
+    int dt;
+    struct statentry *prevplayer;
+    struct highscore *currscore;
+
+    i = fread(&currplayer, sizeof(currplayer), 1, fp);
+    if (i < 0)
+    {
+      fprintf(stderr, "error reading player record, aborting loop\n");
+      perror("");
+    }
+    if (i <= 0)
+      break;
+
+    for (i = 0; i < nplayers; i++)
+    {
+      if (0 == strcmp(database[i].name, currplayer.name))
+	break;
+    }
+    if (i < nplayers)
+      prevplayer = &database[i];
+    else
+      prevplayer = &zeroplayer;
+
+    dt = currplayer.stats.st_tticks - prevplayer->stats.st_tticks;
+
+    if (dt < mintime /* minutes */ * 60 * 10)
+      continue;
+
+    if (nscores >= scoresize)
+    {
+      scores = (struct highscore *) realloc(scores, sizeof(*scores) * (scoresize *= 2));
+    }
+    currscore = &scores[nscores++];
+    strcpy(currscore->name, currplayer.name);
+    currscore->ticks = dt;
+
+    COMPUTE(di);
+    COMPUTE(tkills);
+    COMPUTE(tlosses);
+    COMPUTE(tarmsbomb);
+    COMPUTE(tresbomb);
+    COMPUTE(tdooshes);
+    COMPUTE(tplanets);
+  }
+
+
+#define offset(field) ( (int)&(((struct highscore*)0)->field) )
+
+  if (!code || code == 1)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_rawdi);
+    brag("Lord of Destruction", "most destruction inflicted", offset(di));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 2)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_perdi);
+    brag("BlitzMeister", "fastest destruction inflicted", offset(di));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 3)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_rawtkills);
+    brag("Hitler", "most opponents defeated", offset(tkills));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 4)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_pertkills);
+    brag("Terminator", "fastest opponents defeated", offset(tkills));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 5)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_rawtlosses);
+    brag("Kamikaze", "most times down in flames", offset(tlosses));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 6)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_pertlosses);
+    brag("Speed Kamikaze", "fastest times down in flames", offset(tlosses));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 7)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_rawtarmsbomb);
+    brag("Carpet Bomber", "most armies bombed", offset(tarmsbomb));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 8)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_pertarmsbomb);
+    brag("NukeMeister", "fastest armies bombed", offset(tarmsbomb));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 9)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_rawtresbomb);
+    brag("Terrorist", "most resources leveled", offset(tresbomb));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 10)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_pertresbomb);
+    brag("Democrat", "fastest resources leveled", offset(tresbomb));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 11)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_rawtdooshes);
+    brag("Executioner", "most armies dooshed", offset(tdooshes));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 12)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_pertdooshes);
+    brag("DooshMeister", "fastest armies dooshed", offset(tdooshes));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 13)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_rawtplanets);
+    brag("Diplomat", "most planets taken", offset(tplanets));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 14)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_pertplanets);
+    brag("speed Diplomat", "fastest planets taken", offset(tplanets));
+  }
+
+  if (!code && topn > 5)
+    printf("\t@@b\n");
+
+  if (!code || code == 15)
+  {
+    qsort(scores, nscores, sizeof(*scores), cmp_ticks);
+    if (name[0] != 0)
+    {
+      for (i = 0; i < nscores; i++)
+      {
+	if (0 == strcmp(scores[i].name, name))
+	{
+	  printf("#%5d:%30s with %1.2f hours\n", i + 1, scores[i].name,
+		 scores[i].ticks / 36000.0);
+	  break;
+	}
+      }
+    }
+    else if (topn > 1)
+    {
+      int i;
+      printf("Addicts:\n");
+      for (i = 0; i < topn && i < nscores; i++)
+      {
+	printf("%30s with %1.2f hours\n", scores[i].name, scores[i].ticks / 36000.0);
+      }
+    }
+    else
+    {
+      printf("Addict: %s with %1.2f hours\n", scores[0].name, scores[0].ticks / 36000.0);
+    }
+  }
+
+  exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-mes.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,210 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+
+#include "config.h"
+
+#include <stdio.h>
+#include "defs.h"
+#include "data.h"
+#include "shmem.h"
+
+void 
+usage(char name[])
+{
+  char *message[255] = {
+    "\nSend messages (accepted from stdin).\n",
+    "\n\t'%s <recipient> [options]'\n\n",
+    "Recipients can be:\n",
+    "\ta number from 0-9 or a letter from a-j to send to one player\n",
+    "\ta team letter [FRKO] to send to that team\n",
+    "\tthe letter 'A' to send to ALL.\n",
+    "\nOptions:\n",
+    "\t-w          without the 'who' part of the message ('GOD->ALL')\n",
+    "\t-n string   from somebody other than 'GOD'\n\n",
+    ""
+  };
+  int x;
+
+  fprintf(stderr, "-- Netrek II (Paradise), %s --\n", PARAVERS);
+  for (x = 0; *message[x] != '\0'; x++)
+    fprintf(stderr, message[x], name);
+
+  exit(1);
+}
+
+void 
+pmessage(from_to, str, recip, group)
+/* ==[ printing of message func ]== */
+  char *from_to;
+  char *str;
+  int recip;
+  int group;
+{
+  struct message *cur;
+  if (++(mctl->mc_current) >= MAXMESSAGE)
+    mctl->mc_current = 0;
+  cur = &messages[mctl->mc_current];
+  cur->m_no = mctl->mc_current;
+  cur->m_flags = group;
+  cur->m_time = 0;
+  cur->m_recpt = recip;
+  cur->m_from = 255;
+  (void) sprintf(cur->m_data, "%s%s", from_to, str);
+  cur->m_flags |= MVALID;
+}
+
+int 
+main(int argc, char **argv)
+{
+  char ch;
+  char to[80];
+  char from[80];
+  char buf2[80];
+  int target;
+  int flag;
+  char name[32];
+
+  strcpy(from, "GOD");
+  strcpy(to, "ALL");
+
+  strcpy(name, argv[0]);
+
+  if (argc == 1)
+    usage(name);
+
+  if ((target = letter_to_pnum(argv[1][0])) >= 0)
+  {				/*--[ personal ]--*/
+    flag = MINDIV;
+    /*
+     * r = &players[target]; printf("debug: 1"); to[0] =
+     * team_to_letter(r->p_team); to[1] = 0;
+     */
+    strcpy(to, argv[1]);
+  }
+  else
+    switch (ch = argv[1][0])
+    {				/*--[ better be a team ]--*/
+     case 'A':
+      target = 0;
+      flag = MALL;
+      break;
+     case 'F':
+      target = FED;
+      flag = MTEAM;
+      strcpy(to, "FED");
+      break;
+     case 'R':
+      target = ROM;
+      flag = MTEAM;
+      strcpy(to, "ROM");
+      break;
+     case 'K':
+      target = KLI;
+      flag = MTEAM;
+      strcpy(to, "KLI");
+      break;
+     case 'O':
+      target = ORI;
+      flag = MTEAM;
+      strcpy(to, "ORI");
+      break;
+     case 'S':
+      printf("+> This options is not compatable yet");
+      exit(1);
+      flag = 0;
+      break;
+     default:
+      usage(name);
+      flag = 0;
+      break;
+    }
+
+  /*
+   * =========================[ check for options ]=========================
+   */
+
+  if (argc >= 3)
+  {
+    if (strcmp(argv[2], "-w") == 0)
+    {				/*-----[ without to/from ]-----*/
+      from[0] = 0;
+    }
+    else if (strcmp(argv[2], "-n") == 0)
+    {				/*--[ different from name ]---*/
+      if (argc <= 2)		/*--[ other than GOD ]--------*/
+	usage(name);
+      if (argc >= 3)
+      {
+	strcpy(from, argv[3]);
+      }
+      else
+      {
+	usage(name);
+      }
+    }
+    else if (strcmp(argv[1], "-u") == 0 || strcmp(argv[1], "-h") == 0)
+    {
+      usage(name);
+    }
+  }
+
+  /*
+   * ===[ merge the to/from strings, make sure they are the same length ]===
+   */
+
+  if (from[0] == 0 || to[0] == 0)
+  {
+    strcpy(buf2, "");
+  }
+  else
+  {
+    if (strlen(from) <= 2)
+    {
+      strcpy(buf2, " ");
+    }
+    strcat(buf2, from);
+    strcat(buf2, "->");
+    strcat(buf2, to);
+
+    while (strlen(buf2) < 9)
+    {				/*---[ if it's too short, extend it ]---*/
+      strcat(buf2, " ");
+    }
+    strcat(buf2, " ");		/*---[ throw in an extra space ]---*/
+  }
+  /*
+   * =========================[ send it on its way ]========================
+   */
+
+  openmem(0);
+
+  while (1)
+  {
+    char buf[80];
+    int len;
+
+    printf(buf2);
+    if (0 == fgets(buf, sizeof(buf), stdin))
+      break;
+    len = strlen(buf);
+    if (buf[len - 1] == '\n')
+      buf[--len] = 0;
+    pmessage(buf2, buf, target, flag);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-pl.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,328 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include "data.h"
+#include "defs.h"
+#include "shmem.h"
+#include "tool-util.h"
+
+/* ------------------------------------------------------------------- */
+char *statnames[] = {"F", "O", "A", "E", "D", "Q"};
+
+char *oldranknames[] = {
+  "Ensign", "Lieutenan",
+  "Lt. Cmdr.", "Commander",
+  "Captain", "Flt. Capt",
+  "Commodore", "Rear Adml",
+  "Admiral"
+};
+
+char *oldshiptypes[] = {"SC", "DD", "CA", "BB", "AS", "SB"};
+
+/* ------------------------------------------------------------------- */
+char *maprank(struct player * p);
+char *mapshiptype(struct player * p);
+char *mapname(char *s);
+char *fillcH(int width, char fchar);
+char *typestat(struct player * p);
+
+/* -------------------------------[ Main ]----------------------------- */
+main(int argc, char **argv)
+{
+  int mode;
+  char monitor[17];
+  char fh[33];
+  int teams[9];
+  int i, count;
+  struct player *j;
+  int usage = 0;
+
+  argv0 = argv[0];
+
+  if (argc > 1)
+  {
+    if (argv[1][0] != '-')
+    {
+      usage++;
+    }
+    else
+    {
+      switch (argv[1][1])
+      {
+       case 'h':
+	usage++;
+	break;
+       case 'd':
+       case 'r':
+       case 'l':
+       case 'o':
+       case 'M':
+       case 'p':
+	mode = argv[1][1];
+	break;
+       default:
+	usage++;
+	break;
+      }
+    }
+  }
+  else
+  {
+    mode = '\0';
+  }
+
+  if (usage)
+  {
+    char *message[255] = {
+      "\n\t'%s [option]'\n",
+      "\nOptions:\n",
+      "\t-h   help (this usage description)\n",
+      "\t-d   Damage Status.\n",
+      "\t-r   ?\n",
+      "\t-l   Lag Statistics\n",
+      "\t-o   Old style (NetrekI Ranks/ships)\n",
+      "\t-M   Default (Metaserver)\n",
+      "\t-p   PID\n\n",
+      "\0"
+    };
+
+    fprintf(stderr, "-- NetrekII (Paradise), %s --\n", PARAVERS);
+    for (i = 0; *message[i] != '\0'; i++)
+      fprintf(stderr, message[i], argv0);
+
+    exit(1);
+  }
+
+  openmem(0);
+
+  for (count = 0, i = 0, j = players; i < MAXPLAYER; i++, j++)
+  {
+    if (j->p_status == PFREE)
+      continue;
+    count++;
+  }
+
+  if (!count)
+  {
+    printf("No one is playing.\n");
+    exit(0);
+  }
+
+  for (i = 0; i < 9; i++)
+    teams[i] = 0;
+
+  for (i = 0, j = players; i < MAXPLAYER; i++, j++)
+  {
+    if (j->p_status == PFREE)
+    {
+      continue;
+    }
+    teams[j->p_team]++;
+  }
+
+  /* print the header #1 */
+  printf("--==[ %d Player%s", count,
+	 (count == 1 ? " ]=====[" : (count > 9 ? "s ]===[" : "s ]====[")));
+  printf(" Feds: %d ]=[ Roms: %d ]=[ Kli: %d ]=[ Ori: %d ]=====--\n",
+	 teams[FED], teams[ROM], teams[KLI], teams[ORI]);
+
+  /* print the header #2 */
+  switch (mode)
+  {
+   case 'd':
+    printf("--==[ Name ]=========[ Type  Kills Damage Shields Armies   Fuel ]======--\n");
+    break;
+   case 'r':
+    printf("--==[ Name ]=========[ Status Type  Genocides  MaxKills        DI ]====--\n");
+    break;
+   case 'l':
+    printf("--==[ Name ]============[ Average   Stnd Dev   Loss ]==================--\n");
+    break;
+   case 'M':
+   case 'o':
+   case '\0':
+    printf("--=======[ Rank ]====[ Name ]=========[ Address ]======================--\n");
+    break;
+   case 'p':
+    printf("--========[ PID ]===[ Name ]==========[ Address ]======================--\n");
+    break;
+  }
+
+  for (i = 0, j = players; i < MAXPLAYER; i++, j++)
+  {
+    if (j->p_status == PFREE)
+    {
+      continue;
+    }
+    switch (mode)
+    {
+     case 'd':
+      printf("  %2s: %-16s   %2s %6.2f %6d %7d %6d %6d\n",
+	     twoletters(j), j->p_name,
+	     typestat(j),
+	     j->p_kills,
+	     j->p_damage,
+	     j->p_shield,
+	     j->p_armies,
+	     j->p_fuel);
+      break;
+     case 'r':
+      printf("  %2s: %-16s %s/%-4d  %2s  %7d  %9.1f  %10.2f\n",
+	     twoletters(j),
+	     j->p_name,
+	     statnames[j->p_status],
+	     j->p_ghostbuster,
+	     typestat(j),
+	     j->p_stats.st_genocides,
+	     j->p_stats.st_tmaxkills,
+	     j->p_stats.st_di);
+      break;
+     case 'l':
+      printf("  %2s: %-16s %7d ms %7d ms %5d%%\n",
+	     twoletters(j),
+	     j->p_name,
+	     j->p_avrt,
+	     j->p_stdv,
+	     j->p_pkls);
+      break;
+     case 'o':
+      if (i > 19)
+	continue;		/* show only first 20 */
+
+      strncpy(fh, j->p_full_hostname, 32);
+      fh[32] = 0;
+      printf("  %2s:  %2s  %-9.9s   %-16s %s@%s\n",
+	     twoletters(j), mapshiptype(j), maprank(j),
+	     mapname(j->p_name), j->p_login, fh);
+      break;
+     case 'p':
+      strncpy(fh, j->p_full_hostname, 32);
+      fh[32] = 0;
+      printf(" %c%2s:  %2s   %-9d %-16s  %s@%s\n",
+	     (j->p_stats.st_flags & ST_CYBORG) ? '*' : ' ',
+	     twoletters(j), typestat(j),
+	     j->p_ntspid,
+	     j->p_name,
+	     j->p_login,
+	     fh);
+      break;
+     case 'M':
+     case '\0':
+      strncpy(fh, j->p_full_hostname, 32);
+      fh[32] = 0;
+      printf(" %c%2s:  %2s  %-11.11s %-16s %s@%s\n",
+	     (j->p_stats.st_flags & ST_CYBORG) ? '*' : ' ',
+	     twoletters(j), typestat(j),
+	     j->p_stats.st_royal ? royal[j->p_stats.st_royal].name
+	     : ranks[j->p_stats.st_rank].name,
+	     j->p_name,
+	     j->p_login,
+	     fh);
+      break;
+    }
+  }
+
+  printf("--==[ NetrekII (Paradise), %s ]%s--\n", PARAVERS, fillcH((63 - strlen(PARAVERS)), '='));
+}
+
+/* ---------------------------[ Functions ]--------------------------- */
+
+/*
+ * map rank into one of the original netrek rank names for compatibility with
+ * the metaserver
+ */
+char *
+maprank(struct player * p)
+{
+  int r;
+
+  r = (int) (10 * (p->p_stats.st_rank / (float) NUMRANKS));
+  if (r < 0)
+    r = 0;
+  if (r > 8)
+    r = 8;
+  return oldranknames[r];
+}
+
+char *
+mapshiptype(struct player * p)
+{
+  int n;
+
+  n = p->p_ship.s_alttype;
+  if (n > 5)
+    n = 5;
+
+  return oldshiptypes[n];
+}
+
+char *
+mapname(char *s)
+{
+  char newname[17];
+
+  if (*s == ' ')
+  {
+    strncpy(newname, s, 16);
+    newname[0] = '_';
+    return newname;
+  }
+  else
+    return s;
+}
+
+/* fills with fchar up to width (width must be less than 255) */
+char *
+fillcH(int width, char fchar)
+{
+  char buf[width];
+  int i;
+
+  for (i = 0; i < width; i++)
+    buf[i] = fchar;
+
+  return buf;
+}
+
+char *
+typestat(struct player * p)
+{
+  char str[3];
+
+  switch (p->p_status)
+  {
+   case PALIVE:
+   case PEXPLODE:
+    str[0] = p->p_ship.s_desig1;
+    str[1] = p->p_ship.s_desig2;
+    str[3] = 0;
+    return str;
+   case PTQUEUE:
+    return "tq";
+   case POBSERVE:
+    return "ob";
+   case POUTFIT:
+    return "of";
+   case PDEAD:
+   default:
+    return "--";
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-promo.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,213 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "struct.h"
+#include "data.h"
+
+int nplayers;
+struct statentry *database;
+
+struct highscore
+{
+  char name[32];
+  int advance, newrank;
+  float didiff;
+};
+
+struct highscore *scores;
+int scoresize, nscores;
+
+int
+cmp_score(a, b)
+  struct highscore *a, *b;
+{
+  float diff = a->newrank - b->newrank;
+
+  if (diff < 0)
+    return 1;
+  else if (diff > 0)
+    return -1;
+
+  diff = a->advance - b->advance;
+
+  if (diff < 0)
+    return 1;
+  else if (diff > 0)
+    return -1;
+
+  diff = a->didiff - b->didiff;
+
+  if (diff < 0)
+    return 1;
+  else if (diff > 0)
+    return -1;
+  else
+    return 0;
+}
+
+struct statentry zeroplayer;
+
+int
+main(argc, argv)
+  int argc;
+  char **argv;
+{
+  struct stat fstats;
+  FILE *fp;
+  int i;
+  int threshold;
+  struct statentry currplayer;
+
+  if (argc != 4)
+  {
+    int x;
+    char message[][255] = {
+      "\n\t'%s n oldfile newfile'\n",
+      "\nLists all players who have been promoted more than n ranks.\n",
+      ""
+    };
+
+    fprintf(stderr, "-- Netrek II (Paradise), %s --\n", PARAVERS);
+    for (i = 0; *message[i] != '\0'; i++)
+      fprintf(stderr, message[i], argv[0]);
+
+    exit(1);
+  }
+
+  threshold = atoi(argv[1]);
+
+
+  fp = fopen(argv[2], "r");
+  if (fp == 0)
+  {
+    fprintf(stderr, "Couldn't open file %s for read", argv[1]);
+    perror("");
+    exit(1);
+  }
+
+  if (fstat(fileno(fp), &fstats) < 0)
+  {
+    fprintf(stderr, "Couldn't fstat file %s", argv[1]);
+    perror("");
+    exit(1);
+  }
+
+  nplayers = fstats.st_size / sizeof(*database);
+  database = (struct statentry *) malloc(sizeof(*database) * nplayers);
+
+  i = fread(database, sizeof(*database), nplayers, fp);
+
+  if (i == 0)
+  {
+    fprintf(stderr, "failed to read any player records from file %s\n", argv[1]);
+    exit(1);
+  }
+  if (i != nplayers)
+  {
+    fprintf(stderr, "failed to read all player records from file %s (%d of %d)\n", argv[1], i, nplayers);
+    nplayers = i;
+  }
+
+  fclose(fp);
+
+  fp = fopen(argv[3], "r");
+  if (fp == 0)
+  {
+    fprintf(stderr, "Couldn't open file %s for read", argv[2]);
+    perror("");
+    exit(1);
+  }
+
+
+  scores = (struct highscore *) malloc(sizeof(*scores) * (scoresize = 256));
+  nscores = 0;
+
+  while (1)
+  {
+    int delta;
+    int dt;
+    struct statentry *prevplayer;
+    struct highscore *currscore;
+
+    i = fread(&currplayer, sizeof(currplayer), 1, fp);
+    if (i < 0)
+    {
+      fprintf(stderr, "error reading player record, aborting loop\n");
+      perror("");
+    }
+    if (i <= 0)
+      break;
+
+    for (i = 0; i < nplayers; i++)
+    {
+      if (0 == strcmp(database[i].name, currplayer.name))
+	break;
+    }
+    if (i < nplayers)
+      prevplayer = &database[i];
+    else
+      prevplayer = &zeroplayer;
+
+    if (currplayer.stats.st_rank - prevplayer->stats.st_rank <= threshold)
+      continue;			/* didn't advance enough */
+
+    if (nscores >= scoresize)
+    {
+      scores = (struct highscore *) realloc(scores, sizeof(*scores) * (scoresize *= 2));
+    }
+    currscore = &scores[nscores++];
+    strcpy(currscore->name, currplayer.name);
+    currscore->newrank = currplayer.stats.st_rank;
+    currscore->advance = currplayer.stats.st_rank - prevplayer->stats.st_rank;
+    currscore->didiff = currplayer.stats.st_di - prevplayer->stats.st_di;
+  }
+
+
+#define offset(field) ( (int)&(((struct highscore*)0)->field) )
+
+  qsort(scores, nscores, sizeof(*scores), cmp_score);
+
+  printf("Congratulations to the following warriors:\n");
+  for (i = 0; i < nscores; i++)
+  {
+    struct highscore *curr = &scores[i];
+    int j;
+
+    printf("%s ", curr->name);
+    for (j = strlen(curr->name); j < 18; j++)
+      putchar(0x1f);
+    printf(" promoted from %s to %s", ranks[curr->newrank - curr->advance].name,
+	   ranks[curr->newrank].name);
+    if (curr->advance > 1)
+    {
+      printf(" (%d ranks)", curr->advance);
+    }
+    printf("\n");
+  }
+  printf("(Your new insignia will be provided as soon as we get\n\
+ enough scrap plastic donations.)");
+
+  exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-reset.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,131 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "defs.h"
+#include "shmem.h"
+#include "getship.h"
+#include "data.h"
+
+#define STEP 10
+char *myname;
+
+main(argc, argv)
+  int argc;
+  char **argv;
+{
+  int i;
+  int player;
+  char buf[1000];
+  int c, seconds, part;
+
+  myname = argv[0];
+
+  if (argc > 3)
+    Usage();
+
+  if (argc == 2)
+  {
+    i = sscanf(argv[1], "%d", &seconds);
+    if (i != 1)
+      Usage();
+    if (seconds < 0)
+      Usage();
+  }
+  else
+  {
+    seconds = 10;
+  }
+  openmem(0);
+
+  part = seconds % STEP;
+  if (part)
+    sleep(part);
+
+  for (seconds -= part; seconds > 0; seconds -= STEP)
+  {
+    sprintf(buf, "%s->ALL  ** Attention: The galaxy will be reset in %d seconds.", SERVNAME, seconds);
+    pmessage(buf, 0, MALL);
+    sleep(STEP);
+  }
+
+  sprintf(buf, "%s->ALL  ** Manual galaxy reset **", SERVNAME);
+  pmessage(buf, 0, MALL);
+
+  zap();
+
+  /* *newgalaxy = 1; */
+  status2->newgalaxy = 1;
+  exit(0);
+}
+
+pmessage(str, recip, group)
+  char *str;
+  int recip;
+  int group;
+{
+  struct message *cur;
+  if (++(mctl->mc_current) >= MAXMESSAGE)
+    mctl->mc_current = 0;
+  cur = &messages[mctl->mc_current];
+  cur->m_no = mctl->mc_current;
+  cur->m_flags = group;
+  cur->m_time = 0;
+  cur->m_from = 255;		/* change 3/30/91 TC */
+  cur->m_recpt = recip;
+  (void) sprintf(cur->m_data, "%s", str);
+  cur->m_flags |= MVALID;
+}
+
+
+Usage()
+{
+  int x;
+  char message[][255] = {
+    "\n\t'%s [n]'\n\n",
+    "Where n is the seconds until the galaxy is reset (default: 10)\n"
+    "\nThis tool resets the galaxy.\n",
+    ""
+  };
+
+  fprintf(stderr, "-- NetrekII (Paradise), %s --\n", PARAVERS);
+  for (x = 0; *message[x] != '\0'; x++)
+    fprintf(stderr, message[x], myname);
+
+  exit(1);
+}
+
+zap()
+{
+  int player;
+
+  for (player = 0; player < MAXPLAYER; player++)
+  {
+    if (players[player].p_status == PFREE)
+      continue;
+    players[player].p_whydead = KPROVIDENCE;
+    players[player].p_whodead = 0;
+    players[player].p_status = PEXPLODE;
+    players[player].p_explode = 10;
+    players[player].p_ntorp = 0;
+    players[player].p_nplasmatorp = 0;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-trim.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,162 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+/*
+ * Kevin P. Smith      12/05/88
+ * 
+ * Modified for Paradise by Rob Forsman 1993 Cleaned up by Brandon Gillespie
+ * Sept 17 1994
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <pwd.h>
+#include "defs.h"
+#include "data.h"
+#include "struct.h"
+
+struct statentry player2;
+/* struct status globals; */
+struct rawdesc *output = NULL;
+char mode;
+
+/* prototypes */
+void trimblanks2(char *str);
+void trimblanks(char *str);
+void usage(char *me);
+
+main(argc, argv)
+  int argc;
+  char **argv;
+{
+  int fd;
+  struct statentry plstats;
+  int i;
+  char buf[512];
+  int harsh = 10;		/* How strict we will be with player trimming */
+  char *me;
+  char *path;
+  FILE *infile = stdin;		/* these used to actually read in from the
+				 * actual file, Rob changed them to
+				 * stdin/out, and I don't mind them that way
+				 * (it actually makes it a little easier */
+  FILE *outfile = stdout;
+
+  me = *argv;
+
+  if (argc == 2)
+  {
+    if (*argv[1] == '-')
+      usage(me);
+    else
+      harsh = atoi(argv[1]);
+  }
+
+  if (argc > 2 || harsh <= 0)
+    usage(me);
+
+  fprintf(stderr, "%s: If you do not know how to use this program, break now and type '%s -h'\n", me, me);
+
+  i = 0;
+  while (1 == fread(&plstats, sizeof(plstats), 1, infile))
+  {
+    /* Player 0 is always saved. */
+    /*
+     * This formula reads: If (deadtime - (10 + rank^2 + playtime/2.4)*n days
+     * > 0), nuke him.
+     */
+    if (i != 0
+	&& harsh < 100
+	&& ((time(NULL) - plstats.stats.st_lastlogin) >
+	    (10 +
+	     plstats.stats.st_rank * plstats.stats.st_rank +
+	     (plstats.stats.st_tticks +
+	      plstats.stats.st_sbticks +
+	      plstats.stats.st_wbticks +
+	      plstats.stats.st_jsticks) / 2.4) * harsh * 24 * 60 * 60)
+      )
+    {
+      fprintf(stderr,
+	      "%-16.16s %7.2f   %4d   %4d   %4d   %4d\n",
+	      plstats.name,
+	      plstats.stats.st_tticks / 36000.0,
+	      plstats.stats.st_tplanets,
+	      player2.stats.st_tarmsbomb,
+	      player2.stats.st_tkills,
+	      player2.stats.st_tlosses);
+      continue;
+    }
+    if (outfile)
+    {
+      fwrite(&plstats, sizeof(plstats), 1, outfile);
+    }
+    i++;
+  }
+  exit(0);
+}
+
+void 
+usage(char *me)
+{
+  int x;
+  char message[][255] = {
+    "\n\t'%s [n] < old-playerdb > new-playerdb'\n",
+    "\nThis program trims a player database file.  The level of niceness is\n",
+    "determined by 'n' (default: 10).  The old player database is read from stdin,\n",
+    "the new player database is written to stdout, a quick description of players\n",
+    "who were removed is written to stderr.  It will remove any character who\n",
+    "has not played for n*10 days, as well as giving some other consideration\n",
+    "to their varied statistics.  The actual formula is:\n\n",
+    "\tIf (deadtime - (10 + rank^2 + playtime/2.4)*n days > 0), nuke him.\n\n"
+  };
+
+  fprintf(stderr, "-- NetrekII (Paradise), %s --\n", PARAVERS);
+  for (x = 0; *message[x] != '\0'; x++)
+    fprintf(stderr, message[x], me);
+
+  exit(0);
+}
+
+void 
+trimblanks2(char *str)
+{
+  *str = 0;
+  str--;
+  while (*str == ' ')
+  {
+    *str = 0;
+    str--;
+  }
+  if (*str == '_')
+    *str = 0;
+}
+
+void 
+trimblanks(char *str)
+{
+  *str = 0;
+  str--;
+  while (*str == ' ')
+  {
+    *str = 0;
+    str--;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-util.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,140 @@
+#include "config.h"
+
+#include "tool-util.h"
+#include "shmem.h"
+#include "data.h"
+
+char
+team_to_letter(t)
+  int t;
+{
+  switch (t)
+  {
+   case FED:
+    return 'F';
+   case ROM:
+    return 'R';
+   case KLI:
+    return 'K';
+   case ORI:
+    return 'O';
+   default:
+    return 'I';
+  }
+}
+
+int
+letter_to_team(ch)
+  char ch;
+{
+  switch (ch)
+  {
+   case 'I':
+   case 'i':
+    return 0;
+   case 'F':
+   case 'f':
+    return FED;
+   case 'R':
+   case 'r':
+    return ROM;
+   case 'K':
+   case 'k':
+    return KLI;
+   case 'O':
+   case 'o':
+    return ORI;
+   default:
+    return -1;
+  }
+}
+
+int
+letter_to_pnum(ch)
+  char ch;
+{
+  switch (ch)
+  {
+   case '0':
+   case '1':
+   case '2':
+   case '3':
+   case '4':
+   case '5':
+   case '6':
+   case '7':
+   case '8':
+   case '9':
+    return ch - '0';
+
+   case 'a':
+   case 'b':
+   case 'c':
+   case 'd':
+   case 'e':
+   case 'f':
+   case 'g':
+   case 'h':
+   case 'i':
+   case 'j':
+   case 'k':
+   case 'l':
+   case 'm':
+   case 'n':
+   case 'o':
+   case 'p':
+   case 'q':
+   case 'r':
+   case 's':
+   case 't':
+   case 'u':
+   case 'v':
+   case 'w':
+   case 'x':
+   case 'y':
+   case 'z':
+    return ch - 'a' + 10;
+   default:
+    return -1;
+  }
+}
+
+char
+pnum_to_letter(ch)
+  int ch;
+{
+  switch (ch)
+  {
+   case 0:
+   case 1:
+   case 2:
+   case 3:
+   case 4:
+   case 5:
+   case 6:
+   case 7:
+   case 8:
+   case 9:
+    return ch + '0';
+   default:
+    return ch - 10 + 'a';
+  }
+}
+
+
+char *
+twoletters(pl)
+  struct player *pl;
+/* calculate the two letters that form the players designation (e.g. R4) */
+{
+#define RINGSIZE MAXPLAYER+3
+  static char buf[RINGSIZE][3];	/* ring of buffers so that this */
+  static int idx;		/* proc can be called several times before
+				 * the results are used */
+  if (idx >= RINGSIZE)
+    idx = 0;
+  buf[idx][0] = teams[pl->p_team].letter;
+  buf[idx][1] = shipnos[pl->p_no];
+  buf[idx][2] = 0;
+  return buf[idx++];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-util.h	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,6 @@
+#include "defs.h"
+
+char team_to_letter( /* int */ );
+char pnum_to_letter( /* int */ );
+int letter_to_team( /* char */ );
+int letter_to_pnum( /* char */ );
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-wm.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,186 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+/*
+ * // overhaul by Brandon Gillespie Sept 17 1994
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "defs.h"
+#include "data.h"
+#include "struct.h"
+#include "shmem.h"
+
+#define CNORMAL   "\33[37;0m"
+#define CBOLD     "\33[1m"
+#define CRED      "\33[31m"
+#define CGREEN    "\33[32m"
+#define CYELLOW   "\33[33m"
+#define CBLUE     "\33[34m"
+#define CMAGENTA  "\33[35m"
+#define CCYAN     "\33[36m"
+
+/* prototypes */
+void printmes(char mstr[80], int mflags, int mrecpt, int mfrom);
+void usage(char *me);
+static int contains(char *str1, char *str2);
+
+#define PRINT(__x) if (1) {\
+        if (displaykills == 1) \
+            printf("\n%s", __x); \
+        else if (mflags != 169) /* MKILLA) */ \
+            printf("\n%s", __x); \
+        printf(CNORMAL); \
+    }
+/*
+ * // Global Variables, bad, but this is an easier way to do options // which
+ * are only set once
+ */
+
+int displaykills = 1;
+int docolor = 0;
+char *myname;
+
+int 
+main(int argc, char **argv)
+{
+  int i;
+  int oldmctl;
+
+  myname = *argv++;
+  argc--;
+
+  while (argc)
+  {
+    if (argv[0][0] == '-')
+    {
+      switch (argv[0][1])
+      {
+       case 'k':
+	displaykills = 0;
+	break;
+       case 'c':
+	docolor = 1;
+	break;
+       default:
+	usage(argv[0]);
+	break;
+      }
+    }
+    argv++;
+    argc--;
+  }
+
+  openmem(0);
+
+  oldmctl = mctl->mc_current;
+
+  for (i = 0; i <= oldmctl; i++)
+  {
+    printmes(messages[i].m_data,
+	     messages[i].m_flags,
+	     messages[oldmctl].m_recpt,
+	     messages[oldmctl].m_from);
+  }
+
+  fflush(stdout);
+
+  for (;;)
+  {
+    sleep(1);
+    while (oldmctl != mctl->mc_current)
+    {
+      oldmctl++;
+      if (oldmctl == 50)
+	oldmctl = 0;
+      printmes(messages[oldmctl].m_data,
+	       messages[oldmctl].m_flags,
+	       messages[oldmctl].m_recpt,
+	       messages[oldmctl].m_from);
+      fflush(stdout);
+    }
+  }
+}
+
+static int 
+contains(char *str1, char *str2)
+{
+  char *s;
+  int length;
+
+  length = strlen(str2);
+  for (s = str1; *s != 0; s++)
+  {
+    if (*s == *str2 && strncmp(s, str2, length) == 0)
+      return (1);
+  }
+  return (0);
+}
+
+void 
+printmes(char mstr[80], int mflags, int mrecpt, int mfrom)
+{
+  if (docolor)
+  {
+    switch (mflags)
+    {
+      case 17:			/* MGOD: */
+      printf(CBOLD);
+      printf(CGREEN);
+      break;
+     case 329:			/* MJOIN: */
+     case 297:			/* MLEAVE: */
+     case 169:			/* MKILLA: */
+     case 101:			/* MTAKE: */
+     case 197:			/* MBOMB: */
+     case 133:			/* MDEST: */
+     case 69:			/* M?: */
+      break;
+     default:
+      printf(CBOLD);
+    }
+  }
+  PRINT(mstr);
+}
+
+void 
+usage(char *me)
+{
+  int x;
+  char message[][255] = {
+    "Netrek II message board watching tool.\n",
+    "\t'%s [options]'\n",
+    "\nOptions:\n",
+    "\t-k    do not remove kills from listing\n",
+    "\t-c    colorized text (need higher than a vt100 term)\n",
+    "\t-h    this usage description\n",
+    "\nNo options will list every message, any other option will be interpreted as\n",
+    "a filter, which is a Terrance Chang mod, and I dont know|care what it is for.\n",
+    ""
+  };
+
+  fprintf(stderr, "-- NetrekII (Paradise), %s --\n", PARAVERS);
+  for (x = 0; *message[x] != '\0'; x++)
+    fprintf(stderr, message[x], me);
+
+  exit(1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tool-xtk.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,319 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "defs.h"
+#include "data.h"
+#include "shmem.h"
+#include "getship.h"
+#include "tool-util.h"
+
+char teamlet[] = {'I', 'F', 'R', 'X', 'K', 'X', 'X', 'X', 'O'};
+char *names[] = {"Neutral", "Fed", "Rom", "", "Kli", "", "", "", "Ori"};
+
+void Usage(char *myname);
+void pmessage();
+
+int 
+main(argc, argv)
+  int argc;
+  char **argv;
+{
+  int i;
+  int pno;
+  char buf[1000];
+  char *myname;
+  int c;
+  struct player *victim;
+
+  myname = *argv;
+
+  if (argc < 2)
+    Usage(myname);
+
+  if (argv[1][1] != 0)
+    Usage(myname);
+  pno = letter_to_pnum(argv[1][0]);
+  if (pno < 0 || pno >= MAXPLAYER)
+  {
+    fprintf(stderr, "player number out of bounds (%d, %d)\n",
+	    pno, MAXPLAYER);
+    exit(1);
+  }
+
+  openmem(0);
+
+  victim = &players[pno];
+
+  if (victim->p_status != PALIVE)
+  {
+    if (argc > 2 && strcmp(argv[2], "F") == 0)
+    {
+      memset(victim, 0, sizeof(struct player));
+      /* bzero(victim, sizeof(struct player));	/* confusion 8/5/91 TC */
+      /* victim->p_status = PFREE; */
+      exit(0);
+    }
+    printf("Slot is not alive.\n");
+    exit(1);
+  }
+  if (argc <= 2)
+  {
+    sprintf(buf, "%s (%2s) was utterly obliterated.",
+	    victim->p_name, twoletters(victim));
+    /* victim->p_name, victim->p_mapchars); */
+    victim->p_ship.s_type = STARBASE;
+    victim->p_whydead = KPROVIDENCE;
+    victim->p_explode = 10;
+    victim->p_status = 3;
+    victim->p_whodead = 0;
+    pmessage(buf, 0, MALL);
+    exit(0);
+  }
+  switch (*argv[2])
+  {
+   case 'e':
+    sprintf(buf, "%s (%2s) has been ejected from the game.",
+	    victim->p_name, twoletters(victim));
+    victim->p_whydead = KQUIT;
+    victim->p_explode = 10;
+    victim->p_status = 3;
+    victim->p_whodead = 0;
+    pmessage(buf, 0, MALL);
+    break;
+   case 's':
+    {
+      int i;
+      for (i = 0; i < NUM_TYPES; i++)
+      {
+	if (argv[2][1] == shipvals[i].s_letter)
+	  break;
+      }
+      if (i >= NUM_TYPES)
+      {
+	fprintf(stderr, "Unknown ship type %c.\n", argv[2][1]);
+	exit(1);
+      }
+      else
+      {
+	get_ship_for_player(victim, i);
+      }
+    }
+
+    victim->p_damage = 0;
+    victim->p_shield = victim->p_ship.s_maxshield;
+    victim->p_wtemp = 0;
+    victim->p_etemp = 0;
+    victim->p_fuel = victim->p_ship.s_maxfuel;
+    break;
+#if 0
+   case 't':
+    switch (argv[2][1])
+    {
+     case 'f':
+      victim->p_x = planets[0].pl_x;
+      victim->p_y = planets[0].pl_y;
+      break;
+     case 'r':
+      victim->p_x = planets[10].pl_x;
+      victim->p_y = planets[10].pl_y;
+      break;
+     case 'k':
+      victim->p_x = planets[20].pl_x;
+      victim->p_y = planets[20].pl_y;
+      break;
+     case 'o':
+      victim->p_x = planets[30].pl_x;
+      victim->p_y = planets[30].pl_y;
+      break;
+     case 'c':
+      victim->p_x = GWIDTH / 2;
+      victim->p_y = GWIDTH / 2;
+      break;
+     default:
+      printf("Valid teleports: frkoc.\n");
+      exit(1);
+    }
+    break;
+#endif
+#if 0
+   case 'S':			/* super ship */
+    victim->p_ship.s_maxshield = 750;
+    victim->p_shield = 750;
+    victim->p_ship.s_maxdamage = 750;
+    victim->p_ship.s_maxegntemp = 5000;
+    break;
+#endif
+   case 'T':
+    {
+      int team;
+      team = letter_to_team(argv[2][1]);
+      if (team < 0)
+      {
+	fprintf(stderr, "Invalid team letter `%c', choose one of [frkoi]\n", argv[2][1]);
+	exit(1);
+      }
+      victim->p_team = team;
+      victim->p_hostile &= ~team;
+      victim->p_swar &= ~team;
+      sprintf(buf, "%2s has been changed to a %s.",
+	      twoletters(victim), names[team]);
+      pmessage(buf, 0, MALL);
+#if 0
+      sprintf(buf, "%c%c", teamlet[victim->p_team],
+	      shipnos[pno]);
+      strncpy(victim->p_mapchars, buf, 2);
+#endif
+    }
+    break;
+   case 'D':			/* demote */
+    --victim->p_stats.st_rank;
+    sprintf(buf, "%2s was (temporarily) demoted for \
+		rank normalization purposes.", twoletters(victim));
+    pmessage(buf, 0, MALL);
+    break;
+   case 'P':
+    ++victim->p_stats.st_rank;
+    break;
+   case 'k':
+    victim->p_kills += 1.0;
+    break;
+   case 'h':
+    victim->p_shield = 0;
+    victim->p_damage = victim->p_ship.s_maxdamage / 2;
+    break;
+   case 'a':
+    victim->p_armies += 6;
+    break;
+   case 'C':
+    teams[victim->p_team].s_surrender = 6;
+    break;
+   case 'L':
+    victim->p_stats.st_sblosses--;
+    break;
+   case 'R':
+    if (victim->p_flags & PFROBOT)
+    {
+      victim->p_ship.s_type = STARBASE;
+      victim->p_whydead = KPROVIDENCE;
+      victim->p_explode = 10;
+      victim->p_status = 3;
+      victim->p_whodead = 0;
+    }
+    break;
+#if 0
+   case 'p':			/* puck? */
+    victim->p_ship.s_tractstr = 1;
+    victim->p_ship.s_torpdamage = -1;
+    victim->p_ship.s_plasmadamage = -1;
+    victim->p_ship.s_phaserdamage = -1;
+    victim->p_hostile = 0;
+    victim->p_swar = 0;
+    victim->p_team = 0;		/* indep */
+    victim->p_ship.s_type = STARBASE;
+    victim->p_ship.s_mass = 200;
+    victim->p_ship.s_repair = 30000;
+
+    victim->p_ship.s_maxspeed = 0;
+#endif
+   default:
+    Usage(myname);
+  }				/* end switch */
+  return 0;
+}
+
+void 
+Usage(char *myname)
+{
+  printf("-- NetrekII (Paradise), %s --\n", PARAVERS);
+  printf("\
+\n\t%'s [0-9a-j] <mode><mode option>'\n\
+\n\
+Where <mode> is one of :\n\
+      e(ject from game)             (simulates self-destruct)\n\
+      s(hip class change)[abcdosA]  (A = ATT)\n\
+      T(eam change)[frko]           (no team == independent)\n\
+      D(emote)                      (-1 to rank)\n\
+      P(romote)                     (+1 to rank)\n\
+      F(ree slot)                   (bypasses 6 minute ghostbuster timeout)\n\
+      k(ills increment)             (+1 kill)\n\
+      h(arm)                        (no shields, 50%% damage)\n\
+      a(rmies increment)            (+6 armies)\n\
+      C(lock, surrender -- set it)  (to 6 minutes (debugging aid))\n\
+      L(oss adjust, SB (-1))        (in case you toast an SB accidentally)\n\
+      R(obot obliterate)            (like obliterate, but only for robots)\n\
+      (no mode == obliterate)\n\
+", myname);
+  exit(1);
+}
+
+
+#if 0
+/* stuff copied from other files: */
+
+char *
+twoletters(pl)
+  struct player *pl;
+/* calculate the two letters that form the players designation (e.g. R4) */
+{
+#define RINGSIZE MAXPLAYER+3
+  static char buf[RINGSIZE][3];	/* ring of buffers so that this */
+  static int idx;		/* proc can be called several times before
+				 * the results are used */
+  if (idx >= RINGSIZE)
+    idx = 0;
+  buf[idx][0] = teams[pl->p_team].letter;
+  buf[idx][1] = shipnos[pl->p_no];
+  buf[idx][2] = 0;
+  return buf[idx++];
+}
+#endif
+
+
+/*------------------------------PMESSAGE----------------------------------*/
+/*
+ * This function sens a message to the message board.  It places the message
+ * in the next position of the array of messages.  The message will ahve a
+ * header attached to the front of it.
+ */
+
+void
+pmessage(str, recip, group)
+  char *str;			/* the message */
+  int recip;			/* who is the recipient */
+  int group;			/* group sent to and other flags */
+{
+  struct message *cur;		/* to pnt to where to put message */
+  int mesgnum;			/* to hold index into array of messgs */
+
+  if ((mesgnum = ++(mctl->mc_current)) >= MAXMESSAGE)
+  {
+    mctl->mc_current = 0;	/* move to next index in array and */
+    mesgnum = 0;		/* warp around if necessart */
+  }
+  cur = &messages[mesgnum];	/* get addr of message struct */
+  cur->m_no = mesgnum;		/* set the message number */
+  cur->m_flags = group;		/* set the group and flags */
+  cur->m_recpt = recip;		/* set the recipient */
+  cur->m_from = 255;		/* message is from God */
+  (void) sprintf(cur->m_data, "%s %s", "XTKILL:", str);
+  cur->m_flags |= MVALID;	/* mark message as valid */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tourny.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,602 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+#ifdef LEAGUE_SUPPORT
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "defs.h"
+#include "struct.h"
+#include "shmem.h"
+#include "data.h"
+
+#define TLOGNAME "/tmp/tourney.log"
+#define MAXTIME 120
+
+FILE *tlog = NULL;
+/* int tournymode = 0; */
+
+#define TOURNEYMODE	(status2->league > 2)
+
+void endtourn();
+void starttourn();
+
+
+#ifndef IRIX
+extern int fprintf();
+#endif
+extern int fclose();
+extern void pmessage();
+extern void explode_everyone();
+extern void endgame_effects();
+
+void
+opentlog()
+{
+  tlog = fopen(TLOGNAME, "a");
+  if (tlog == NULL)
+    fprintf(stderr, "Could not open the tournament logfile");
+  else
+  {
+#ifdef SYSV
+    setvbuf(tlog, NULL, _IOLBF, BUFSIZ);
+#else
+    setlinebuf(tlog);
+#endif
+    fprintf(tlog, "\n\n\n\nOPENING TOURNAMENT LOG\n\n");
+  }
+}
+
+/*
+ * Return a string identifying the player and his ship. Uses a ring of
+ * buffers so that it can be used multiple times in a printf
+ */
+char *
+id_player(p)
+  struct player *p;
+{
+  static char bufs[16][80];
+  static int ring = 0;
+  int count;
+
+  ring++;
+  count = sizeof(bufs) / sizeof(*bufs);
+  if (ring >= count)
+    ring = 0;
+
+  sprintf(bufs[ring], "%s <%s> %c%c", twoletters(p),
+	  p->p_name, p->p_ship.s_desig1, p->p_ship.s_desig2);
+
+  return bufs[ring];
+}
+
+/*
+ * Return a string identifying the player and his ship. Uses a ring of
+ * buffers so that it can be used multiple times in a printf
+ */
+char *
+id_planet(p)
+  struct planet *p;
+{
+  static char bufs[16][80];
+  static int ring = 0;
+  int count;
+
+  ring++;
+  count = sizeof(bufs) / sizeof(*bufs);
+  if (ring >= count)
+    ring = 0;
+
+  sprintf(bufs[ring], "#%d [%s] %s", p->pl_no, p->pl_name,
+	  teams[p->pl_owner].shortname);
+
+  return bufs[ring];
+}
+
+
+/*
+ * List of player related actions
+ * 
+ */
+
+enum player_status_e status_cache[MAXPLAYER];
+enum ship_types_e ship_cache[MAXPLAYER];
+
+void
+tlog_refit(pl)
+  struct player *pl;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  /* we have to print the OLD ship type he was flying */
+  fprintf(tlog, "%ld\trefit %s <%s> %c%c %dt\n", status->clock,
+	  twoletters(pl), pl->p_name,
+	  shipvals[ship_cache[pl->p_no]].s_desig1,
+	  shipvals[ship_cache[pl->p_no]].s_desig2,
+	  pl->p_updates);
+
+  ship_cache[pl->p_no] = pl->p_ship.s_type;
+}
+
+/*
+ * player was killed by player. call before erasing armies
+ */
+void
+tlog_plkill(victim, killer1, killer2)
+  struct player *victim;
+  struct player *killer1;
+  struct player *killer2;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tkill %s+%da,%dt,%.2fk by %s&%s\n",
+	  status->clock,
+	  id_player(victim), victim->p_armies, victim->p_updates,
+	  victim->p_kills,
+    killer1 ? id_player(killer1) : "_", killer2 ? id_player(killer2) : "_");
+
+  status_cache[victim->p_no] = victim->p_status;
+}
+
+/*
+ * player changed status from ALIVE to something else without telling us.
+ * call before erasing armies
+ */
+void
+tlog_plquit(victim)
+  struct player *victim;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tquit %s+%da,%dt,%.2fk\n",
+	  status->clock,
+	  id_player(victim), victim->p_armies, victim->p_updates,
+	  victim->p_kills);
+
+  status_cache[victim->p_no] = victim->p_status;
+}
+
+/*
+ * player was killed by planet. call before erasing armies
+ */
+void
+tlog_plankill(victim, killer1, killer2)
+  struct player *victim;
+  struct planet *killer1;
+  struct player *killer2;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tkill %s+%da by %s&%s\n",
+	  status->clock, id_player(victim), victim->p_armies,
+	  id_planet(killer1), killer2 ? id_player(killer2) : "_");
+  status_cache[victim->p_no] = victim->p_status;
+}
+
+/*
+ * planet was destroyed call before changing owner to IND
+ */
+void
+tlog_plandest(pl, killer)
+  struct planet *pl;
+  struct player *killer;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tpl_destroy %s by %s\n", status->clock, id_planet(pl),
+	  id_player(killer));
+}
+
+/*
+ * planet was taken call after changing owner
+ */
+void
+tlog_plantake(pl, killer)
+  struct planet *pl;
+  struct player *killer;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tpl_take %s by %s\n", status->clock, id_planet(pl),
+	  id_player(killer));
+}
+
+/*
+ * planet was abandoned call before changing owner
+ */
+void
+tlog_planaban(pl, killer)
+  struct planet *pl;
+  struct player *killer;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tpl_aban %s by %s\n", status->clock, id_planet(pl),
+	  id_player(killer));
+}
+
+void
+tlog_jsassist(js)
+  struct player *js;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tjsassist %s\n", status->clock, id_player(js));
+}
+
+/* call before transferring the army */
+void
+tlog_beamup(pl, carrier)
+  struct planet *pl;
+  struct player *carrier;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tbeamup %s from %s@%da\n", status->clock,
+	  id_player(carrier), id_planet(pl), pl->pl_armies);
+}
+
+/* call after transferring the army */
+void
+tlog_beamdown(pl, carrier)
+  struct planet *pl;
+  struct player *carrier;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tbeamdown %s to %s@%da\n", status->clock,
+	  id_player(carrier), id_planet(pl), pl->pl_armies);
+}
+
+/* call before transferring the army */
+void
+tlog_Bbeamup(base, carrier)
+  struct player *base;
+  struct player *carrier;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\txfer %s from %s\n", status->clock, id_player(carrier),
+	  id_player(base));
+}
+
+/* call after transferring the army */
+void
+tlog_Bbeamdown(base, carrier)
+  struct player *base;
+  struct player *carrier;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\txfer %s to %s\n", status->clock, id_player(carrier),
+	  id_player(base));
+}
+
+/* call after destroying armies */
+void
+tlog_bomb(pl, killer, narmies)
+  struct planet *pl;
+  struct player *killer;
+  int narmies;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  if (!narmies)
+    return;
+
+  fprintf(tlog, "%ld\tbomb %s by %s (%da)\n", status->clock,
+	  id_planet(pl), id_player(killer), narmies);
+}
+
+void
+tlog_bres(pl, killer, resource)
+  struct planet *pl;
+  struct player *killer;
+  char *resource;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tresbomb %s (%s) by %s\n", status->clock,
+	  id_planet(pl), resource, id_player(killer));
+}
+
+
+/*
+ * non-player action stuff
+ * 
+ */
+
+/* call before popping */
+void
+tlog_pop(pl, narmies)
+  struct planet *pl;
+  int narmies;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tpoparmies %s %+da\n", status->clock,
+	  id_planet(pl), narmies);
+}
+
+void
+tlog_res(pl, resource)
+  struct planet *pl;
+  char *resource;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\tresgrow %s (%s)\n", status->clock,
+	  id_planet(pl), resource);
+}
+
+/* call before changing owner */
+void
+tlog_revolt(pl)
+  struct planet *pl;
+{
+  if (!TOURNEYMODE)
+    return;
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "%ld\trevolt %s\n", status->clock, id_planet(pl));
+}
+
+void
+scan_for_unexpected_tourny_events()
+{
+  int i;
+  for (i = 0; i < MAXPLAYER; i++)
+  {
+    struct player *p = &players[i];
+    if (status_cache[i] != PALIVE)
+    {
+      status_cache[i] = p->p_status;
+      ship_cache[i] = -1;
+      continue;
+    }
+
+    if (p->p_status != PALIVE)
+    {
+      tlog_plquit(p, 0, 0);
+      status_cache[i] = p->p_status;
+    }
+    else if (ship_cache[i] < 0)
+    {
+      ship_cache[i] = p->p_ship.s_type;
+    }
+    else if (ship_cache[i] != p->p_ship.s_type)
+    {
+      tlog_refit(p);
+    }
+  }
+}
+
+/*
+ * end of T log procs
+ * 
+ */
+
+
+void
+closetlog()
+{
+  if (tlog != NULL)
+  {
+    fprintf(tlog, "\n\nCLOSING TOURNAMENT LOG\n\n\n\n");
+    fclose(tlog);
+  }
+  tlog = NULL;
+}
+
+
+void
+tlog_all()
+{
+  int i;
+  struct planet *pl;
+
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "The time is: %ld ----------------\n", status->clock);
+  for (i = 0, pl = &planets[i]; i < NUMPLANETS; i++, pl++)
+    fprintf(tlog, "Planet: %s  %x  %s  -- armies %d\n", pl->pl_name,
+	    pl->pl_flags, teams[pl->pl_owner].shortname, pl->pl_armies);
+}
+
+void
+tlog_conquerline(line)
+  char *line;
+{
+  if (!tlog)
+    return;
+
+  fprintf(tlog, "C:\t%s\n", line);
+}
+
+
+
+
+
+void
+udtourny()
+{
+  int trem;
+  char buf[120];
+  if (!status2->league)
+    return;
+
+  /* server is configured for league play */
+
+  if (status2->league == 1)
+    return;			/* we're still prepping */
+
+  trem = --status2->leagueticksleft;
+
+
+  switch (status2->league)
+  {
+   case 2:			/* the 1-minute pre tourney warm up. */
+    if (trem == SECONDS(5))
+      pmessage("5 seconds to tournament start", -1, MALL, UMPIRE);
+    else if (trem == SECONDS(2))
+      pmessage("Hold on to your hats.  Everybody dies!", -1, MALL, UMPIRE);
+    else if (trem <= 0)
+    {
+      starttourn();
+    }
+    break;
+
+   case 3:			/* full-on T-mode */
+
+    buf[0] = 0;
+    if (trem % MINUTES(20) == 0 ||
+	(trem < MINUTES(20) && 0 == trem % MINUTES(5)) ||
+	(trem < MINUTES(5) && 0 == trem % MINUTES(1)))
+    {
+      sprintf(buf, "There are %d minutes remaining in regulation play",
+	      trem / MINUTES(1));
+    }
+    else if (trem < MINUTES(1) && 0 == trem % SECONDS(10))
+    {
+      sprintf(buf, "There are %d seconds remaining in regulation play",
+	      trem / SECONDS(1));
+    }
+    if (buf[0])
+      pmessage(buf, -1, MALL, UMPIRE);
+    if (trem <= 0)
+      /* maybe go into overtime */
+      endtourn();
+    break;
+   case 4:
+    /* overtime, not implemented */
+    break;
+  }
+}
+
+
+
+void
+starttourn()
+{
+  int i, j;
+  struct planet *pl;
+  char s[80];
+
+  opentlog();
+  for (i = 0, pl = &planets[i]; i < NUMPLANETS; i++, pl++)
+  {
+    for (j = 0; j < MAXTEAM + 1; j++)
+    {
+      pl->pl_tinfo[j].timestamp = 0;
+      /* doesn't work? */
+      pl->pl_hinfo = (PL_TYPE(*pl) == PLSTAR) ? ALLTEAM : pl->pl_owner;
+    }
+  }
+  status->clock = 0;
+
+  explode_everyone(KTOURNSTART, 0);
+
+  tlog_all();
+
+
+  status2->league++;
+  status2->leagueticksleft = MINUTES(configvals->regulation_minutes);
+
+  /* version team names configured time date */
+  pmessage(" ", 0, MALL, UMPIRE);
+  sprintf(s, "Timer started -- %d minutes remaining",
+	  status2->leagueticksleft / MINUTES(1));
+  pmessage(s, 0, MALL, UMPIRE);
+  pmessage(" ", 0, MALL, UMPIRE);
+}
+
+
+void
+endtourn()
+{
+  pmessage(" ", 0, MALL, UMPIRE);
+  pmessage("Time is done", 0, MALL, UMPIRE);
+  pmessage(" ", 0, MALL, UMPIRE);
+
+  /* print damage assesments */
+  endgame_effects(1 << status2->home.index, 1 << status2->away.index, -1);
+
+  scan_for_unexpected_tourny_events();
+
+  tlog_all();
+
+  closetlog();
+
+  /* conquer */
+
+  status2->league = 1;
+
+  /* we should shut the game off here (status->gameup=0) */
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/util.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,123 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+
+#include "config.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <signal.h>
+#include <sys/time.h>
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "shmem.h"
+
+struct player *me;
+struct ship *myship;
+struct stats *mystats;
+
+
+
+/*----------------------------VISIBLE FUNCTIONS---------------------------*/
+
+/*-------------------------------ANGDIST----------------------------------*/
+/*
+ * This function provides the proper angular distance between two angles. The
+ * angles are expressed as numbers from 0-255.
+ */
+
+int
+angdist(x, y)
+  unsigned char x, y;
+{
+  register unsigned char res;	/* temp var */
+
+  res = x - y;			/* get abs value of difference */
+  if (res > 128)		/* if more than 180 degrees */
+    return (256 - (int) res);	/* then choose to go other way around */
+  return ((int) res);		/* else its just the difference */
+}
+
+/*-------------------------------------------------------------------------*/
+
+
+/*
+ * this function checks to see if an occurrence is temporally spaced from the
+ * previous one.  This is useful in preventing the client from firing torps
+ * and missiles too quickly and to limit detting to a reasonable frequency
+ * (detting too fast burns fuel and increases wtemp without any benefit).
+ */
+
+int
+temporally_spaced(lasttime, gap)
+  struct timeval *lasttime;
+  int gap;			/* microseconds */
+{
+  struct timeval curtp;
+
+  gettimeofday(&curtp, (struct timezone *) 0);
+  if ((curtp.tv_sec == lasttime->tv_sec &&
+       curtp.tv_usec < lasttime->tv_usec + gap)
+      || (curtp.tv_sec == lasttime->tv_sec + 1 &&
+	  curtp.tv_usec + 1000000 < lasttime->tv_usec + gap))
+    return 0;
+
+  lasttime->tv_sec = curtp.tv_sec;
+  lasttime->tv_usec = curtp.tv_usec;
+  return 1;
+}
+
+/*
+ */
+
+int
+check_fire_warp()
+{
+  if (configvals->fireduringwarp || !(me->p_flags & PFWARP))
+    return 1;
+
+  warning("Can not fire while in warp.");
+
+  return 0;
+}
+
+int
+check_fire_warpprep()
+{
+  if (configvals->fireduringwarpprep || !me->p_warptime)
+    return 1;
+
+  warning("Can not fire while preparing for warp.");
+
+  return 0;
+}
+
+int
+check_fire_docked()
+{
+  if (configvals->firewhiledocked || !(me->p_flags & PFDOCK))
+    return 1;
+
+  warning("It is unsafe to use weapons while docked.");
+
+  return 0;
+}
+
+
+/*-------END OF FILE--------*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wander2.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,202 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <sys/file.h>
+#include <math.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <errno.h>
+#include <pwd.h>
+#include <ctype.h>
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+
+extern void (*r_signal()) ();
+
+extern struct planet *planets;
+
+#define COS(x) ((x) >= 0.0 ? Cosine[(int)(x)] : Cosine[(int)(-(x))])
+#define SIN(x) ((x) >= 0.0 ? Sine[(int)(x)] : -Sine[(int)(-(x))])
+
+#define PUPDATE 999999
+
+int pl_home[4];
+int pl_core[4][10];
+int pl_dist[4][10];
+double increment = 0.016;
+double incrementrecip = 62.5;
+float *Cosine, *Sine;
+
+double dpre;
+double fpre;
+double pi = 3.1415926;
+
+int planeti, planetj;
+
+/* call only once */
+
+
+void
+pinit()
+{
+  double dx, dy;
+  int i, j;
+
+  int pre;
+
+  void pmove();
+
+  pre = 3.5 / increment;
+  dpre = (double) pre;
+
+  Cosine = (float *) calloc(sizeof(float), pre);
+  Sine = (float *) calloc(sizeof(float), pre);
+  for (i = 0; i < pre; i++)
+  {
+    Cosine[i] = cos((double) i * increment);
+    Sine[i] = sin((double) i * increment);
+  }
+
+  /* openmem(); */
+
+  pl_home[0] = 0;
+  pl_core[0][0] = 5;
+  pl_core[0][1] = 7;
+  pl_core[0][2] = 8;
+  pl_core[0][3] = 9;
+  pl_home[1] = 10;
+  pl_core[1][0] = 12;
+  pl_core[1][1] = 15;
+  pl_core[1][2] = 16;
+  pl_core[1][3] = 19;
+  pl_home[2] = 20;
+  pl_core[2][0] = 24;
+  pl_core[2][1] = 26;
+  pl_core[2][2] = 29;
+  pl_core[2][3] = 25;
+  pl_home[3] = 30;
+  pl_core[3][0] = 34;
+  pl_core[3][1] = 37;
+  pl_core[3][2] = 38;
+  pl_core[3][3] = 39;
+
+  for (i = 0; i < 4; i++)
+  {
+    for (j = 0; j < 4; j++)
+    {
+      dx = (double) (planets[pl_core[i][j]].pl_x - planets[pl_home[i]].pl_x);
+      dy = (double) (planets[pl_home[i]].pl_y - planets[pl_core[i][j]].pl_y);
+      pl_dist[i][j] = isqrt(dx * dx + dy * dy);
+      /* pl_dist[i][j] = 12000; */
+    }
+  }
+
+  planeti = 0;
+  planetj = 0;
+
+#if 0
+  {
+    static struct itimerval udt;
+    r_signal(SIGALRM, pmove);
+
+    udt.it_interval.tv_sec = 0;
+    udt.it_interval.tv_usec = PUPDATE;
+    udt.it_value.tv_sec = 0;
+    udt.it_value.tv_usec = PUPDATE;
+    (void) setitimer(ITIMER_REAL, &udt, (struct itimerval *) 0);
+
+    while (1)
+      pause();
+  }
+#endif
+}
+
+/* call once per second */
+void
+pmove()
+{
+  int i, j;
+  double dir;
+  double dx, dy;
+
+  /*
+   * for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) {
+   */
+  i = planeti;
+  j = planetj;
+  planetj = (planetj + 1) % 4;
+  if (planetj == 0)
+    planeti = (planeti + 1) % 4;
+
+  dir = atan2((double) (planets[pl_core[i][j]].pl_y - planets[pl_home[i]].pl_y),
+	 (double) (planets[pl_core[i][j]].pl_x - planets[pl_home[i]].pl_x));
+  if (dir > pi)
+    dir = dir - 2.0 * pi;
+  if (dir >= 0.0)
+    dir = (dir * incrementrecip + 1.5);
+  else
+    dir = (dir * incrementrecip + 0.5);
+
+
+  planets[pl_core[i][j]].pl_x =
+    planets[pl_home[i]].pl_x +
+    (int) (pl_dist[i][j] * (dx = COS(dir)));
+  planets[pl_core[i][j]].pl_y =
+    planets[pl_home[i]].pl_y +
+    (int) (pl_dist[i][j] * (dy = SIN(dir)));
+  /*
+   * dir = atan2((double) (planets[pl_core[i][j]].pl_y -
+   * planets[pl_home[i]].pl_y), (double) (planets[pl_core[i][j]].pl_x -
+   * planets[pl_home[i]].pl_x));
+   */
+
+  /* planets[pl_core[i][j]].pl_flags |= PLREDRAW; */
+}
+
+/*
+ * } }
+ */
+
+/*
+ * usage(string) char *string; { printf("Usage: %s [-dnnn]\n", string);
+ * printf("  -dnnn  delay nnn 1/10 seconds between frames\n"); }
+ * 
+ * openmem() { extern int errno; int	shmemKey = PKEY; int	shmid; struct
+ * memory	*sharedMemory;
+ * 
+ * errno = 0; shmid = shmget(shmemKey, 0, 0); if (shmid < 0) { if (errno !=
+ * ENOENT) { fprintf(stderr, "shmget\n"); exit(1); } shmid = shmget(shmemKey,
+ * 0, 0); if (shmid < 0) { fprintf(stderr, "Daemon not running\n"); exit (1);
+ * } } sharedMemory = (struct memory *) shmat(shmid, 0, 0); if (sharedMemory
+ * == (struct memory *) -1) { fprintf(stderr, "shared memory\n"); exit (1); }
+ * players = sharedMemory->players; torps = sharedMemory->torps; plasmatorps
+ * = sharedMemory->plasmatorps; planets = sharedMemory->planets; phasers =
+ * sharedMemory->phasers; mctl = sharedMemory->mctl; messages =
+ * sharedMemory->messages; teams = sharedMemory->teams; status =
+ * sharedMemory->status; }
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/warning.c	Sat Dec 06 04:37:05 1997 +0000
@@ -0,0 +1,155 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <signal.h>
+#include <sys/time.h>
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+
+void updateWarnings();
+
+#define WQLEN 8
+#define WARN_GAP 300000		/* microseconds */
+
+/*
+ * * The warning in text will be printed in the warning window. * The message
+ * will last WARNTIME/10 seconds unless another message * comes through and
+ * overwrites it.
+ */
+
+/*
+ * a small buffer of warnings to be sent... we want to space them out, since
+ * warning() is sometimes called in quick succesison
+ */
+
+static struct warning_spacket w_buf[WQLEN];
+static int numw = 0, whichw = 0;
+
+static struct timeval space = {0, 0};
+
+/*-------------------------------VISIBLE FUNCTIONS------------------------*/
+
+/*--------------------------------WARNING---------------------------------*/
+/*
+ * This function sends a warning message to the client, or queues the warning
+ * to be sent a little later if we just sent one.  The warning can be a
+ * maximum of 79 characters plus the delimiter.
+ */
+
+
+extern char *strncpy();
+extern int sendClientPacket();
+
+void
+warning(text)
+  char *text;			/* the warning string */
+{
+  struct warning_spacket warn;	/* warning packet to send warning in */
+  struct warning_spacket *wp;
+  int t;
+
+  t = temporally_spaced(&space, WARN_GAP);
+  if (!numw && t)
+  {
+    /* don't need to queue it */
+    warn.type = SP_WARNING;	/* set the type */
+    strncpy(warn.mesg, text, 80);	/* copy message into packet */
+    warn.mesg[79] = '\0';	/* chop message to 79 chars + delimeter */
+    sendClientPacket((struct player_spacket *) & warn);	/* send the warning
+							 * packet */
+  }
+  else
+  {
+    /* first check to see if this warning has already been queued */
+    if (!strcmp(text, w_buf[(whichw + numw - 1) % WQLEN].mesg))
+      return;
+
+    wp = &w_buf[(whichw + numw) % WQLEN];
+
+    wp->type = SP_WARNING;
+    strncpy(wp->mesg, text, 80);
+    wp->mesg[79] = '\0';
+
+    if (++numw == WQLEN)
+      numw = WQLEN - 1;
+
+    /* This is useful especially if updates/sec is set low */
+    if (t)
+    {				/* then there's been enough time to send
+				 * another one */
+      sendClientPacket((struct player_spacket *) & w_buf[whichw]);
+      whichw = (whichw + 1) % WQLEN;
+      numw--;
+    }
+  }
+}
+
+
+/*---------------------------- UPDATEWARNINGS ---------------------------*/
+/*
+ * Called by updateClient.  Check to see if there are warnings queued, and
+ * send one when enough time has gone by
+ */
+
+void
+updateWarnings()
+{
+  if (!numw)
+    return;			/* nothing queued */
+
+  if (!temporally_spaced(&space, WARN_GAP))
+    return;			/* not time yet */
+
+  /* we're assuming that the entry in w_buf has been properly filled in */
+  sendClientPacket((struct player_spacket *) & w_buf[whichw]);
+
+  whichw = (whichw + 1) % WQLEN;
+  numw--;
+}
+
+/*------------------------------ IMM_WARNING ----------------------------*/
+
+/*
+ * This sends a warning, bypassing the time-interval check.  Used for
+ * messages that give continuous updates (like bomb and beam messages) that
+ * are sent more frequently then the time interval allows.
+ */
+
+void
+imm_warning(text)
+  char *text;
+{
+  struct warning_spacket warn;
+
+  warn.type = SP_WARNING;
+  strncpy(warn.mesg, text, 80);
+  warn.mesg[79] = '\0';
+  sendClientPacket((struct player_spacket *) & warn);
+}
+
+/*------------------------------------------------------------------------*/
+
+
+/*-------END OF FILE-------*/
Binary file src/wm has changed