Update of /cvsroot/netrek/server/Vanilla/robots
In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv28256/robots

Modified Files:
	inl.c newbie.c rmove.c 
Log Message:
merge 2.11.1 from darcs

Index: rmove.c
===================================================================
RCS file: /cvsroot/netrek/server/Vanilla/robots/rmove.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- rmove.c	12 May 2006 03:44:49 -0000	1.3
+++ rmove.c	1 Jun 2006 03:17:26 -0000	1.4
@@ -201,7 +201,7 @@
         (me->p_team != 0)) {
         messAll(me->p_no,roboname,"I'm bored.");
         hostile++;
-        declare_war(ALLTEAM);
+        declare_war(ALLTEAM, 0);
     }
 
     /* Our first priority is to phaser plasma torps in nearby vicinity... */
@@ -739,7 +739,7 @@
     if (target >= 0) {
 	j = &players[target];
 	if (!(me->p_war & j->p_team))
-	    declare_war(players[target].p_team); /* make sure we're at war 7/31/91 TC */
+	    declare_war(players[target].p_team, 0); /* make sure we're at war 7/31/91 TC */
 
 	/* We have an enemy */
 	/* Get his range */

Index: newbie.c
===================================================================
RCS file: /cvsroot/netrek/server/Vanilla/robots/newbie.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- newbie.c	12 May 2006 03:44:49 -0000	1.4
+++ newbie.c	1 Jun 2006 03:17:26 -0000	1.5
@@ -75,6 +75,7 @@
 static int rprog(char *login, char *monitor);
 static void stop_this_bot(struct player * p);
 static void save_armies(struct player *p);
+static int checkpos(void);
 
 static void
 reaper(int sig)
@@ -99,8 +100,8 @@
 
 #ifndef TREKSERVER
     if (gethostname(hostname, 64) != 0) {
-        perror("gethostname");
-        exit(1);
+	 perror("gethostname");
+	 exit(1);
     }
 #else
     strcpy(hostname, TREKSERVER);
@@ -117,7 +118,7 @@
     if (!debug)
         SIGNAL(SIGINT, cleanup);
 
-    class = STARBASE;
+    class = ATT;
     target = -1;                /* no target 7/27/91 TC */
     if ( (pno = pickslot(QU_NEWBIE_DMN)) < 0) {
        printf("exiting! %d\n", pno);
@@ -137,20 +138,42 @@
 
     me->p_pos = -1;                  /* So robot stats don't get saved */
     me->p_flags |= PFROBOT;          /* Mark as a robot */
-    me->p_x = 75000;                 /* displace to on overlooking position */
-    me->p_y = 100;                  /* maybe we should just make it fight? */
+
+#define POSITIONX 55000
+#define POSITIONY 50000
+
+    me->p_x = POSITIONX;                 /* displace to on overlooking position */
+    me->p_y = POSITIONY;                 /* maybe we should just make it fight? */
     me->p_hostile = 0;
     me->p_swar = 0;
     me->p_war = 0;
     me->p_team = 0;     /* indep */
 
     oldmctl = mctl->mc_current;
+
 #ifdef nodef
     for (i = 0; i <= oldmctl; i++) {
         check_command(&messages[i]);
     }
 #endif
 
+#ifdef nodef
+    /* Could make Merlin hostile to everybody, pretty fun */
+    me->p_hostile = (FED | ROM | KLI | ORI); /* WAR! */
+    me->p_swar = (FED | ROM | KLI | ORI); /* WAR! */
+    me->p_war = (FED | ROM | KLI | ORI); /* WAR! */
+#endif
+
+#ifdef nodef
+    /* Could make Merlin friendly and allow docking JKH */
+    /* since he is in the middle of the galaxy */
+    me->p_ship.s_type = STARBASE;    /* kludge to allow docking */
+    me->p_flags |= PFDOCKOK;         /* allow docking */
+    /* Merlin Cloaks when t-mode starts, so this is useless for now */
+    /* It's an interesting bug as all the bots like hunterkiller are */
+    /* also invisible */
+#endif
+
     status->gameup |= GU_NEWBIE;
     queues[QU_NEWBIE_PLR].q_flags |= (QU_REPORT | QU_OPEN);
     queues[QU_NEWBIE_OBS].q_flags |= (QU_REPORT | QU_OPEN);
@@ -168,12 +191,6 @@
 
     me->p_status = PALIVE;              /* Put robot in game */
 
-    /* Only allow Rom/Fed game to make robot team selection easier. */
-    /* Disable this because it breaks on timercide.  The other team
-       needs to come in as a 3rd race after being timercided.
-    queues[QU_PICKUP].tournmask = FED|ROM;
-    */
-
     while (1) {
         PAUSE(SIGALRM);
     }
@@ -183,7 +200,7 @@
 {
     int         shmemKey = PKEY;
     static int no_humans = 0;
-   
+    
     HANDLE_SIG(SIGALRM,checkmess);
     me->p_ghostbuster = 0;         /* keep ghostbuster away */
     if (me->p_status != PALIVE){  /*So I'm not alive now...*/
@@ -210,27 +227,37 @@
             no_humans = 0;
     }
 
-    /* Stop or start a robot. */
 
-    if ((ticks % ROBOEXITWAIT) == 0)
-    {
-        if ((QUPLAY(QU_NEWBIE_PLR) + QUPLAY(QU_NEWBIE_BOT)) > queues[QU_PICKUP].max_slots) {
-                 stop_a_robot();
+    /* Stop a robot. */
+    if ((ticks % ROBOEXITWAIT) == 0) {
+        if ((QUPLAY(QU_NEWBIE_PLR) + QUPLAY(QU_NEWBIE_BOT)) > 
+         	    queues[QU_PICKUP].max_slots) {
+	    stop_a_robot();
 	}
     }
+
+    /* Start a robot */
     if ((ticks % ROBOCHECK) == 0) {
         int next_team;
         num_players(&next_team);
-
-        if (((QUPLAY(QU_NEWBIE_PLR) + QUPLAY(QU_NEWBIE_BOT)) < (queues[QU_PICKUP].max_slots - 1)) && (nb_robots < NB_ROBOTS))
-        {
+	
+        if (((QUPLAY(QU_NEWBIE_PLR) + QUPLAY(QU_NEWBIE_BOT)) < (queues[QU_PICKUP].max_slots - 1)) && (nb_robots < NB_ROBOTS))  {
             if (next_team == FED)
                 start_a_robot("-Tf");
-            else
+            if (next_team == ROM)
                 start_a_robot("-Tr");
+            if (next_team == ORI)
+                start_a_robot("-To");
+            if (next_team == KLI)
+                start_a_robot("-Tk");
         }
     }
 
+    /* Check Merlin's x and y position */
+    if ( (ticks % ROBOCHECK) == 0 ) {
+	checkpos();
+    }
+
     if ((ticks % SENDINFO) == 0) {
         static int alternate = 0;
 
@@ -247,6 +274,41 @@
 
 }
 
+/* assuming this gets called once a second... */
+static int checkpos(void)
+{
+    static int oldx=POSITIONX;
+    static int oldy=POSITIONY;
+    static int moving=0;
+    static int stopped=0;
+
+    /* are we moving? */
+    if ( (me->p_x != oldx) || (me->p_y != oldy) ) {
+	moving=1;
+	stopped=0;
+	oldx=me->p_x;
+	oldy=me->p_y;
+    }
+
+    /* if we stopped moving */
+    /* count how long */
+    if ( (me->p_x == oldx) && (me->p_y == oldy) ) {
+	moving=0;
+	stopped=stopped + 1;
+    }
+
+    /* stopped for sometime now */
+    if ( moving==0 && stopped > 15 ) {
+	/* move us back to overlooking position */
+	if ( me->p_x != POSITIONX )
+	    me->p_x = POSITIONX;
+	if ( me->p_y != POSITIONY )
+	    me->p_y = POSITIONY;
+	stopped=0; /*do we need to reset this? */
+    }
+
+    return 1;
+}
 
 static int is_robots_only(void)
 {
@@ -279,7 +341,7 @@
     int i;
     struct player *j;
 
-    /* Nuke robot from the team with the fewest humans. */
+    /* nuke the first available bot */
     for (i = 0, j = players; i < MAXPLAYER; i++, j++) {
         if (j->p_status == PFREE)
             continue;
@@ -306,6 +368,33 @@
     return 0;
 }
 
+int killrobot(pp_team)
+{
+    struct player *j;
+    int i, keep, kill;
+
+    keep = 0;
+    kill = 0;
+    for (i = 0, j = players; i < MAXPLAYER; i++) {
+        if (j[i].p_status == PFREE)
+            continue;
+        if (j[i].p_status == POBSERV)
+            continue;
+
+        if (strcmp(j[i].p_login,"robot!") == 0) {
+            if (j[i].p_status == PALIVE ) {
+                if (j[i].p_team & pp_team) {
+                    keep = i;
+                    kill = 1;
+                }
+            }
+        }
+    }
+    if (kill == 1)
+        stop_this_bot(&j[keep]);
+    return kill;
+}
+
 static void stop_this_bot(struct player *p) {
     p->p_ship.s_type = STARBASE;
     p->p_whydead=KQUIT;
@@ -339,27 +428,161 @@
 {
     int i;
     struct player *j;
-    int team_count[MAXTEAM+1];
-
+    int tc, team_count[MAXTEAM+1];
+    long int rt;
     int c = 0;
 
     team_count[ROM] = 0;
     team_count[FED] = 0;
+    team_count[ORI] = 0;
+    team_count[KLI] = 0;
+    tc = 0;
 
     for (i = 0, j = players; i < MAXPLAYER; i++, j++) {
         if (j->p_status != PFREE && j->p_status != POBSERV &&
-            !(j->p_flags & PFROBOT))
-            {
-                team_count[j->p_team]++;
-                c++;
-            }
+                !(j->p_flags & PFROBOT)) {
+            team_count[j->p_team]++;
+            c++;
+        }
     }
 
     /* Assign which team gets the next robot. */
-    if (team_count[ROM] > team_count[FED])
-        *next_team = FED;
-    else
-        *next_team = ROM;
+
+    /* Count number of teams */
+    if (team_count[ROM] > 0)
+        tc++;
+    if (team_count[FED] > 0)
+        tc++;
+    if (team_count[KLI] > 0)
+        tc++;
+    if (team_count[ORI] > 0)
+        tc++;
+
+    if (tc == 0) { /* no teams yet, join anybody */
+        rt = random() % 4;
+
+        if (rt==0)
+            *next_team = FED;
+        if (rt==1)
+            *next_team = ROM;
+        if (rt==2)
+            *next_team = KLI;
+        if (rt==3)
+            *next_team = ORI;
+    }
+
+    if (tc == 1) { /* 1 team, join 1 of 2 possible opposing teams */
+        rt = random() % 2;
+
+        if (team_count[FED] > 0) {
+            if (rt == 1) {
+                *next_team = ROM; 
+            }
+            else {
+                *next_team = ORI; 
+            }
+        }
+
+        if (team_count[ROM] > 0) {
+            if (rt == 1) {
+                *next_team = FED; 
+            }
+            else {
+                *next_team = KLI; 
+            }
+        }
+
+        if (team_count[KLI] > 0) {
+            if (rt == 1) {
+                *next_team = ROM; 
+            }
+            else {
+                *next_team = ORI; 
+            }
+        }
+
+        if (team_count[ORI] > 0) {
+            if (rt == 1) {
+                *next_team = FED; 
+            }
+            else {
+                *next_team = KLI; 
+            }
+        }
+
+    }
+
+    if (tc >= 2) { /* 2 or more teams, join opposing team with less members */
+        rt = random()%2;
+
+        if (team_count[FED]>0 && team_count[ROM]>0) {
+            if (team_count[ROM]>team_count[FED])
+                *next_team=FED;
+            else
+                *next_team=ROM;
+        }
+
+        if (team_count[ORI]>0 && team_count[KLI]>0) {
+            if (team_count[KLI]>team_count[ORI])
+                *next_team=ORI;
+            else
+                *next_team=KLI;
+        }
+
+        if (team_count[FED]>0 && team_count[ORI]>0) {
+            if (team_count[ORI]>team_count[FED])
+                *next_team=FED;
+            else
+                *next_team=ORI;
+        }
+
+        if (team_count[ROM]>0 && team_count[KLI]>0) {
+            if (team_count[KLI]>team_count[ROM])
+                *next_team=ROM;
+            else
+                *next_team=KLI;
+        }
+
+    }
+
+    /* 3 or more tourn teams.... */
+    /* kill off bots in teams with less than 4 players */
+    /* re-align *next_team so we don't be polish about it */
+    if (tc >= 3) { /* 3 or more teams */
+        if (team_count[ROM]>=4 && team_count[FED]>=4) {
+            killrobot(KLI);
+            killrobot(ORI);
+            if (team_count[ROM]>team_count[FED])
+                *next_team=FED;
+            else
+                *next_team=ROM;
+        }
+        if (team_count[FED]>=4 && team_count[ORI]>=4) {
+            killrobot(ROM);
+            killrobot(KLI);
+            if (team_count[ORI]>team_count[FED])
+                *next_team=FED;
+            else
+                *next_team=ORI;
+        }
+        if (team_count[ROM]>=4 && team_count[KLI]>=4) {
+            killrobot(FED);
+            killrobot(ORI);
+            if (team_count[KLI]>team_count[ROM])
+                *next_team=ROM;
+            else
+                *next_team=KLI;
+        }
+        if (team_count[KLI]>=4 && team_count[ORI]>=4) {
+            killrobot(FED);
+            killrobot(ROM);
+            if (team_count[KLI]>team_count[ORI])
+                *next_team=ORI;
+            else
+                *next_team=KLI;
+        }
+    }
+
 
     return c;
 }
@@ -400,9 +623,34 @@
     char            command[256];
     int pid;
 
-    sprintf(command, "%s %s %s %s -h %s -p %d -n '%s' -X robot! -b -O -i",
+    /* How Merlin forks a robot
+     * 
+     * RCMD -> remote command, usually "" 
+     * robot_host -> hostname of robot server, usually ""
+     * OROBOT -> robot executable, usually "robot"
+     * team -> whichever team, usually "-Tr" for Roms. 
+     * hostname -> target newbie netrek server
+     * PORT -> usually 3592
+     * namearg() -> Name of the bot, circulates from the namelist above
+     *
+     * So robot command usually looks like:
+     * robot -Tr -h localhost -p 3592 -n Obliterator -X robot! -g -b -0 -i
+     * -Tr join Romulans
+     * -h hostname
+     * -p portname
+     * -n player name
+     * -X login name
+     * -g send the OggV byte to ID self as a robot, the bots use this
+     * -b blind mode, do not listen to anybody
+     * -0 no passwd during login sequence
+     * -i INL mode, sets robot updates to 5 updates per second
+     * -C read commands file, usually ROBOTDIR/og 
+     */
+    sprintf(command, "%s %s %s %s -h %s -p %d -n '%s' -X robot! -g -b -O -i",
             RCMD, robot_host, OROBOT, team, hostname, PORT, namearg() );
-   
+
+    sprintf(command, "%s -C %s",command, COMFILE); 
+
     pid = fork();
     if (pid == -1)
      return;