Date:	Wednesday January 7, 2004 @ 20:42
Author:	unbelver

Update of /home/netrek/cvsroot/Vanilla/ntserv
In directory swashbuckler.real-time.com:/var/tmp/cvs-serv14253/ntserv

Modified Files:
	daemonII.c 
Log Message:

Added in Psychosis' hockey code running on puck.psychosis.net.
Disabled by default, but useful to keep in the main tree.  3
differences.  

PUCK_FIRST:  Puck process runs first on each update.  Mainly for shots
on edge of shot range.  Puck isn't pressored out before puck notices
that it is shot.

FO_BIAS:  non-scoring team, or team that's more than 5 goals behind
get faceoff advantage.  Advantage settable with FACEOFF_HELP.

SITOUT_HURTS:  Normally a sitout puts you within 5 points of exploding
to avoid cheating.  Undefine this and sitout won't hurt.

--Carlos V.




****************************************

Index: Vanilla/ntserv/daemonII.c
diff -u Vanilla/ntserv/daemonII.c:1.39 Vanilla/ntserv/daemonII.c:1.40
--- Vanilla/ntserv/daemonII.c:1.39	Mon Jul  7 17:19:55 2003
+++ Vanilla/ntserv/daemonII.c	Wed Jan  7 20:42:20 2004
@@ -36,6 +36,22 @@
 #include <sys/stat.h>
 #endif
 
+#ifdef PUCK_FIRST 
+#include <sys/sem.h> 
+/* this is from a semctl man page */
+#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) 
+/* union semun is defined by including <sys/sem.h> */ 
+#else /*__GNU_LIBRARY__ && !__SEM_SEMUN_UNDEFINED */
+/* according to X/OPEN we have to define it ourselves */ 
+union semun {
+   int val;                                   /* value for SETVAL */
+   struct semid_ds *buf;              /* buffer for IPC_STAT, IPC_SET */
+   unsigned short int *array;         /* array for GETALL, SETALL */
+   struct seminfo *__buf;             /* buffer for IPC_INFO */ 
+   }; 
+#endif /*__GNU_LIBRARY__ && !__SEM_SEMUN_UNDEFINED */
+#endif /*PUCK_FIRST*/
+
 #define fuse(X) ((ticks % (X)) == 0)
 #define TOURNEXTENSION 15       /* Tmode gone for 15 seconds 8/26/91 TC */
 #define NotTmode(X) (!(status->tourn) && ((X - tourntimestamp)/10 > TOURNEXTENSION))
@@ -112,6 +128,13 @@
 extern void solicit(int force);
 extern void pmove(void);
 
+#ifdef PUCK_FIRST
+static void signal_puck(void);
+static int pucksem_id;
+static union semun pucksem_arg;
+static struct sembuf pucksem_op[1];
+#endif /*PUCK_FIRST*/
+
 static int debug = 0;
 static int ticks = 0;
 static int tourntimestamp = 0; /* ticks since last Tmode 8/2/91 TC */
@@ -245,6 +268,21 @@
 
    if (start_robot) fork_robot(start_robot);
 
+#ifdef PUCK_FIRST
+    if ((pucksem_id = semget(PUCK_FIRST, 1, 0600 | IPC_CREAT)) != -1 ||
+        (pucksem_id = semget(PUCK_FIRST, 1, 0600)) != -1) 
+    {
+	pucksem_arg.val = 0;
+	pucksem_op[0].sem_num = 0;
+	pucksem_op[0].sem_op = -1;
+	pucksem_op[0].sem_flg = 0;
+    }
+    else 
+    {
+	ERROR(1,("Unable to get puck semaphore."));
+    }
+#endif /*PUCK_FIRST*/
+    
     (void) SIGNAL(SIGALRM, move);
     udt.it_interval.tv_sec = 0;
     udt.it_interval.tv_usec = reality;
@@ -590,6 +628,14 @@
         oldtourn=0;
         status->tourn=0;
     }
+
+#ifdef PUCK_FIRST
+    /* The placement of signal_puck before udplayers() is key.  If udplayers()
+       happens first the puck can be pushed out of range of a valid shot,
+       among other things.  */
+    signal_puck();
+#endif /*PUCK_FIRST */
+
     if (fuse(PLAYERFUSE)) {
         udplayers();
     }
@@ -822,6 +868,8 @@
 		    ERROR(4,("%s: ship in POUTFIT too long (of=%d,wd=%d)\n", 
 			     j->p_mapchars, outfitdelay, j->p_whydead));
 
+                    fflush(stdout);
+
 		    /* Force the player out of the game */
                     saveplayer(j);
                     if (j->p_process > 1) {
@@ -3429,6 +3477,12 @@
     if (!removemem())
         ERROR(1,("exitDaemon: cannot removed shared memory segment"));
 
+#ifdef PUCK_FIRST
+    if(pucksem_id != -1)
+        if (semctl(pucksem_id, 0, IPC_RMID, pucksem_arg) == -1)
+          ERROR(1,("exitDaemon: cannot remove puck semaphore"));
+#endif /*PUCK_FIRST*/
+
     switch(sig){
         case SIGSEGV:
         case SIGBUS:
@@ -4358,6 +4412,52 @@
    }
 }
 #endif
+#ifdef PUCK_FIRST
+void do_nuttin (int sig) { }
+
+/* This has [should have] the daemon wait until the puck has finished by
+   waiting on a semaphore.  Error logging is not entirely useful.
+*/
+static void signal_puck(void)
+{
+    int i;
+    struct player *j;
+    int puckwait = 0;
+    
+    for (i = 0, j = players; i < MAXPLAYER; i++, j++)
+        if (j->p_status != PFREE && j->w_queue == QU_ROBOT &&
+	    strcmp(j->p_name, "Puck") == 0) 
+	{ 
+	    /* Set semaphore to 0 in case there are multiple pucks. Yuck. */
+	    if (pucksem_id != -1 &&
+		semctl(pucksem_id, 0, SETVAL, pucksem_arg) == -1) 
+	    {
+		perror("signal_puck semctl");
+		pucksem_id = -1;
+		/* are there any errors that would 'fix themselves?' */
+	    }
+	    if (kill(j->p_process, SIGALRM) < 0) 
+	    {
+		if (errno == ESRCH) 
+		{
+		    ERROR(1,("daemonII/signal_puck: slot %d missing\n", i));
+		    freeslot(j);
+		}
+	    }
+	    else if (pucksem_id != -1) 
+	    {
+		puckwait = 1;
+	    }
+	}
+    
+    if (puckwait)
+    {
+	SIGNAL(SIGALRM, do_nuttin);
+	semop(pucksem_id, pucksem_op, 1);
+	SIGNAL(SIGALRM, SIG_IGN);
+    }
+}
+#endif /*PUCK_FIRST*/
 
 /*
  * The minor problem here is that the only client update speeds that
@@ -4378,6 +4478,14 @@
         continue;
       if (j->p_process <= 1)
         continue;
+
+#ifdef PUCK_FIRST
+      if (j->p_status != PFREE && j->w_queue == QU_ROBOT &&
+	  strcmp(j->p_name, "Puck") == 0)
+      {
+	  continue; 
+      }
+#endif /*PUCK_FIRST*/
 
       t = j->p_timerdelay;
       if (!t)                   /* paranoia */

_______________________________________________
vanilla-devel mailing list
vanilla-devel at us.netrek.org
https://mailman.real-time.com/mailman/listinfo/vanilla-devel