tAI player code updated to work with new non-blocking network code, and new abilities stuff (particularly new fighting code) - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 3b2d7b0968c354a1b0a9766c35631a75c821737a
 (DIR) parent 3a3b61362f104331e750ca2b3b9b57f2ad08dcbd
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Tue, 10 Apr 2001 19:54:23 +0000
       
       AI player code updated to work with new non-blocking network code, and new
       abilities stuff (particularly new fighting code)
       
       
       Diffstat:
         M ChangeLog                           |       1 +
         M src/AIPlayer.c                      |      91 +++++++++++++++++++++++--------
         M src/curses_client.c                 |      15 ++++++++++++---
         M src/gtk_client.c                    |       2 +-
       
       4 files changed, 83 insertions(+), 26 deletions(-)
       ---
 (DIR) diff --git a/ChangeLog b/ChangeLog
       t@@ -1,4 +1,5 @@
        cvs
       +    - AI players now are at least partially functional
            - Fix for server segfault on invalid short network messages
            - dopewars no longer runs GTK+ setgid
            - "make install" installs dopewars as group "wheel" if "games" is
 (DIR) diff --git a/src/AIPlayer.c b/src/AIPlayer.c
       t@@ -35,7 +35,7 @@
        #if NETWORKING
        #define NUMNAMES      8
        #define MINSAFECASH   300
       -#define MINSAFEHEALTH 40
       +#define MINSAFEHEALTH 140
        
        /* Reserve some space for picking up new guns */
        #define SPACERESERVE  10
       t@@ -54,6 +54,8 @@ void AIPlayerLoop() {
           gchar *pt;
           Player *AIPlay;
           fd_set readfs,writefs;
       +   gboolean ReadOK,QuitRequest;
       +
           AIPlay=g_new(Player,1);
           FirstClient=AddPlayer(0,AIPlay,FirstClient);
           g_message(_("AI Player started; attempting to contact server at %s:%d..."),
       t@@ -62,6 +64,10 @@ void AIPlayerLoop() {
           if (pt) g_error(_("Could not connect to dopewars server\n(%s)\n"
                           "AI Player terminating abnormally."),_(pt));
           AIPlay->fd=ClientSock;
       +
       +   InitAbilities(AIPlay);
       +   SendAbilities(AIPlay);
       +
           AISetName(AIPlay);
           g_message(_("Connection established\n"));
        
       t@@ -73,7 +79,7 @@ void AIPlayerLoop() {
              FD_ZERO(&writefs);
              FD_SET(ClientSock,&readfs);
              if (AIPlay->WriteBuf.DataPresent) FD_SET(ClientSock,&writefs);
       -      if (bselect(ClientSock+1,&readfs,NULL,NULL,NULL)==-1) {
       +      if (bselect(ClientSock+1,&readfs,&writefs,NULL,NULL)==-1) {
                 if (errno==EINTR) continue;
                 printf("Error in select\n"); exit(1);
              }
       t@@ -81,21 +87,24 @@ void AIPlayerLoop() {
                 WriteConnectionBufferToWire(AIPlay);
              }
              if (FD_ISSET(ClientSock,&readfs)) {
       -         pt=bgets(ClientSock);
       -         if (!pt) {
       -            g_print(_("Connection to server lost!\n"));
       -            ShutdownNetwork();
       -            break;
       -         } else {
       +         QuitRequest=FALSE;
       +         ReadOK=ReadConnectionBufferFromWire(AIPlay);
       +
       +         while ((pt=ReadFromConnectionBuffer(AIPlay))!=NULL) {
                    if (HandleAIMessage(pt,AIPlay)) {
       -               g_free(pt);
       -               ShutdownNetwork();
       +               QuitRequest=TRUE;
                       break;
                    }
       -            g_free(pt);
       +         }
       +         if (QuitRequest) break;
       +
       +         if (!ReadOK) {
       +            g_print(_("Connection to server lost!\n"));
       +            break;
                 }
              }
           }
       +   ShutdownNetwork();
           g_print(_("AI Player terminated OK.\n"));
        }
        
       t@@ -112,6 +121,52 @@ void AISetName(Player *AIPlay) {
           g_print(_("Using name %s\n"),GetPlayerName(AIPlay));
        }
        
       +gboolean ShouldRun(Player *AIPlay) {
       +/* Returns TRUE if it would be prudent to run away...           */
       +   gint TotalHealth;
       +
       +   if (TotalGunsCarried(AIPlay)==0) return TRUE;
       +
       +   TotalHealth=AIPlay->Health + AIPlay->Bitches.Carried*100;
       +   return (TotalHealth < MINSAFEHEALTH);
       +}
       +
       +static void HandleCombat(Player *AIPlay,gchar *Msg) {
       +/* Decodes the fighting-related message "Msg", and then decides whether */
       +/* to stand or run...                                                   */
       +   gchar *text;
       +   gchar *AttackName,*DefendName,*BitchName,FightPoint;
       +   int DefendHealth,DefendBitches,BitchesKilled,ArmPercent;
       +   gboolean CanRunHere,Loot,CanFire;
       +
       +   if (HaveAbility(AIPlay,A_NEWFIGHT)) {
       +      ReceiveFightMessage(Msg,&AttackName,&DefendName,&DefendHealth,
       +                          &DefendBitches,&BitchName,&BitchesKilled,
       +                          &ArmPercent,&FightPoint,&CanRunHere,&Loot,
       +                          &CanFire,&text);
       +   } else {
       +      text=Msg;
       +      if (AIPlay->Flags&FIGHTING) FightPoint=F_MSG;
       +      else FightPoint=F_LASTLEAVE;
       +      CanFire = (AIPlay->Flags&CANSHOOT);
       +      CanRunHere=FALSE;
       +   }
       +   PrintAIMessage(text);
       +
       +   if (ShouldRun(AIPlay)) {
       +      if (CanRunHere) {
       +         SendClientMessage(AIPlay,C_NONE,C_FIGHTACT,NULL,"R");
       +      } else {
       +         AIDealDrugs(AIPlay);
       +         AIJet(AIPlay);
       +      }
       +   } else if (FightPoint==F_LASTLEAVE) {
       +      AIJet(AIPlay);
       +   } else {
       +      SendClientMessage(AIPlay,C_NONE,C_FIGHTACT,NULL,"F");
       +   }
       +}
       +
        int HandleAIMessage(char *Message,Player *AIPlay) {
        /* Performs appropriate processing on an incoming network message */
        /* "Message" for AI player "AIPlay". Returns 1 if the game should */
       t@@ -138,15 +193,7 @@ int HandleAIMessage(char *Message,Player *AIPlay) {
                 AISetName(AIPlay);
                 break;
              case C_FIGHTPRINT:
       -         PrintAIMessage(Data);
       -         if (From!=&Noone) {
       -            AIPlay->Flags |= FIGHTING+CANSHOOT;
       -         }
       -         if (TotalGunsCarried(AIPlay)>0 && AIPlay->Health>MINSAFEHEALTH) {
       -            SendClientMessage(AIPlay,C_NONE,C_FIGHTACT,NULL,"F");
       -         } else {
       -            AIJet(AIPlay);
       -         }
       +         HandleCombat(AIPlay,Data);
                 break;
              case C_PRINTMESSAGE:
                 PrintAIMessage(Data);
       t@@ -169,7 +216,7 @@ int HandleAIMessage(char *Message,Player *AIPlay) {
                 tv.tv_sec=AITurnPause;
                 tv.tv_usec=0;
                 bselect(0,NULL,NULL,NULL,&tv);
       -         dpg_print(_("Jetting to %tde with %P cash and %P debt"),
       +         dpg_print(_("Jetting to %tde with %P cash and %P debt\n"),
                        Location[(int)AIPlay->IsAt].Name,AIPlay->Cash,AIPlay->Debt);
                 if (brandom(0,100)<10) AISendRandomMessage(AIPlay);
                 break;
       t@@ -396,7 +443,7 @@ void AIHandleQuestion(char *Data,char AICode,Player *AIPlay,Player *From) {
                 AISendAnswer(AIPlay,From,"Y");
                 break;
              case C_ASKRUNFIGHT:
       -         AISendAnswer(AIPlay,From,AIPlay->Health<MINSAFEHEALTH ? "R" : "F");
       +         AISendAnswer(AIPlay,From,ShouldRun(AIPlay) ? "R" : "F");
                 break;
              case C_ASKBANK:
                 if (RealBank==-1) {
 (DIR) diff --git a/src/curses_client.c b/src/curses_client.c
       t@@ -1167,6 +1167,7 @@ void display_message(char *buf) {
                       addch(' ' | StatsAttr);
                    }
                    addch(ACS_VLINE | StatsAttr);
       +            addch(' ' | TextAttr);
                 }
              }
              return;
       t@@ -1299,10 +1300,18 @@ void print_status(Player *Play,char DispDrug) {
              }
              for (i=0;i<NumDrug;i++) {
                 if (Play->Drugs[i].Carried>0) {
       +/* Display of carried drugs with price (%tde="Opium", etc. by default) */
       +            if (HaveAbility(Play,A_DRUGVALUE)) {
       +               dpg_string_sprintf(text,_("%-7tde  %3d @ %P"),Drug[i].Name,
       +                          Play->Drugs[i].Carried,
       +                          Play->Drugs[i].TotalValue/Play->Drugs[i].Carried);
       +               mvaddstr(3+c,Width/2+3,text->str);
       +            } else {
        /* Display of carried drugs (%tde="Opium", etc. by default) */
       -            dpg_string_sprintf(text,_("%-7tde  %3d"),Drug[i].Name,
       -                               Play->Drugs[i].Carried);
       -            mvaddstr(3+c/2,Width/2+3+(c%2)*17,text->str);
       +               dpg_string_sprintf(text,_("%-7tde  %3d"),Drug[i].Name,
       +                                  Play->Drugs[i].Carried);
       +               mvaddstr(3+c/2,Width/2+3+(c%2)*17,text->str);
       +            }
                    c++;
                 }
              }
 (DIR) diff --git a/src/gtk_client.c b/src/gtk_client.c
       t@@ -977,7 +977,7 @@ void UpdateInventory(struct InventoryWidgets *Inven,
        
              if (Objects[i].Carried > 0) {
                 if (price>0) CanSell=TRUE; else CanDrop=TRUE;
       -         if (HaveAbility(ClientData.Play,A_DRUGVALUE)) {
       +         if (HaveAbility(ClientData.Play,A_DRUGVALUE) && AreDrugs) {
                    titles[1] = dpg_strdup_printf("%d @ %P",Objects[i].Carried,
                                      Objects[i].TotalValue/Objects[i].Carried);
                 } else {