view src/getentry.c @ 5:054275999194

Initial revision
author darius
date Sat, 06 Dec 1997 04:37:03 +0000
parents aa38447a4b21
children
line wrap: on
line source

/*--------------------------------------------------------------------------
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 <sys/types.h>
#include <sys/time.h>
#include "defs.h"
#include "struct.h"
#include "data.h"
#include "packets.h"
#include "shmem.h"

extern int overload;		/* 7/31/91 TC let overloaded join any team */

extern int updateShips();
extern int sendMaskPacket();
int tournamentMask();
extern int briefUpdateClient();
extern int flushSockBuf();
extern int socketPause();
extern int readFromClient();
extern int isClientDead();
extern int exitGame();
#ifndef	IRIX
extern int printf();
#endif
extern int closeUdpConn();
extern unsigned int sleep();
extern int connectToClient();
extern int updateSelf();
extern int sendPickokPacket();
extern int allowed_ship();
extern int time_access();
int deadTeam();
int realNumShips();

#if 1

void
detourneyqueue()
{
  me->p_status = POUTFIT;
  me->p_whydead = KPROVIDENCE;
}

#endif


void
getEntry(team, stype)
  int *team;
  int *stype;
{


  int switching = -1;		/* confirm switches 7/27/91 TC */
  inputMask = CP_OUTFIT;
  for (;;)
  {
    /* updateShips so he knows how many players on each team */
    if (blk_flag)
      updateShips();
    sendMaskPacket(tournamentMask(me->p_team));
    if (blk_flag)
      briefUpdateClient();
    flushSockBuf();
    /* Have we been busted? */
    if (me->p_status == PFREE)
    {
      me->p_status = PDEAD;
      me->p_explode = 600;
    }
    socketPause();
    readFromClient();
    if (isClientDead())
    {
      int i;

      if (noressurect)
	exitGame();
      printf("Ack!  The client went away!\n");
      printf("I will attempt to resurrect him!\n");

      /* UDP fail-safe */
      commMode = COMM_TCP;
      if (udpSock >= 0)
	closeUdpConn();

      /* For next two minutes, we try to restore connection */
      shutdown(sock, 2);
      sock = -1;
      for (i = 0;; i++)
      {
	switch (me->p_status)
	{
	 case PFREE:
	  me->p_status = PDEAD;
	  me->p_explode = 600;
	  break;
	 case PALIVE:
	 case POBSERVE:
	  me->p_ghostbuster = 0;
	  break;
	 case PDEAD:
	  me->p_explode = 600;
	  break;
	 default:
	  me->p_explode = 600;
	  me->p_ghostbuster = 0;
	  break;
	}
	sleep(5);
	if (connectToClient(host, nextSocket))
	  break;
	if (i == 23)
	{
	  printf("Oh well, maybe I'm getting rusty!\n");
	  switch (me->p_status)
	  {
	   case PFREE:
	    break;
	   case PALIVE:
	   case POBSERVE:
	    me->p_ghostbuster = 100000;
	    break;
	   case PDEAD:
	    me->p_explode = 0;
	    break;
	   default:
	    me->p_explode = 0;
	    me->p_ghostbuster = 100000;
	    break;
	  }
	  exitGame();
	}
      }
      printf("A miracle!  He's alive!\n");
      teamPick = -1;
      updateSelf();
      updateShips();
      flushSockBuf();
    }
    if (teamPick != -1)
    {
      if (teamPick < 0 || teamPick > 3)
      {
	warning("Get real!");
	sendPickokPacket(0);
	teamPick = -1;
	continue;
      }
#if 1
      if (!(tournamentMask(me->p_team) & (1 << teamPick)))
      {
	warning("I cannot allow that.  Pick another team");
	sendPickokPacket(0);
	teamPick = -1;
	continue;
      }
#endif

      if (((1 << teamPick) != me->p_team) &&
	  (me->p_team != ALLTEAM))	/* switching teams 7/27/91 TC */
	if ((switching != teamPick)
	    && (me->p_whydead != KGENOCIDE)
#ifdef LEAGUE_SUPPORT
	    && !status2->league
#endif
	  )
	{
	  switching = teamPick;
	  warning("Please confirm change of teams.  Select the new team again.");
	  sendPickokPacket(0);
	  teamPick = -1;
	  continue;
	}
      /* His team choice is ok. */
      if (shipPick < 0 || shipPick >= NUM_TYPES)
      {
	warning("That is an illegal ship type.  Try again.");
	sendPickokPacket(0);
	teamPick = -1;
	continue;
      }
      if (!allowed_ship(1 << teamPick, mystats->st_rank, mystats->st_royal, shipPick))
      {
	sendPickokPacket(0);
	teamPick = -1;
	continue;
      }
      if (shipvals[shipPick].s_nflags & SFNMASSPRODUCED)
      {
	warning("o)utpost, u)tility, or s)tandard?");
	sendPickokPacket(0);
	tmpPick = shipPick;
	continue;
      }
      break;
    }
#if 1
    if (me->p_status == PTQUEUE)
    {
      if (status->tourn)
	detourneyqueue();
      /* You don't time out on the tourney queue */
      me->p_ghostbuster = 0;
    }
#endif
  }
  *team = teamPick;
  if ((shipvals[tmpPick].s_nflags & SFNMASSPRODUCED) &&
      ((shipvals[shipPick].s_numports) || (shipPick == SCOUT)))
  {

    *stype = tmpPick;
    tmpPick = CRUISER;
  }
  else
  {
    *stype = shipPick;
    tmpPick = CRUISER;
  }
  sendPickokPacket(1);
  flushSockBuf();
}




