diff src/enter.c @ 2:2719a89505ba

First entry of Paradise Server 2.9 patch 10 Beta
author darius
date Sat, 06 Dec 1997 04:37:01 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/enter.c	Sat Dec 06 04:37:01 1997 +0000
@@ -0,0 +1,515 @@
+/*--------------------------------------------------------------------------
+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 <sys/ipc.h>
+#include <sys/shm.h>
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "shmem.h"
+#include "grid.h"
+
+void auto_peace();
+static void placeIndependent();
+extern int
+pmessage2(			/* char *str, int recip, int group, char
+	      address, unsigned char from */ );
+extern int
+pmessage(			/* char *str, int recip, int group, char
+	     address */ );
+
+
+
+/*------------------------------NUMBER DEFINES-----------------------------*/
+#define INDEP (GWIDTH/3)	/* width of region in the center of galaxy */
+/* that independents can join in */
+
+#define MIN_DIST_FROM_STAR 3000.0	/* min distance from a star that
+					 * enter() */
+/* will place you */
+/*-------------------------------------------------------------------------*/
+
+
+int
+find_start_planet(team, flag)
+  int team, flag;
+{
+  int valid[MAXPLANETS];
+  int nvalid;
+  int i;
+
+  nvalid = 0;
+  for (i = 0; i < NUMPLANETS; i++)
+  {
+    struct planet *pl = &planets[i];
+    if (pl->pl_owner == team && (!flag || pl->pl_flags & flag))
+      valid[nvalid++] = i;
+  }
+  if (nvalid < 1)
+    return -1;
+
+  return valid[lrand48() % nvalid];
+}
+
+
+
+/*------------------------------VISIBLE FUNCTIONS-------------------------*/
+
+#define BOSSMAN		NUMROYALRANKS-1
+#define SIDEKICK	NUMROYALRANKS-2
+#define AMBASSADOR	NUMROYALRANKS-3
+
+#ifdef UFL
+#undef SIDEKICK
+#define SIDEKICK	NUMROYALRANKS-1
+#undef AMBASSADOR
+#define AMBASSADOR	NUMROYALRANKS-1
+#endif
+
+/*--------------------------------PEANUT_GALLERY--------------------------*/
+/*
+ * This function checks too see if certain "important" people have logged in,
+ * and displays a special message to the rest of the players.  As the chief
+ * Paradise hack, I forbid removal of any of the code in this function.
+ * Other names may be added.  If you choose to disregard this, a malefiction
+ * will be leveled upon your head and all of your progeny will be born with
+ * their noses two times too large.
+ */
+
+#define AT_LEAST(rank) if (me->p_stats.st_royal<rank) me->p_stats.st_royal = rank;
+
+
+void
+peanut_gallery()
+{
+  char buf[90];
+
+  if (strcmp(me->p_name, "a fungusamongus") == 0)
+  {				/* that's me! */
+    pmessage2("  ", 0, MALL, "LDDENYS > ", me->p_no);
+    pmessage2("Yikes.  EEK!  Help.  There seems to be a fungus among us!", 0, MALL, "LDDENYS > ", me->p_no);
+    pmessage2("  ", 0, MALL, "LDDENYS > ", me->p_no);
+
+  }
+  else if (strcmp(me->p_name, "Lynx") == 0)
+  {
+    pmessage2("\"GAME OVER MAN, GAME OVER!\"", 0, MALL, "Lynx->ALL ", me->p_no);
+
+  }
+  else if (strcmp(me->p_name, "Hammor") == 0)
+  {
+    pmessage2("Please don't hurt 'em, Hammor!", 0, MALL, "GOD->ALL", me->p_no);
+
+  }
+  else if (strcmp(me->p_name, "Bubbles") == 0)
+  {
+    pmessage2("Whoa!", 0, MALL, "KAOLSEN > ", me->p_no);
+    pmessage2("Dudes.", 0, MALL, "KAOLSEN > ", me->p_no);
+    pmessage2("Cool.", 0, MALL, "KAOLSEN > ", me->p_no);
+
+  }
+  else if (strcmp(me->p_name, "KnightRaven") == 0)
+  {
+    pmessage2("Insert Heiji quote here", 0, MALL, "KAOLSEN > ", me->p_no);
+    AT_LEAST(AMBASSADOR);
+
+  }
+  else if (strcmp(me->p_name, "wibble") == 0)
+  {
+    pmessage("No mountain is unclimbable, no river uncrossable, no client RSA"
+	     ,0, MALL, "EGO->wibble", me->p_no);
+    pmessage("key unbreakable.  We can just make it bloody difficult!",
+	     0, MALL, "EGO->wibble", me->p_no);
+
+  }
+  else if (strcmp(me->p_name, "Key") == 0)
+  {
+    time_t curtime;
+    struct tm *tmstruct;
+    int hour;
+
+    (void) time(&curtime);
+    tmstruct = localtime(&curtime);
+    if (!(hour = tmstruct->tm_hour % 12))
+      hour = 12;
+
+    sprintf(buf, "It's %d:%02d%s, time [for me] to die.", hour,
+	    tmstruct->tm_min, tmstruct->tm_hour >= 12 ? "pm" : "am");
+    pmessage(buf, 0, MALL, "GOD->ALL", me->p_no);
+
+  }
+  else if (strcmp(me->p_name, "MikeL") == 0)
+  {
+    pmessage("<This space for rent>", 0, MALL, "GOD->ALL", me->p_no);
+
+
+  }
+  else if (strcmp(me->p_name, "Bolo") == 0)
+  {
+    pmessage("Bolo Mk. MCLXVII On-line.", 0, MALL, MSERVA, me->p_no);
+  }
+}
+
+
+
+void
+advertise_tourney_queue()
+{
+  char buf[80], addrbuf[10];
+  int count = 0;
+  int i;
+
+  if (status->tourn)
+    return;
+
+  for (i = 0; i < MAXPLAYER; i++)
+  {
+    if (players[i].p_status == PTQUEUE)
+      count++;
+  }
+
+  sprintf(addrbuf, "%s->YOU ", SERVNAME);
+  sprintf(buf, "There %s %d player%s on the tournament queue",
+	  (count == 1) ? "is" : "are", count, (count == 1) ? "" : "s");
+  pmessage(buf, me->p_no, MINDIV, addrbuf);
+}
+
+
+
+
+/*------------------------------------ENTER-------------------------------*/
+/*
+ * This function places a player into the game.  It initializes fields in the
+ * player structure and his ship.  It determines where in the galaxy to put
+ * the player.  This function is also used to place robots and independents.
+ * If tno = 4, then the player is independent.  If it is 5 then the player is
+ * a robot.
+ */
+
+/*
+ * CRD feature: starting planet (for robots) - MAK,  2-Jun-93 Also added
+ * starting planet number as a useful return value.
+ */
+
+int
+enter(tno, disp, pno, s_type, startplanet)
+  int tno;			/* team player is on */
+  int disp;			/* not used, so I used it 7/27/91 TC */
+  int pno;			/* player's number */
+  int s_type;			/* player's ship type */
+  int startplanet;		/* planet to enter near (or -1) */
+{
+  static int lastteam = -1;	/* to hold team of last enter */
+  static int lastrank = -1;	/* to hold rank of last enter */
+  char buf[80];			/* to sprintf into */
+  char buf2[80];		/* to sprintf into */
+  char addrbuf[10];		/* to hold address */
+
+  if ((startplanet < 0) || (startplanet >= NUMPLANETS))
+    startplanet = -1;
+
+  (void) strncpy(me->p_name, pseudo, sizeof(me->p_name));	/* get name */
+  me->p_name[sizeof(me->p_name) - 1] = '\0';	/* delimiet just in case */
+
+  me->p_kills = 0.0;		/* have no kills yet */
+  get_ship_for_player(me, s_type);	/* get the player's ship type */
+
+  if (me->p_ship.s_nflags & SFNHASFIGHTERS)
+    me->p_ship.s_missilestored = 0;
+
+  me->p_docked = 0;		/* not docked to anyone */
+  me->p_updates = 0;		/* start updating immediately */
+  me->p_flags = PFSHIELD;
+  if (allows_docking(me->p_ship))
+    me->p_flags |= PFDOCKOK;	/* enable docking */
+  me->p_dir = 0;		/* direction angle of zero */
+  me->p_desdir = 0;		/* desired direction of zero */
+  me->p_speed = 0;		/* speed of zero */
+  me->p_desspeed = 0;		/* desired speed of zero */
+  me->p_subspeed = 0;		/* fractional part of speed zero */
+
+  /* Gunboat docked to ships stuff */
+  if ((me->p_ship.s_nflags & SFNMASSPRODUCED) &&
+      (shipvals[shipPick].s_numports))
+  {
+    int i;
+
+    me->p_team = (1 << tno);
+    for (i = 0; i < MAXPLAYER; i++)
+      if ((players[i].p_ship.s_type == shipPick) &&
+	  (players[i].p_team == me->p_team) &&
+	  (players[i].p_status == PALIVE) &&	/* if all this stuff... */
+	  (players[i].p_flags & PFDOCKOK) &&
+	  (players[i].p_docked < players[i].p_ship.s_numports) &&
+	  (players[i].p_ship.s_missilestored))
+      {
+	me->p_x = players[i].p_x;	/* ...dock em on */
+	me->p_y = players[i].p_y;
+	newdock(i);
+	if (players[i].p_ship.s_missilestored != -1)
+	  players[i].p_ship.s_missilestored--;
+	if (players[i].p_flags & PFCLOAK)
+	{
+	  me->p_flags |= PFCLOAK;
+	  me->p_cloakphase = players[i].p_cloakphase;
+	}
+	else
+	  me->p_cloakphase = 0;
+	break;
+      }
+  }
+  /* End Gunboat stuff */
+
+  if ((tno == 4) || (tno == 5))
+  {				/* if player indep or a robot */
+    me->p_team = 0;		/* he has no team */
+  }
+  else
+  {				/* else player is normal player--find planet */
+    me->p_team = (1 << tno);	/* set players team number */
+
+    /*
+     * forgive me father, for I have used short-circuiting to emulate control
+     * flow
+     */
+    (startplanet >= 0		/* start planet already specified? */
+     || (((startplanet = me->p_lastrefit) >= 0	/* we've got a home planet */
+	  && (planets[startplanet].pl_flags & PLSHIPYARD)	/* and it's a yard */
+	  && (planets[startplanet].pl_owner == me->p_team))	/* and it's ours */
+	 || 0 < (me->p_lastrefit = -1))	/* oops, no more home shipyard, F */
+     || (startplanet = find_start_planet(me->p_team, PLSHIPYARD)) != -1
+     || (startplanet = find_start_planet(me->p_team, PLREPAIR)) != -1
+     || (startplanet = find_start_planet(me->p_team, PLAGRI)) != -1
+     || (startplanet = find_start_planet(me->p_team, PLFUEL)) != -1
+     || (startplanet = find_start_planet(me->p_team, PLHOME)) != -1
+     || (startplanet = find_start_planet(me->p_team, 0)) != -1
+      );
+  }
+  if (startplanet == -1)
+  {
+    placeIndependent();
+  }
+  else
+  {
+    int i;
+    double dx, dy;
+    struct planet *l;
+
+    /* we have a planet */
+    /* use p_x and y as scratch registers */
+    while (1)
+    {
+      me->p_x = planets[startplanet].pl_x + (lrand48() % 10000) - 5000;
+      me->p_y = planets[startplanet].pl_y + (lrand48() % 10000) - 5000;
+      if (me->p_x < 0)		/* can't come in outside of borders */
+	me->p_x = 0;		/* now can we?  */
+      if (me->p_y < 0)
+	me->p_y = 0;
+      if (me->p_x >= GWIDTH)
+	me->p_x = GWIDTH - 1;
+      if (me->p_y >= GWIDTH)
+	me->p_y = GWIDTH - 1;
+      for (i = 0, l = &planets[0]; i < NUMPLANETS; i++, l++)
+      {
+	if (PL_TYPE(*l) == PLSTAR)
+	{
+	  dx = ABS(l->pl_x - me->p_x);
+	  dy = ABS(l->pl_y - me->p_y);
+	  if (dx * dx + dy * dy <
+	      MIN_DIST_FROM_STAR * MIN_DIST_FROM_STAR)
+	    break;
+	}
+      }
+      if (i == NUMPLANETS)
+	break;
+    }
+    /* legitimize p_x and p_y */
+    move_player(me->p_no, me->p_x, me->p_y, 0);
+  }
+  me->p_ntorp = 0;		/* have not fired torps yete */
+  if (!((me->p_ship.s_nflags & SFNMASSPRODUCED) &&
+	(shipvals[shipPick].s_numports)))
+    me->p_cloakphase = 0;	/* no cloaking phase--not cloaked */
+  me->p_nplasmatorp = 0;	/* no plasma torps */
+  me->p_swar = 0;		/* at war with nobody */
+  me->p_armies = 0;		/* carrying no armies */
+  tmpPick = 0;
+
+  switch_special_weapon();
+
+  if (!keeppeace)		/* if keep peace mode then */
+    auto_peace();		/* set do automatic peace */
+  me->p_hostile &= ~me->p_team;	/* hostile to all but own team */
+  me->p_swar &= ~me->p_team;
+#if 0
+  sprintf(buf, "%c%c", teamlet[me->p_team], shipnos[me->p_no]);
+  strncpy(me->p_mapchars, buf, 2);
+#endif
+  if ((lastteam != tno) || (lastrank != mystats->st_rank))
+  {
+    if ((lastteam > 0) && (lastteam < NUMTEAM) && (lastteam != tno))
+      declare_war((1 << lastteam) | me->p_hostile);	/* if changing then
+							 * adjust war stat */
+    lastteam = tno;		/* store team number in static */
+    lastrank = mystats->st_rank;/* store rank in static */
+    sprintf(addrbuf, " %s->ALL", twoletters(me));
+    if ((tno == 4) && (strcmp(me->p_monitor, "Nowhere") == 0))
+    {
+      time_t curtime;		/* if a robot and independent */
+      struct tm *tmstruct;	/* to hold time */
+      int queuesize;		/* to hold queue size */
+      int hour;			/* to hold hour */
+
+      time(&curtime);		/* get the time */
+      tmstruct = localtime(&curtime);	/* convert to local time */
+      if (!(hour = tmstruct->tm_hour % 12))	/* get the hour */
+	hour = 12;
+      sprintf(buf, "It's %d:%02d%s, time to die.", hour, tmstruct->tm_min,
+	      tmstruct->tm_hour >= 12 ? "pm" : "am");
+      if ((queuesize = status->count - status->wait) > 0)
+      {
+	/* lint: queuesize set but not used in function enter */
+	sprintf(buf2, "  Approximate queue size: %d.", status->answer);
+	strcat(buf, buf2);	/* get queue size if queue */
+      }
+      pmessage2(buf, 0, MALL, addrbuf, me->p_no);	/* display message */
+    }
+    else if (tno == 5)
+    {				/* if a robot then */
+      if (players[disp].p_status != PFREE)
+      {
+	sprintf(buf2, "%s has been targeted for termination.",
+		twoletters(&players[disp]));
+	pmessage2(buf2, 0, MALL, addrbuf, me->p_no);
+      }
+    }
+#ifdef LEAGUE_SUPPORT
+    if (!status2->league)	/* no peanut messages in a league game */
+#endif
+      peanut_gallery();		/* check for important people */
+
+    if (me->p_stats.st_royal == 0)
+      sprintf(buf, "%s %.16s is now %2.2s (%.16s@%.32s)",
+	      ranks[me->p_stats.st_rank].name, me->p_name,
+	      twoletters(me), me->p_login, me->p_full_hostname);
+    else
+      sprintf(buf, "%s %.16s is now %2.2s (%.16s@%.32s)",
+	      royal[me->p_stats.st_royal].name, me->p_name,
+	      twoletters(me), me->p_login, me->p_full_hostname);
+
+    pmessage2(buf, 0, MALL | MJOIN, addrbuf, me->p_no);
+
+#if 1
+    advertise_tourney_queue();
+#endif
+
+  }
+  delay = 0;
+  return startplanet;
+}
+
+
+
+
+/*--------------------------------AUTOPEACE------------------------------*/
+/*
+ * This function set the player as hostile to all teams with at least one
+ * player on them if it is t-mode.  Otherwise if it is not t-mode the player
+ * is set as hositle to everyone.
+ */
+
+void
+auto_peace()
+{
+  int i, num[MAXTEAM + 1];	/* to hold team's player counts */
+  struct player *p;		/* looping var */
+
+  num[0] = num[FED] = num[ROM] = num[KLI] = num[ORI] = 0;	/* zero counts */
+  for (i = 0, p = players; i < MAXPLAYER; i++, p++)	/* loop all players */
+    if (p->p_status != PFREE)	/* ince the count of the team the */
+      num[p->p_team]++;		/* player is on */
+  if (status->tourn)		/* if t-mode then make player hostile */
+    me->p_hostile =		/* make all teams with a player on */
+      ((FED * (num[FED] >= configvals->tournplayers)) |
+       (ROM * (num[ROM] >= configvals->tournplayers)) |
+       (KLI * (num[KLI] >= configvals->tournplayers)) |
+       (ORI * (num[ORI] >= configvals->tournplayers)));
+  else				/* else if not t-mode then */
+    me->p_hostile = FED | ROM | KLI | ORI;	/* hostile to everyone */
+}
+
+
+
+
+/*------------------------------PLACEINDEPENDENT---------------------------*/
+/*
+ * This function places an independent player in the game so he is not near
+ * any other players.
+ */
+
+static void
+placeIndependent()
+{
+  int i;			/* ye olde looping var */
+  struct player *p;		/* to point to players */
+  int good, failures;		/* flag for success, count of tries */
+
+  failures = 0;			/* have started loops yet */
+  while (failures < 10)
+  {				/* only try 10 times */
+    me->p_x = GWIDTH / 2 + (lrand48() % INDEP) - INDEP / 2;	/* middle 9th of */
+    me->p_y = GWIDTH / 2 + (lrand48() % INDEP) - INDEP / 2;	/* galaxy */
+    good = 1;
+    for (i = 0, p = players; i < MAXPLAYER; i++, p++)
+    {
+      if ((p->p_status != PFREE) && (p != me))
+      {
+	if ((ABS(p->p_x - me->p_x) < 2 * TRACTDIST) &&
+	    (ABS(p->p_y - me->p_y) < 2 * TRACTDIST))
+	{
+	  failures++;		/* found a player too close */
+	  good = 0;		/* position not good */
+	  break;		/* try another positon */
+	}
+      }
+    }
+    if (good)			/* if good placement found then */
+      return;			/* return */
+  }
+  fprintf(stderr, "Couldn't place the bot successfully.\n");
+}
+
+
+
+
+/*------------------------------------------------------------------------*/
+
+
+
+
+/*----------END OF FILE--------*/