diff src/misc.c @ 4:aa38447a4b21

First entry of Paradise Server 2.9 patch 10 Beta
author darius
date Sat, 06 Dec 1997 04:37:03 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/misc.c	Sat Dec 06 04:37:03 1997 +0000
@@ -0,0 +1,562 @@
+/*--------------------------------------------------------------------------
+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 <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <setjmp.h>
+
+#include "defs.h"
+#include "misc.h"
+#include "struct.h"
+#include "data.h"
+#include "daemonII.h"
+#include "planets.h"
+#include "shmem.h"
+
+/*------------------------------MODULE VARIABLES--------------------------*/
+
+#define	NMESSAGES	16
+/* The list of messages that are sent when t-mode begins.  */
+char *warmessages[] = {
+  "A dark mood settles upon the galaxy as galactic superpowers seek",
+  "to colonize new territory.  Border disputes errupt developing",
+  "into all out intergalactic WAR!!!",
+
+  "Slick Willy is elected president, the bottom falls out of the",
+  "economy, and the pressure to expand rises.",
+
+  "Clinton found with foreign emperor's wife!",
+  "All out war ensues.",
+
+  "Taxes on the rich raised to 80%.",
+  "The rich flee to neigboring empire.",
+  "Democrats demand extradition.",
+  "Foreign emporer refuses.",
+  "Hillary 'Rob Them' Clinton declares war!",
+  "Bill hides out in London.",
+
+  "INTERGALACTIC BEER SHORTAGE!",
+  "CHAOS LIKE IT HAS NEVER BEEN SEEN BEFORE ENSUES!",
+
+  "The American Gladiators hit as the number 1 show on the vid.",
+  "After a gruesome episode, the masses storm out their homes,",
+  "jump in their ships, make a quick stop at their local 7-11",
+  "to grab a few beers, then head out into the galaxy to ",
+  "KICK SOME ASS.  WAR!!!!!!!!!!!!!!!!!!",
+
+  "Khan is resurrected in a bizzare experiment.  Elected as head of",
+  "the Starfleet Council, he removes all pajama-wearing new-age",
+  "hippies from Starfleet.  (And you thought the borg were bad news)",
+
+  "Several members of the computing support staff of the Galactic",
+  "Council are severely injured in a freak skydiving accident.",
+  "The rest are killed.  The network collapses without their",
+  "guidance.  Galactic chaos breaks out!",
+
+  /* oldies */
+  "A dark mood settles upon the galaxy",
+  "Political pressure to expand is rising",
+  "Border disputes break out as political tensions increase!",
+  "Galactic superpowers seek to colonize new territory!",
+  "'Manifest Destiny' becomes motive in galactic superpower conflict!",
+  "Diplomat insults foriegn emperor's mother and fighting breaks out!",
+  "Dan Quayle declares self as galactic emperor and chaos breaks out!",
+  "Peace parties have been demobilized, and fighting ensues.",
+};
+
+
+/*
+ * The starting index of the message series and the number of messages in
+ * series.
+ */
+int warm[NMESSAGES][2] = {
+  {0, 3},
+  {3, 2},
+  {5, 2},
+  {7, 6},
+  {13, 2},
+  {15, 5},
+  {20, 3},
+  {23, 4},
+  {27, 1},
+  {28, 1},
+  {29, 1},
+  {30, 1},
+  {31, 1},
+  {32, 1},
+  {33, 1},
+  {34, 1},
+};
+
+
+/* The set of message series that are displayed when t-mode ends. */
+char *peacemessages[] = {
+  "The expansionist pressure subsides, and temporary agreements are",
+  "reached in local border disputes.",
+  "Peace returns to the galaxy...",
+
+  "Wild mob storms the White House!",
+  "Clinton flees.",
+  "Order returns to the galaxy.",
+
+  "Slick Willy apologizes about incident with foreign emperor's wife.",
+  "Claims he did not penetrate.",
+  "Peace ensues.",
+
+  "The economy goes belly up.  The Democrats are kicked",
+  "out of office, tarred and feathered, and sent to the",
+  "zoo on Rigel 4.  Capitalism is implemented and order",
+  "returns to the empire.",
+
+  "Officials sieze hidden beer stockpiles at the Mackenzie brother's",
+  "house!  The beer shortage is over.  Peace breaks out.",
+
+  "The people decide they would rather sit home and watch",
+  "Al Bundy than fight.  The war comes to an end.",
+
+  "Khan takes a fatal blow to the kidneys when Kirk returns from",
+  "retirement and whacks him in the back with his walker.",
+  "It looks like the hippies are back in control.",
+
+  "Sole survivors of the skydiving accident that took out the",
+  "rest of the computing support staff, Michael McLean and Brad",
+  "Spatz are released from intensive care and rebuild the",
+  "network.  Peace is restored to the Galaxy.",
+
+  /* oldies */
+  "A new day dawns as the oppressive mood lifts",
+  "The expansionist pressure subsides",
+  "Temporary agreement is reached in local border disputes.",
+  "Galactic governments reduce colonization efforts.",
+  "'Manifest Destiny is no longer a fad.' says influential philosopher.",
+  "Diplomat apologizes to foreign emperor's mother and invasion is stopped!",
+  "Dan Quayle is locked up and order returns to the galaxy!",
+  "The peace party has reformed, and is rallying for peace",
+};
+
+
+/*
+ * The starting index of each message series and the number of messages in
+ * the series.
+ */
+int peacem[NMESSAGES][2] = {
+  {0, 3},
+  {3, 3},
+  {6, 3},
+  {9, 4},
+  {13, 2},
+  {15, 2},
+  {17, 3},
+  {20, 4},
+  {24, 1},
+  {25, 1},
+  {26, 1},
+  {27, 1},
+  {28, 1},
+  {29, 1},
+  {30, 1},
+  {31, 1},
+};
+
+
+static int series = 0;		/* the message series that was printed */
+/* when t-mode started.  */
+
+/*------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+
+/*------------------------------VISIBLE FUNCTIONS-------------------------*/
+
+/*---------------------------------WARMESSAGE----------------------------*/
+/*
+ * This function is called when t-mode ensues.  It chooses a message series
+ * and prints it out.  It records the message series in the module's series
+ * variable so that the corresponding peace message series can be printed.
+ */
+
+
+void
+warmessage()
+{
+  int i;			/* to hold index */
+  int n;			/* number of messages in a series */
+
+  i = lrand48() % NMESSAGES;	/* choose message series */
+  series = i;			/* record series number */
+  n = warm[i][1];		/* get number of messages in series */
+  i = warm[i][0];		/* get index of first message */
+  while (n > 0)
+  {				/* print all messages */
+    pmessage(warmessages[i], 0, MALL, "  WAR->  ");
+    n--;			/* dec messages that need to be printed */
+    i++;			/* on to next message */
+  }
+}
+
+
+
+
+/*-------------------------------PEACEMESSAGE-----------------------------*/
+/*
+ * This function prints a peace message series.  It uses the module variable
+ * series to decide which message series to print.
+ */
+
+void
+peacemessage()
+{
+  int i;			/* to hold index */
+  int n;			/* number of messages in a series */
+
+  n = peacem[series][1];	/* get # messages in series */
+  i = peacem[series][0];	/* get starting index */
+  while (n > 0)
+  {				/* print all messages */
+    pmessage(peacemessages[i], 0, MALL, " PEACE-> ");
+    n--;			/* dec messages that need to be printed */
+    i++;			/* on to next message */
+  }
+}
+
+
+
+
+/*-------------------------------REALNUMSHIPS-----------------------------*/
+/*
+ * This function counts the number of ships on a team.  If the race is the
+ * same and the slot is not free, then the ship is counted.
+ */
+
+int
+realNumShips(owner)
+  int owner;
+{
+  int i, num;			/* for looping and counting */
+  struct player *p;		/* to point to a player */
+
+  num = 0;			/* zero the count of ships */
+  for (i = 0, p = players; i < MAXPLAYER; i++, p++)
+    if ((p->p_status != PFREE) && (p->p_team == owner))
+      num++;			/* found a ship on this team, inc count */
+  return (num);			/* return number of ships */
+}
+
+
+
+
+/*------------------------------TOURNAMENTMODE------------------------------*/
+/*
+ * This function counts the number of players on each team and sees if two or
+ * more teams have enough players for t-mode.  It returns a 0 for no team
+ * mode.
+ */
+
+int
+tournamentMode()
+{
+#ifdef LEAGUE_SUPPORT
+  if (status2->league)
+  {
+    return status2->league > 2;
+  }
+  else
+#endif
+  {
+    static int wt = -1;		/* warning time due to team unbalance */
+    static int lct = -1;	/* last check time (ie last pmessage) */
+    char buf[80];		/* temp buffer for tmode halt warning */
+    int i;			/* looping vars */
+    int t[16];			/* to count players with */
+    int counts[4];
+    /* Even though teams go from 0-8, leave */
+    /* this at 16...or bad things might happen */
+    struct player *p;		/* to point to players */
+
+    for (i = 0; i < 16; i++)	/* clear the team players count array */
+      t[i] = 0;
+    for (i = 0, p = players; i < MAXPLAYER; i++, p++)
+    {
+      /* through all players */
+      if (p->p_flags & PFROBOT)
+	continue;		/* robots don't count */
+      switch (p->p_status)
+      {
+       case PFREE:		/* free slots obviously don't count */
+       case POBSERVE:		/* and neither do observers */
+	break;
+
+       case PEXPLODE:
+       case PDEAD:
+       case PTQUEUE:
+	if (p->p_observer)
+	  break;		/* observers in these modes don't count */
+	/* we can fall through here */
+       case POUTFIT:
+       case PALIVE:
+	t[p->p_team]++;
+	break;
+      }
+    }
+
+#if 0
+    /*
+     * If there hasnt been tmode recently (5 mins) clear all kills, and place
+     * any carried armies on the most valuble planet not yet finished.
+     */
+    if ((tourntimestamp - ticks) > 300)
+    {
+      int x;
+      for (x = 0; x < MAXPLAYER; x++)
+      {
+	if (players[x].p_status == PALIVE)
+	{
+	  if (players[x].p_armies > 0)
+	    PlaceLostArmies(players[x]);
+	  players[x].p_kills = 0.00;
+	}
+      }
+    }
+#endif
+
+    i = 0;			/* zero count of # teams with tournplayers */
+    if (t[FED] >= configvals->tournplayers)
+      counts[i++] = t[FED];
+    if (t[ROM] >= configvals->tournplayers)
+      counts[i++] = t[ROM];
+    if (t[KLI] >= configvals->tournplayers)
+      counts[i++] = t[KLI];
+    if (t[ORI] >= configvals->tournplayers)
+      counts[i++] = t[ORI];
+    if (i > 1)
+    {
+      i = counts[0] - counts[1];
+      if (i < 0)
+	i = -i;
+      if (i > 2)
+      {				/* Too big a team imbalance */
+	if (wt == -1)
+	{
+	  wt = status->clock;	/* make a timestamp */
+	  lct = status->clock;	/* used every time it sends the message */
+	}
+	if (((status->clock - wt) < 3) && (lct < status->clock))
+	{
+	  /*
+	   * teams are unblananced, and we havn't said anything for 1 minute,
+	   * warn everybody  Yes these are noisy strings, but I want people
+	   * to notice.
+	   */
+	  pmessage("**************************!! Teams are unbalanced !!**************************", 0, MALL, "");
+	  sprintf(buf, "********************* TMODE WILL BE HALTED IN %li MINUTES **********************", (wt - status->clock) + 3);
+	  pmessage(buf, 0, MALL, "");
+	  pmessage("************************ if this problem isn't fixed *************************", 0, MALL, "");
+	  lct = status->clock;
+	  return (1);
+	}
+	else if ((status->clock - wt) >= 3)
+	{
+	  if (lct < status->clock)
+	  {
+	    pmessage("******************!! TMODE HALTED DUE TO TEAM IMBALANCE !!********************", 0, MALL, "");
+	    pmessage("*********************** Balance teams to resume tmode ************************", 0, MALL, "");
+	    lct = status->clock;
+	  }
+	  return (0);		/* stop tmode */
+	}
+      }
+      else
+      {
+	wt = -1;
+	lct = -1;
+      }
+      return (1);		/* return that we are in team mode */
+    }
+    return (0);			/* we are NOT in T-mode */
+  }
+}
+
+
+
+
+/*------------------------------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, address)
+  char *str;			/* the message */
+  int recip;			/* who is the recipient */
+  int group;			/* group sent to and other flags */
+  char *address;		/* the header attached to front */
+{
+  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", address, str);
+  cur->m_flags |= MVALID;	/* mark message as valid */
+}
+
+/*
+ * send a message from god to a particular player number
+ */
+
+void
+god2player(str, pno)
+  char *str;
+  int pno;
+{
+  struct message *cur;		/* to pnt to where to put message */
+
+  if (++(mctl->mc_current) >= MAXMESSAGE)
+    mctl->mc_current = 0;
+  cur = &messages[mctl->mc_current];
+
+  cur->m_no = mctl->mc_current;
+  cur->m_flags = MINDIV;
+  cur->m_recpt = pno;
+  cur->m_from = 255;
+  sprintf(cur->m_data, "%s->%s %s", SERVNAME, twoletters(&players[pno]), str);
+  cur->m_flags |= MVALID;
+}
+
+
+
+
+/*-------------------------------LOG_MESSAGE------------------------------*/
+/*
+ * This function writes a message into the logfile so the server god can look
+ * at it later.  It is used to record messages to god.
+ */
+
+void
+log_message(msg)
+  char *msg;			/* the string to record */
+{
+  char *path;			/* to hold path and name */
+  FILE *logfile;		/* to open logfile with */
+
+  path = build_path(GODLOGFILE);
+  logfile = fopen(path, "a");	/* let's try to open this baby */
+  if (!logfile)			/* Oops, could not open */
+    return;			/* OUt of Dodge */
+  fputs(msg, logfile);		/* write the string to log file */
+  fclose(logfile);		/* close the sucker up */
+}
+
+
+
+
+/*-----------------------------PARSE_GODMESSAGES----------------------------*/
+/*
+ * This function checks all the new messages in the message buffer to see if
+ * the keyword 'GOD' is at the first of the message.  If it is, then the
+ * message is written to the logfile so the server god can read it.
+ */
+
+void
+parse_godmessages()
+{
+  char buf[100];		/* bigger than message::m_data */
+  static int lastparsed = 0;	/* keeps track of last message */
+
+  while (mctl->mc_current != lastparsed)
+  {				/* Is there a new message? */
+    struct message *cur;	/* to point to message struct */
+    char *s;			/* to point to string */
+
+    if (++lastparsed >= MAXMESSAGE)	/* rollover after end of */
+      lastparsed = 0;		/* message buffer */
+    cur = &messages[lastparsed];/* get new message's struct */
+
+    s = cur->m_data + 1;	/* get new message */
+    while ((*s != ' ') && (*s != 0))	/* go until first space */
+      s++;
+    while ((*s == ' ') && (*s != 0))	/* go past spaces */
+      s++;
+
+    if (!*s)
+      continue;
+    if (cur->m_flags & MGOD)
+    {				/* if it's to god */
+      sprintf(buf, "%s says: %s\n",
+	      (cur->m_from >= 0) ? players[cur->m_from].p_name : "who", s);
+    }
+    else
+    {				/* or labeled to god */
+      if (strncmp(s, "GOD:", 4) != 0)	/* check for 'GOD' keyword */
+	continue;		/* not there, then next message */
+      sprintf(buf, "GOD: %s\n", s + 4);
+    }
+    log_message(buf);		/* go record message */
+  }
+}
+
+/*------------------------------------------------------------------------*/
+#if 0
+/*--------------------------[ PLACE LOST ARMIES ]--------------------------*/
+/*
+ * If for some reason or another the player looses armies they may be
+ * carrying (ghost busts, etc), this function is called, to place the armies
+ * safely on a planet.
+ */
+
+void
+PlaceLostArmies(victim)
+  struct player *victim;
+{
+  char buf[80];
+  int i, startplanet;
+
+  ((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);
+  planets[startplanet].pl_armies += victim->p_armies;
+  (void) sprintf(buf, "%s's %d armies placed on %s",
+	    victim->p_name, victim->p_armies, planets[startplanet].pl_name);
+  pmessage(buf, 0, MALL | MGHOST, MSERVA);
+}
+#endif
+/*------------------------------------------------------------------------*/
+
+/*----------END OF FILE--------*/