/*------------------------------TOURNAMENTMASK----------------------------*/
/*
 * This function takes the players current team and returns a mask of the
 * teams that the player can join.
 */

int
leaguemask(ishome, idx)
  int ishome;			/* team index */
  int idx;
{
#ifdef LEAGUE_SUPPORT
  if (status2->league == 1)
    return idx_to_mask(ishome);
  else
#endif
    return idx_to_mask(idx);
}

int
tournamentMask(team)
  int team;			/* players current team */
{
  int i;			/* looping var */
  int team1, team2;		/* for getting two possible teams */
  int num1, num2;		/* to hold num players on teams */

  if (!blk_flag)		/* not a paradise client */
    return (0);
  if (status->gameup == 0)	/* if game over, can join no team */
    return (0);
  if (overload)			/* if tester slot then can join */
    return (ALLTEAM);		/* any team */
  if (mustexit)			/* should we force player out */
    return (0);
  if (!time_access())		/* if server closed then can join */
    return (0);			/* no team */

#ifdef LEAGUE_SUPPORT
  /* league stuff */
  if (status2->league)
  {
    if (me->p_homeaway == AWAY)
      return leaguemask(1, status2->away.index);
    else if (me->p_homeaway == HOME)
      return leaguemask(0, status2->home.index);
    else
    {
      warning("You have connected to a league server but aren't on a side.");
      me->p_homeaway = (lrand48() & 1) + 1;	/* dangerous int->enum cast */
      return 0;
    }
    /* NOTREACHED */
  }
#endif
  if (me->p_homeaway != NEITHER)
  {
    warning("You have connected to a non-league server with a league ntserv.");
    me->p_homeaway = NEITHER;
  }

  if (!status->tourn)
  {
    return status2->nontteamlock;
  }

  if (team != ALLTEAM && deadTeam(team))	/* if former team dead */
    team = ALLTEAM;		/* then check all others */
  for (i = 0; i < NUMTEAM; i++)
  {				/* go through all teams and eliminate */
    if ((team & (1 << i)) && (deadTeam(1 << i)))	/* from team var all
							 * teams */
      team &= ~(1 << i);	/* that are dead */
  }
  team1 = 0;			/* no team in team 1 */
  num1 = 0;			/* 0 players on team 1 */
  team2 = 0;			/* no team in team 2 */
  num2 = 0;			/* 0 players on team 2 */
  for (i = 0; i < NUMTEAM; i++)
  {				/* go through all teams */
    if (deadTeam(1 << i))	/* if team is dead then */
      continue;			/* disregard it */
    if (realNumShips(1 << i) >= configvals->tournplayers)
    {				/* enough players */
      if (!team1)		/* if no team in team1 yet */
	team1 = (1 << i);	/* then this will be team 1 */
      else
      {				/* otherwise its team2 */
	team2 = (1 << i);
	num1 = realNumShips(team1);	/* get num players on two teams */
	num2 = realNumShips(team2);
	if (num1 == num2)
	{			/* if teams same size then */
	  if (team & (team1 | team2))	/* if player on one team */
	    return (team & (team1 | team2));	/* let him join same team */
	  return (team1 | team2);	/* otherwise, he can join either */
	}
	else if ((num1 > num2) && (team != team1))
	  return (team2);	/* if slight imabalance */
	else if ((num1 < num2) && (team != team2))
	  return (team1);	/* if slight imbalance */
	else
	{
	  if (ABS(num1 - num2) < 2 || (((num1 > num2) && (team == team2)) ||
				       (num2 > num1 && team == team1)))
	    return (team);
	  else
	    return (team1 | team2);
	}
      }
    }
  }				/* end of for loop */
  return (team);		/* just in case */
}




/*--------------------------------REALNUMSHIPS-----------------------------*/
/*
 * Count the real number of ships on a team.  This function returns a count
 * of all the ships on a team that are not PFREE.
 */

int
realNumShips(owner)
  int owner;			/* the team to check for */
{
  int i;			/* looping var */
  int num;			/* to hold ship count */
  struct player *p;		/* to point to players */

  num = 0;			/* initialize count */
  for (i = 0, p = players; i < MAXPLAYER; i++, p++)
  {
    if ((p->p_status != PFREE) &&
	!(p->p_flags & (PFSNAKE | PFBIRD)) &&
	(p->p_team == owner))
    {
      num++;			/* if ship not free and on our team */
    }
  }
  return (num);			/* retun number of ships */
}




/*----------------------------------DEADTEAM-------------------------------*/
/*
 * This function counts the number of planets that a team owns.  It returns a
 * 1 if the team has no planets, and a 0 if they have at least one planet.
 */

int
deadTeam(owner)
  int owner;			/* team to check for */
{
  int i;			/* looping var */
  struct planet *p;		/* to point to a planets */

  for (i = 0, p = planets; i < NUMPLANETS; i++, p++)
  {
    if (p->pl_owner & owner)	/* if planet owned by team then */
      return (0);		/* found one planet owned by team */
  }
  return (1);			/* no planets found, team is dead */
}

/*-------------------------------------------------------------------------*/





/*---------END OF FILE--------*/