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;