Mercurial > ~darius > hgwebdir.cgi > paradise_server
changeset 3:cafa94d86546
Initial revision
author | darius |
---|---|
date | Sat, 06 Dec 1997 04:37:01 +0000 |
parents | 2719a89505ba |
children | aa38447a4b21 |
files | src/defs.h src/dutil.c |
diffstat | 2 files changed, 750 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/defs.h Sat Dec 06 04:37:01 1997 +0000 @@ -0,0 +1,388 @@ +/*-------------------------------------------------------------------------- +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 defs_h_ +#define defs_h_ + + +#ifdef SVR4 /* to get it to work under Solaris [BDyess] */ +#define sigsetmask sigset +#endif /* SVR4 */ + +#define MAXPLAYER 32 + +#define MAXPLANETS 60 /* A new variable called NUMPLANETS takes the + * place of this #define in many parts of the + * code -- this one just sets the initial + * array sizes, so it is, literally, a + * maximum */ + +#define MAX_GWIDTH 200000 /* GWIDTH is used in most of the code -- this + * is a max value. */ +#define TGRID_GRANULARITY 800 /* The width and height, in the same units as + * GWIDTH, of one terrain_grid unit. */ +#define NTERRAIN 128 /* number of bytes of zipped terrain data to + * send */ +/* at once */ +#define LOG2NTERRAIN 7 /* well, you should be able to figure this + * out */ +#define TERRAIN_MASK NTERRAIN-1 /* NTERRAIN should always be a power of 2, + * otherwise */ +/* updateTerrain() in socket.c will break */ +/* + * NOTE! NTERRAIN can *NEVER* be greater than 128 due to the way the + * structure + */ +/* + * and socket code work. This may eventually be a bummer when higher + * bandwidths + */ +/* + * are around, but for now with me & my linux box, this is just fine. + * Besides, + */ +/* + * preliminary tests show that the gzipped terrain grid to be usually less + * than + */ +/* 350 bytes anyway. */ + +#define TGRID_SIZE (MAX_GWIDTH/TGRID_GRANULARITY) + +#define MAXTORP 8 + +/* Parnes's (Raynfala's) Butt Torp Code */ +/* HALFARC = (0-128), FACTOR = (0-16) */ + +#define TORP_PENALTY_HALFARC myship->s_torp.wtemp_halfarc +#define TORP_PENALTY_FACTOR myship->s_torp.wtemp_factor + +#define NPTHINGIES 8 +#define NGTHINGIES 40 +#define TOTALTHINGIES (MAXPLAYER*NPTHINGIES + NGTHINGIES) +#define MAXPLASMA 1 +#define WINSIDE 500 /* Size of strategic and tactical windows */ +#define BORDER 4 /* border width for option windows */ +#define PSEUDOSIZE 16 +#define CLOAK_PHASES 7 /* number of drawing phases in a cloak + * engage/disengage */ +#define NUMRANKS 18 +#ifdef CASSIUS_ROYALTY +#define NUMROYALRANKS 10 +#else +#define NUMROYALRANKS 5 +#endif +#define GODLIKE (NUMROYALRANKS-2) + +/* These are configuration definitions */ +/* GWIDTH was once a #define, now it's a variable in the configvals */ + +#define WARP1 20 /* warp one will move 20 spaces per update */ +#define SCALE 40 /* Window will be one pixel for 20 spaces */ +#define SHIPDAMDIST 3000 /* At this range, an exploding ship does + * damage */ +#define DETDIST 1800 /* At this range a torp can be detonated */ +/* was 1600. 6/29/92 TC */ +/* was 1800 8/1/92 TC */ +#define NEWDETDIST 1800 + +#define PHASEDIST 6000 /* At this range a player can do damage with + * phasers -- outdated */ +#define ENTORBDIST 900 /* At this range a player can orbit a planet */ +#define ORBDIST 800 /* A player will orbit at this radius */ +#define FORBDIST 7500 /* The radius at which fighters patrol */ +#define ORBSPEED 2 /* This is the fastest a person can go into + * orbit */ +#define PFIREDIST 1500 /* At this range a planet will shoot at a + * player */ + +#define MIN_AST_DAMAGE 10 /* the minimum damage caused by an asteroid */ +#define VAR_AST_DAMAGE 5 /* the max additional damage caused by an + * asteroid per speed factor */ +#define MIN_AST_HIT 2 /* the minimum chance of hitting an asteroid */ + +#define TORP_HIT_AST 8 +#define PLASMA_HIT_AST 12 /* percent for asteroid collisions. */ +#define FIGHTER_HIT_AST 3 +#define MISSILE_HIT_AST 5 + +#define VACANT -1 /* indicates vacant port on a starbase */ +#define PDAMAGE -2 /* indicates damaged port on a starbase */ +#define DOCKDIST 600 + +#define TRACTDIST 6000 /* maximum effective tractor beam range */ + +#define TICKSPERSEC 10 /* clock ticks per second */ +#define UPDATE (1000000/TICKSPERSEC) /* Update time is 100000 + * micro-seconds */ +#define AUTOQUIT 60 /* auto logout in 60 secs */ +#define SECONDS(s) (TICKSPERSEC*s) +#define MINUTES(s) (60*SECONDS(s)) + +/* These are memory sections */ +#define PLAYER 1 +#define MAXMESSAGE 50 +#define MAXREVIEWMESSAGE 20 + +#define rosette(x) ((((x) + 8) / 16) & 15) +/* #define rosette(x) ((((x) + 256/VIEWS/2) / (256/VIEWS) + VIEWS) % VIEWS) */ +/* (((x + 8) / 16 + 16) % 16) */ + +/* These are the teams */ +/* + * Note that I used bit types for these mostly for messages and war status. + * This was probably a mistake. It meant that Ed had to add the 'remap' area + * to map these (which are used throughout the code as the proper team + * variable) into a nice four team deep array for his color stuff. Oh well. + */ +#define NOBODY 0x0 +#define FED 0x1 +#define ROM 0x2 +#define KLI 0x4 +#define ORI 0x8 +#define ALLTEAM (FED|ROM|KLI|ORI) +#define MAXTEAM (ORI) /* was ALLTEAM (overkill?) 6/22/92 TMC */ +#define NUMTEAM 4 +/* + * * These are random configuration variables + */ +#define VICTORY 3 /* Number of systems needed to conquer the + * galaxy */ +#define WARNTIME 30 /* Number of updates to have a warning on the + * screen */ +#define MESSTIME 30 /* Number of updates to have a message on the + * screen */ + +#define BUILD_SB_TIME 30 /* Minutes to rebuild an SB */ +#define BUILD_JS_TIME 15 /* Minutes to rebuild an JS 1-24 bjg */ +#define BUILD_WA_TIME 45 /* Minutes to rebuild an WA 1-24 bjg */ + +#define TARG_PLAYER 0x1 /* Flags for gettarget */ +#define TARG_PLANET 0x2 +#define TARG_CLOAK 0x4 /* Include cloaked ships in search */ +#define TARG_SELF 0x8 + +/* Data files to make the game play across daemon restarts. */ + +#ifdef LEAGUE_SUPPORT +#define PLAYERFILE (status2->league ? "/tmp/tourney.players":"etc/db.players") +#else +#define PLAYERFILE "etc/db.players" +#endif +#define GLOBAL "etc/db.global" +#define PLFILE "etc/planets" +#define MOTD "etc/motd" +#define WCMOTD "etc/motd.wc" /* wrong client message */ +#define CLOSEDMOTD "etc/motd.closed" /* if doesn't exist, MOTD is + * used. */ +#define PICS "etc/conf.pics" +#define NTSERV "bin/ntserv" +#define DAEMON "bin/daemonII" +#define ROBOT "bin/robotII" +#define LOGFILENAME "logs/server.log" +#define CONQFILE "logs/conquer" +#define SYSDEF_FILE "etc/conf.sysdef" +#define RSA_KEY_FILE "etc/rsa.keys" +#define GODLOGFILE "logs/god.log" +#define CLUEPHRASEFILE "etc/cluephrases" +#define MAILCLUECHECK "bin/mailcluecheck" + +/* + * If this isn't defined, the "Count: n players" messages will go into + * logfile, as before. Otherwise, they'll go into this file: + */ +/* #define COUNTFILENAME "logs/countfile" */ + +/* Listen stuff */ +#define METASERVER "metaserver.ecst.csuchico.edu" +#define PORT 2592 /* port to listen on */ + +/* Other stuff that Ed added */ + +#define ABS(a) /* abs(a) */ (((a) < 0) ? -(a) : (a)) +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#define myPlasmaTorp(t) (me->p_no == (t)->pt_owner) +#define myTorp(t) (me->p_no == (t)->t_owner) +#define myMissile(t) (me->p_no == (t)->ms_owner) +#define friendlyPlasmaTorp(t) ((!(me->p_team & (t)->pt_war)) || (myPlasmaTorp(t))) +#define friendlyTorp(t) (((!(me->p_team & (t)->t_war)) && \ + (!(t->t_team & (me->p_swar | me->p_hostile)))) || \ + (myTorp(t))) +#define friendlyMissile(t) (((!(me->p_team & (t)->ms_war)) && \ + (!(t->ms_team & (me->p_swar | me->p_hostile)))) || \ + (myMissile(t))) +#define myPhaser(p) (&phasers[me->p_no] == (p)) +#define friendlyPhaser(p) (me->p_team == players[(p) - phasers].p_team) +#define myPlayer(p) (me == (p)) +#define myPlanet(p) (me->p_team == (p)->pl_owner) +#define friendlyPlayer(p) ((!(me->p_team & \ + ((p)->p_swar | (p)->p_hostile))) && \ + (!((p)->p_team & \ + (me->p_swar | me->p_hostile)))) +#define isAlive(p) ((p)->p_status == PALIVE) +#define friendlyPlanet(p) ((p)->pl_info & me->p_team && \ + !((p)->pl_owner & (me->p_swar | me->p_hostile))) + +#if 0 +#define torpColor(t) \ + (myTorp(t) ? myColor : shipCol[remap[players[(t)->t_owner].p_team]]) +#define plasmatorpColor(t) \ + (myPlasmaTorp(t) ? myColor : shipCol[remap[players[(t)->pt_owner].p_team]]) +#define phaserColor(p) \ + (myPhaser(p) ? myColor : shipCol[remap[players[(p) - phasers].p_team]]) +/* + * Cloaking phase (and not the cloaking flag) is the factor in determining + * the color of the ship. Color 0 is white (same as 'myColor' used to be). + */ +#define playerColor(p) \ + (myPlayer(p) ? \ + (cloak_pixels[0][me->p_cloakphase]) \ + : (cloak_pixels[remap[(p)->p_team]][(p)->p_cloakphase])) +#define planetColor(p) \ + (((p)->pl_info & me->p_team) ? shipCol[remap[(p)->pl_owner]] : unColor) + +#define planetFont(p) \ + (myPlanet(p) ? bfont : friendlyPlanet(p) ? ifont : dfont) +#define shipFont(p) \ + (myPlayer(p) ? bfont : friendlyPlayer(p) ? ifont : dfont) +#endif + +/* + * This macro allows us to time things based upon the SIGALRM signal. Given a + * number of 1/5 seconds, it will return the number of SIGALRMs we will + * receive in that period. + */ +#define efticks(x) ((x)*200000/timerDelay) + +/* + * UDP control stuff + */ +#ifdef GATEWAY +#define UDP_NUMOPTS 11 +#define UDP_GW UDP_NUMOPTS-1 +#else +#define UDP_NUMOPTS 10 +#endif +#define UDP_CURRENT 0 +#define UDP_STATUS 1 +#define UDP_DROPPED 2 +#define UDP_SEQUENCE 3 +#define UDP_SEND 4 +#define UDP_RECV 5 +#define UDP_DEBUG 6 +#define UDP_FORCE_RESET 7 +#define UDP_UPDATE_ALL 8 +#define UDP_DONE 9 +#define COMM_TCP 0 +#define COMM_UDP 1 +#define COMM_VERIFY 2 +#define COMM_UPDATE 3 +#define COMM_MODE 4 /* put this one last */ +#define SWITCH_TCP_OK 0 +#define SWITCH_UDP_OK 1 +#define SWITCH_DENIED 2 +#define SWITCH_VERIFY 3 +#define CONNMODE_PORT 0 +#define CONNMODE_PACKET 1 +#define STAT_CONNECTED 0 +#define STAT_SWITCH_UDP 1 +#define STAT_SWITCH_TCP 2 +#define STAT_VERIFY_UDP 3 +#define MODE_TCP 0 +#define MODE_SIMPLE 1 +#define MODE_FAT 2 +#define MODE_DOUBLE 3 /* put this one last */ + +#define UDP_RECENT_INTR 300 +#define UDP_UPDATE_WAIT 5 /* 5 second wait */ + +/* server version of UDPDIAG */ +/* (change these to "#define UDPDIAG(x) <return>" for smaller & faster code) */ +#define UDPDIAG(x) { if (configvals->udpAllowed > 1) { printf("UDP: "); printf x; }} +#define V_UDPDIAG(x) { if (configvals->udpAllowed > 2) { printf("UDP: "); printf x; }} + +#define FAE_RATE 8 /* The Fighter-Army exchange rate */ +#define FTORP_DAMAGE 50 +#define FTORP_SPEED 12 +#define FTORP_FUSE 40 +#define FTORP_TRACK 1 + +#define RSA_VERSION "RSA v2.0 SERVER" /* String must begin with "RSA v" */ +#define KEY_SIZE 32 +#define RESERVED_SIZE 16 +#define MSG_LEN 80 +#define NAME_LEN 16 +#define KEYMAP_LEN 96 + +struct player; + +void warning( /* char * */ ); +int in_warp( /**/ ); +void get_ship_for_player( /* struct player *me, int s_type */ ); +void switch_special_weapon( /**/ ); +void declare_war( /* int mask */ ); +char *twoletters( /* struct player * */ ); +void updateClient(); + + +/* random number stuff */ +#include <stdlib.h> + +#ifdef HAVE_RAND48 + +#define MAXRAND 2147483648 +extern long lrand48(); +extern void srand48(); +extern double drand48(); + +#else /* HAVE_RAND48 */ + +#ifdef HAVE_RANDOM + +#define MAXRAND 2147483648 +extern long random(); +extern void srandom(); + +#else /* HAVE_RANDOM */ + +#define MAXRAND (RAND_MAX+1) +#define random rand +#define srandom srand +extern int rand(); +#ifdef sparc +extern srand(); +#else +extern void srand(); +#endif + +#endif /* HAVE_RANDOM */ + +#define lrand48 random +#define srand48(s) srandom((int)s) +#define drand48() ((double)random() / (double)MAXRAND) + +#endif /* HAVE_RAND48 */ + + +#endif /* defs_h_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dutil.c Sat Dec 06 04:37:01 1997 +0000 @@ -0,0 +1,362 @@ +/*-------------------------------------------------------------------------- +NETREK II -- Paradise + +Permission to use, copy, modify, and distribute this software and its +documentation, or any derivative works thereof, for any NON-COMMERCIAL +purpose and without fee is hereby granted, provided that this copyright +notice appear in all copies. No representations are made about the +suitability of this software for any purpose. This software is provided +"as is" without express or implied warranty. + + Xtrek Copyright 1986 Chris Guthrie + Netrek (Xtrek II) Copyright 1989 Kevin P. Smith + Scott Silvey + Paradise II (Netrek II) Copyright 1993 Larry Denys + Kurt Olsen + Brandon Gillespie +--------------------------------------------------------------------------*/ + +#include "config.h" +#include <stdio.h> +#include <math.h> +#include <signal.h> +#include <string.h> + +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "daemonII.h" +#include "shmem.h" + +#define friendly(fred, bart) \ + (!(fred->p_team & (bart->p_swar|bart->p_hostile)) && \ + !(bart->p_team & (fred->p_swar|fred->p_hostile))) + +/*--------------------------------KILLMESS--------------------------------*/ + +/* + * This function prints to the messages who killed who. This function now + * adds the way of death onto the end of the kill message. + */ + + +extern void pmessage(); +int get_explode_views(); +#ifndef SYSV /* this is barfing on HP/UX */ +extern int fprintf(); +#endif +extern void killerstats(); +extern void checkmaxkills(); +#ifdef LEAGUE_SUPPORT +extern void tlog_plkill(); +#else +#define tlog_plkill(a,b,c) +#endif +extern void loserstats(); + +void +killmess(victim, killer) + struct player *victim, *killer; /* killee and killer */ +{ + char buf[80]; /* to sprintf into */ + + sprintf(buf, "%s (%s", victim->p_name, twoletters(victim)); + + if (victim->p_armies) + { + if ((victim->p_ship.s_nflags & SFNHASFIGHTERS) && (victim->p_ship.s_type != STARBASE)) + sprintf(buf + strlen(buf), "+%d fighters", + victim->p_ship.s_missilestored); + else + sprintf(buf + strlen(buf), "+%d armies", victim->p_armies); + } + strcat(buf, ")"); + if (killer) + { + sprintf(buf + strlen(buf), " was kill %0.2f for %s (%s)", + killer->p_kills, killer->p_name, + twoletters(killer)); + + if (friendly(victim, killer)) + strcat(buf, "[no credit]"); + + } + else + { + if (victim->p_whydead == KPLANET) + { + sprintf(buf + strlen(buf), " was %s by %s (%s)", + PL_TYPE(planets[victim->p_whodead]) == PLSTAR ? + "burned to a crisp" : "shot down", + planets[victim->p_whodead].pl_name, + teams[planets[victim->p_whodead].pl_owner].shortname); + } + else if (victim->p_whydead == KASTEROID) + sprintf(buf + strlen(buf), " was crushed by an asteroid"); + else + { + strcat(buf, " was killed"); + } + } + switch (victim->p_whydead) + { /* determine why player died */ + case KTORP: + strcat(buf, "[torp]"); + break; + case KPHASER: + strcat(buf, "[phaser]"); + break; + case KSHIP: + strcat(buf, "[explosion]"); + break; + case KPLASMA: + strcat(buf, "[plasma]"); + break; + case KASTEROID: + strcat(buf, "[asteroid]"); + break; + case KPLANET: + switch (PL_TYPE(planets[victim->p_whodead])) + { + case PLSTAR: + strcat(buf, "[star]"); + break; + case PLPLANET: + strcat(buf, "[planet]"); + break; + default: + strcat(buf, "[space rock]"); + break; + } + break; + default: + strcat(buf, "[unknown]"); + } + pmessage(buf, 0, MALL | MKILLA, "GOD->ALL"); +} + + + + +/*-------------------------------VISIBLE FUNCTIONS------------------------*/ + +/*-------------------------------CAUSE_KABOOM------------------------------*/ +/* + * This function sets the victim to explode and sets the counter for the + * explosion views. + */ + +void +cause_kaboom(victim) + struct player *victim; /* which ship to blast to tiny fragments */ +{ + victim->p_status = PEXPLODE; /* set player as exploding */ + victim->p_explode = (short) get_explode_views(victim->p_ship.s_type); +} + +/*------------------------------GET_EXPLODE_VIEWS--------------------------*/ +/* returns the number of ship views for the given ship type */ + +int +get_explode_views(stype) + short stype; +{ + switch (stype) + { + case STARBASE: + case WARBASE: + case JUMPSHIP: + return 2 * SBEXPVIEWS / PLAYERFUSE; /* big kablooey */ + } + return 10 / PLAYERFUSE; /* small kablooey */ +} + +/*------------------------------INFLICT_DAMAGE-----------------------------*/ +/* + * This function is used to inflict damage on a player. If the player dies + * as a result he will be made to explode. The function returns a 1 if the + * victim was killed and a 0 otherwise. If the sp parameter is a zero then + * the victim was damaged by something other than a ship. It is the + * responsibil- ity of the caller to set the whydead field of the victim. + */ + +int +inflict_damage(sp, op, victim, damage, why) + struct player *sp; /* player that inflicted the damage */ + struct player *op; /* other player that could be responsible */ + struct player *victim; /* which ship to victimize */ + int damage; /* how much damage, should be positive */ + int why; /* the source of the damage */ +{ + if (damage < 0) + { /* should not be called with - damage */ + fprintf(stderr, "Attempt to inflict negative damage\n"); + return 0; + } + + if (victim->p_flags & PFSHIELD) + { /* shields up? */ + int penetrated; + /* + * if the server is configured for damage penetration then the shields + * will not absorb all the damage + */ + penetrated = damage * configvals->penetration + * (victim->p_ship.s_maxshield - victim->p_shield) + / (victim->p_ship.s_maxshield); + damage -= penetrated; + + victim->p_shield -= damage; /* damage shields */ + if (victim->p_shield < 0) + { /* we punched through the shield */ + damage = -victim->p_shield; /* excess damage will apply to hull */ + victim->p_shield = 0; /* and zero the shields */ + } + else + damage = 0; + damage += penetrated; /* some of the damage got through the shields */ + } + if (damage > 0) + { + victim->p_damage += damage; /* all damage to hull */ + if (configvals->erosion > 0) + { + float chance = damage * configvals->erosion; + while (chance >= 0.5) + { /* no matter how much you suffer there's a + * chance you can avoid permanent damage */ + if (lrand48() & 0x40) + { + victim->p_ship.s_maxdamage--; /* apply damage to maximum */ + victim->p_damage--; /* instead of current */ + } + chance -= 0.5; + } + if (drand48() < chance) + { + victim->p_ship.s_maxdamage--; /* apply damage to maximum */ + victim->p_damage--; /* instead of current */ + } + } + } + + if (victim->p_damage >= victim->p_ship.s_maxdamage) + { /* victim dead? */ + cause_kaboom(victim); /* make him explode */ + if (sp) + { + victim->p_whydead = why; + if (!friendly(sp, victim) + && sp != victim /* hozers were getting credit for killing + * themselves because they were at war with + their own race */ ) + { + /* if a hostile player was responsible */ + tlog_plkill(victim, sp, op); + if (victim->p_ship.s_type == PATROL) + sp->p_kills += .5 + ((float) victim->p_armies + victim->p_kills) / 10.0; + else + sp->p_kills += 1.0 + ((float) victim->p_armies + victim->p_kills) / 10.0; + killerstats(sp->p_no, victim); /* adjust everyones stats */ + checkmaxkills(sp->p_no); + killmess(victim, sp); + victim->p_whodead = sp->p_no; + } + else if (op && !friendly(op, victim) && op != victim) + { + /* the primary assassin was friendly, check auxiliary killer */ + tlog_plkill(victim, op, sp); + + if (victim->p_ship.s_type == PATROL) + op->p_kills += .5 + ((float) victim->p_armies + victim->p_kills) / 10.0; + else + op->p_kills += 1.0 + ((float) victim->p_armies + victim->p_kills) / 10.0; + killerstats(op->p_no, victim); /* adjust everyones stats */ + checkmaxkills(op->p_no); + killmess(victim, op); + victim->p_whodead = op->p_no; + } + else + { + /* + * give no credit since it was friendly and the auxiliary murderer + * was friendly too + */ + tlog_plkill(victim, sp, (struct player *) 0); + killmess(victim, sp); + victim->p_whodead = sp->p_no; + } + } + loserstats(victim->p_no); + return 1; /* victim died */ + } + else + return 0; /* victim lived */ +} + +/*-------------------------------------------------------------------------*/ + + +struct ranksorter +{ + int pno; + int rank; + float di; + int teammates; +}; + +static struct ranksorter admirals[MAXTEAM]; + +int +enemy_admiral(tno) + int tno; +{ + int teammates; + int pno; + int i; + + for (i = 0; i < MAXTEAM; i++) + { + admirals[i].teammates = 0; + admirals[i].rank = -1; + } + + for (i = 0; i < MAXPLAYER; i++) + { + int team; + struct player *pl; + pl = &players[i]; + + if (pl->p_status == PFREE || + pl->p_team == tno) + continue; + + team = pl->p_team; + admirals[team].teammates++; + + if (pl->p_stats.st_rank < admirals[team].rank) + continue; + if (pl->p_stats.st_rank > admirals[team].rank || + pl->p_stats.st_di > admirals[team].di) + { + admirals[team].pno = i; + admirals[team].rank = pl->p_stats.st_rank; + admirals[team].di = pl->p_stats.st_di; + } + } + + teammates = -1; + pno = 0; + for (i = 0; i < MAXTEAM; i++) + { + if (admirals[i].teammates > teammates) + { + pno = admirals[i].pno; + teammates = admirals[i].teammates; + } + } + return pno; +} + + +/*--------END OF FILE-------*/