# HG changeset patch # User darius # Date 881383025 0 # Node ID 0836fb919dfa604852a8f3c7a9c79ceb4f20985e # Parent 814de70c9f67d5f4c726974cd8028bef21af69e1 First entry of Paradise Server 2.9 patch 10 Beta diff -r 814de70c9f67 -r 0836fb919dfa src/sockio.c --- /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 +#include +#include +#include +#include + +#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; +} diff -r 814de70c9f67 -r 0836fb919dfa src/stats.c --- /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 */ +} diff -r 814de70c9f67 -r 0836fb919dfa src/struct.h --- /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< 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---------*/ diff -r 814de70c9f67 -r 0836fb919dfa src/structdesc.c --- /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 diff -r 814de70c9f67 -r 0836fb919dfa src/structdesc.h --- /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[]; diff -r 814de70c9f67 -r 0836fb919dfa src/sysdefaults.c --- /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 +#include +#include + +#include +#include + +#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-------*/ diff -r 814de70c9f67 -r 0836fb919dfa src/terrain.c --- /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 +#include +#include +#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; + } + } + } + } +} diff -r 814de70c9f67 -r 0836fb919dfa src/terrain.h --- /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(); diff -r 814de70c9f67 -r 0836fb919dfa src/timecheck.c --- /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 +#include +#include + +#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----------*/ diff -r 814de70c9f67 -r 0836fb919dfa src/tool-ds.c --- /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 '\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); +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-heraldry.c --- /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 +#include +#include +#include +#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); +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-hr.c --- /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 +#include +#include +#include +#include +#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("-------------------------------------------------------------------------------"); +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-hs.c --- /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 +#include +#include +#include +#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 -c [-name ] '\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); +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-mes.c --- /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 +#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 [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); + } +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-pl.c --- /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 +#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 "--"; + } +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-promo.c --- /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 +#include +#include +#include + +#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); +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-reset.c --- /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 + +#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; + } +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-trim.c --- /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 +#include +#include +#include +#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--; + } +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-util.c --- /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++]; +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-util.h --- /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 */ ); diff -r 814de70c9f67 -r 0836fb919dfa src/tool-wm.c --- /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 +#include +#include +#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); +} diff -r 814de70c9f67 -r 0836fb919dfa src/tool-xtk.c --- /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 + +#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] '\n\ +\n\ +Where 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 */ +} diff -r 814de70c9f67 -r 0836fb919dfa src/tourny.c --- /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 +#include + +#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 diff -r 814de70c9f67 -r 0836fb919dfa src/util.c --- /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 +#include +#include +#include +#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--------*/ diff -r 814de70c9f67 -r 0836fb919dfa src/wander2.c --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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; } + */ diff -r 814de70c9f67 -r 0836fb919dfa src/warning.c --- /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 +#include +#include +#include +#include +#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-------*/ diff -r 814de70c9f67 -r 0836fb919dfa src/wm Binary file src/wm has changed