tDisplay of opponents' health etc. (GTK+ client) during fights; server-side handling of cops "improved" - 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 a96bd21b0b2002205b654688d053839ca273e99c
 (DIR) parent 5ebfa83f281e86dc72f327e880ab53979dddd460
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Sat,  7 Apr 2001 03:50:21 +0000
       
       Display of opponents' health etc. (GTK+ client) during fights; server-side
       handling of cops "improved"
       
       
       Diffstat:
         M src/curses_client.c                 |       5 +++--
         M src/dopewars.c                      |      16 ++++++++++++----
         M src/dopewars.h                      |       3 ++-
         M src/gtk_client.c                    |     116 +++++++++++++++++++++++++++++--
         M src/message.c                       |      44 +++++++++++++++++++++++++++----
         M src/message.h                       |       6 ++++--
         M src/serverside.c                    |      67 ++++++++++++++++++-------------
         M src/serverside.h                    |       2 +-
       
       8 files changed, 211 insertions(+), 48 deletions(-)
       ---
 (DIR) diff --git a/src/curses_client.c b/src/curses_client.c
       t@@ -1038,7 +1038,7 @@ void DisplayFightMessage(Player *Play,char *text) {
           static int x,y;
           char *textpt;
           int i;
       -   gchar *AttackName,*DefendName;
       +   gchar *AttackName,*DefendName,*BitchName;
           int DefendHealth,DefendBitches,BitchesKilled,ArmPercent;
           gboolean Loot;
        
       t@@ -1056,7 +1056,8 @@ void DisplayFightMessage(Player *Play,char *text) {
           } else {
              if (HaveAbility(Play,A_NEWFIGHT)) {
                 ReceiveFightMessage(text,&AttackName,&DefendName,&DefendHealth,
       -                             &DefendBitches,&BitchesKilled,&ArmPercent,
       +                             &DefendBitches,&BitchName,&BitchesKilled,
       +                             &ArmPercent,
                                     &FightPoint,&RunHere,&Loot,&CanFire,&textpt);
              } else {
                 textpt=text;
 (DIR) diff --git a/src/dopewars.c b/src/dopewars.c
       t@@ -125,7 +125,7 @@ struct METASERVER DefaultMetaServer = {
        };
        int NumTurns=31;
        
       -int PlayerArmour=100,BitchArmour=60;
       +int PlayerArmour=100,BitchArmour=50;
        
        struct GLOBALS Globals[NUMGLOB] = {
           { &Port,NULL,NULL,NULL,"Port",N_("Network port to connect to"),
       t@@ -271,6 +271,12 @@ struct GLOBALS Globals[NUMGLOB] = {
           { &StaticCop.GunIndex,NULL,NULL,NULL,"GunIndex",
             N_("Zero-based index of the gun that cops are armed with"),
             (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL },
       +   { &StaticCop.CopGun,NULL,NULL,NULL,"CopGun",
       +     N_("Number of guns that each cop carries"),
       +     (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL },
       +   { &StaticCop.DeputyGun,NULL,NULL,NULL,"DeputyGun",
       +     N_("Number of guns that each deputy carries"),
       +     (void **)(&Cop),&StaticCop,sizeof(struct COP),"Cop",&NumCop,NULL },
           { NULL,NULL,&StaticDrug.Name,NULL,"Name",
             N_("Name of each drug"),
             (void **)(&Drug),&StaticDrug,
       t@@ -415,9 +421,9 @@ char *DefaultStoppedTo[NUMSTOPPEDTO] = {
        };
        
        struct COP DefaultCop[NUMCOP] = {
       -   { N_("Officer Hardass"),N_("deputy"),N_("deputies"),2,2,30,30,2,8,0 },
       -   { N_("Officer Bob"),N_("deputy"),N_("deputies"),6,4,30,20,4,10,0 },
       -   { N_("Agent Smith"),N_("cop"),N_("cops"),20,6,20,20,6,18,1 }
       +   { N_("Officer Hardass"),N_("deputy"),N_("deputies"),4,3,30,30,2,8,0,1,1 },
       +   { N_("Officer Bob"),N_("deputy"),N_("deputies"),15,4,30,20,4,10,0,2,1 },
       +   { N_("Agent Smith"),N_("cop"),N_("cops"),50,6,20,20,6,18,1,3,2 }
        };
        
        struct GUN DefaultGun[NUMGUN] = {
       t@@ -1151,6 +1157,8 @@ void CopyCop(struct COP *dest,struct COP *src) {
           dest->MinDeputies=src->MinDeputies;
           dest->MaxDeputies=src->MaxDeputies;
           dest->GunIndex=src->GunIndex;
       +   dest->CopGun=src->CopGun;
       +   dest->DeputyGun=src->DeputyGun;
        }
        
        void CopyGun(struct GUN *dest,struct GUN *src) {
 (DIR) diff --git a/src/dopewars.h b/src/dopewars.h
       t@@ -211,6 +211,7 @@ struct COP {
           gint AttackPenalty,DefendPenalty;
           gint MinDeputies,MaxDeputies;
           gint GunIndex;
       +   gint CopGun,DeputyGun;
        };
        extern struct COP DefaultCop[NUMCOP],*Cop;
        
       t@@ -320,7 +321,7 @@ typedef struct tag_serverdata {
           char *Comment,*Version,*Update,*UpSince;
        } ServerData;
        
       -#define NUMGLOB 86
       +#define NUMGLOB 88
        struct GLOBALS {
           int *IntVal;
           price_t *PriceVal;
 (DIR) diff --git a/src/gtk_client.c b/src/gtk_client.c
       t@@ -645,13 +645,18 @@ static GtkWidget *AddFightButton(gchar *Text,GtkAccelGroup *accel_group,
           return button;
        }
        
       +struct combatant {
       +   GtkWidget *name,*bitches,*healthprog,*healthlabel;
       +};
       +
        static void CreateFightDialog() {
       -   GtkWidget *dialog,*vbox,*button,*hbox,*hbbox,*hsep,*text;
       +   GtkWidget *dialog,*vbox,*button,*hbox,*hbbox,*hsep,*text,*table;
           GtkAccelGroup *accel_group;
       +   GArray *combatants;
           gchar *buf;
        
           FightDialog=dialog=gtk_window_new(GTK_WINDOW_DIALOG);
       -   gtk_window_set_default_size(GTK_WINDOW(dialog),450,300);
       +   gtk_window_set_default_size(GTK_WINDOW(dialog),500,300);
           gtk_signal_connect(GTK_OBJECT(dialog),"delete_event",
                              GTK_SIGNAL_FUNC(DisallowDelete),NULL);
           gtk_window_set_default_size(GTK_WINDOW(dialog),240,130);
       t@@ -666,7 +671,22 @@ static void CreateFightDialog() {
        
           vbox=gtk_vbox_new(FALSE,7);
        
       +   table=gtk_table_new(2,4,FALSE);
       +   gtk_table_set_row_spacings(GTK_TABLE(table),5);
       +   gtk_table_set_col_spacings(GTK_TABLE(table),5);
       +
       +   hsep=gtk_hseparator_new();
       +   gtk_table_attach_defaults(GTK_TABLE(table),hsep,0,4,1,2);
       +   gtk_widget_show_all(table);
       +   gtk_box_pack_start(GTK_BOX(vbox),table,FALSE,FALSE,0);
       +   gtk_object_set_data(GTK_OBJECT(dialog),"table",table);
       +
       +   combatants = g_array_new(FALSE,TRUE,sizeof(struct combatant));
       +   g_array_set_size(combatants,1);
       +   gtk_object_set_data(GTK_OBJECT(dialog),"combatants",combatants);
       +
           text=gtk_scrolled_text_new(NULL,NULL,&hbox);
       +   gtk_widget_set_usize(text,150,120);
        
           gtk_text_set_editable(GTK_TEXT(text),FALSE);
           gtk_text_set_word_wrap(GTK_TEXT(text),TRUE);
       t@@ -702,18 +722,101 @@ static void CreateFightDialog() {
           gtk_widget_show(dialog);
        }
        
       +static void UpdateCombatant(gchar *DefendName,int DefendBitches,
       +                            gchar *BitchName,int DefendHealth) {
       +   gint i,RowIndex;
       +   gchar *name;
       +   struct combatant *compt;
       +   GArray *combatants;
       +   GtkWidget *table;
       +   gchar *BitchText,*HealthText;
       +   gfloat ProgPercent;
       +
       +   combatants=(GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog),
       +                                            "combatants");
       +   table=GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog),"table"));
       +   if (!combatants) return;
       +
       +   if (DefendName[0]) {
       +      compt=NULL;
       +      for (i=1,RowIndex=2;i<combatants->len;i++,RowIndex++) {
       +         compt=&g_array_index(combatants,struct combatant,i);
       +         if (!compt || !compt->name) { compt=NULL; continue; }
       +         gtk_label_get(GTK_LABEL(compt->name),&name);
       +         if (name && strcmp(name,DefendName)==0) break;
       +         compt=NULL;
       +      }
       +      if (!compt) {
       +         i=combatants->len;
       +         g_array_set_size(combatants,i+1);
       +         compt=&g_array_index(combatants,struct combatant,i);
       +         gtk_table_resize(GTK_TABLE(table),i+2,4);
       +         RowIndex=i+1;
       +      }
       +   } else {
       +      compt=&g_array_index(combatants,struct combatant,0);
       +      RowIndex=0;
       +   }
       +
       +   BitchText=dpg_strdup_printf(_("%d %tde"),DefendBitches,BitchName);
       +   HealthText=g_strdup_printf(_("Health: %d"),DefendHealth);
       +
       +   ProgPercent=(gfloat)DefendHealth/100.0;
       +
       +   if (compt->name) {
       +      if (DefendName[0]) gtk_label_set_text(GTK_LABEL(compt->name),DefendName);
       +      gtk_label_set_text(GTK_LABEL(compt->bitches),BitchText);
       +      gtk_label_set_text(GTK_LABEL(compt->healthlabel),HealthText);
       +      gtk_progress_bar_update(GTK_PROGRESS_BAR(compt->healthprog),
       +                              ProgPercent);
       +   } else {
       +      compt->name = gtk_label_new(DefendName[0] ? DefendName : _("You"));
       +      gtk_table_attach_defaults(GTK_TABLE(table),compt->name,0,1,
       +                                RowIndex,RowIndex+1);
       +      compt->bitches = gtk_label_new(BitchText);
       +      gtk_table_attach_defaults(GTK_TABLE(table),compt->bitches,1,2,
       +                                RowIndex,RowIndex+1);
       +      compt->healthprog = gtk_progress_bar_new();
       +      gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(compt->healthprog),
       +                                    GTK_PROGRESS_LEFT_TO_RIGHT);
       +      gtk_progress_bar_update(GTK_PROGRESS_BAR(compt->healthprog),
       +                              ProgPercent);
       +      gtk_table_attach_defaults(GTK_TABLE(table),compt->healthprog,2,3,
       +                                RowIndex,RowIndex+1);
       +      compt->healthlabel = gtk_label_new(HealthText);
       +      gtk_table_attach_defaults(GTK_TABLE(table),compt->healthlabel,3,4,
       +                                RowIndex,RowIndex+1);
       +      gtk_widget_show(compt->name);
       +      gtk_widget_show(compt->bitches);
       +      gtk_widget_show(compt->healthprog);
       +      gtk_widget_show(compt->healthlabel);
       +   }
       +
       +   g_free(BitchText); g_free(HealthText);
       +}
       +
       +static void FreeCombatants() {
       +   GArray *combatants;
       +   combatants=(GArray *)gtk_object_get_data(GTK_OBJECT(FightDialog),
       +                                            "combatants");
       +   if (!combatants) return;
       +
       +   g_array_free(combatants,TRUE);
       +}
       +
        void DisplayFightMessage(char *Data) {
           Player *Play;
           gint EditPos;
           GtkAccelGroup *accel_group;
           GtkWidget *Deal,*Fight,*Stand,*Run,*Text;
           char cr[] = "\n";
       -   gchar *AttackName,*DefendName,FightPoint,*Message;
       +   gchar *AttackName,*DefendName,*BitchName,FightPoint,*Message;
           int DefendHealth,DefendBitches,BitchesKilled,ArmPercent;
           gboolean CanRunHere,Loot,CanFire;
        
           if (!Data) {
              if (FightDialog) {
       +         FreeCombatants();
                 gtk_widget_destroy(FightDialog); FightDialog=NULL;
              }
              return;
       t@@ -735,8 +838,11 @@ void DisplayFightMessage(char *Data) {
        
           if (HaveAbility(Play,A_NEWFIGHT)) {
              ReceiveFightMessage(Data,&AttackName,&DefendName,&DefendHealth,
       -                          &DefendBitches,&BitchesKilled,&ArmPercent,
       +                          &DefendBitches,&BitchName,&BitchesKilled,&ArmPercent,
                                  &FightPoint,&CanRunHere,&Loot,&CanFire,&Message);
       +      if (FightPoint==F_HIT || FightPoint==F_ARRIVED || FightPoint==F_MISS) {
       +         UpdateCombatant(DefendName,DefendBitches,BitchName,DefendHealth);
       +      }
              if (FightPoint==F_LASTLEAVE) {
                 Play->Flags&= ~FIGHTING;
              } else {
       t@@ -952,7 +1058,7 @@ static void JetCallback(GtkWidget *widget,gpointer data) {
        
        void JetButtonPressed(GtkWidget *widget,gpointer data) {
           if (ClientData.Play->Flags & FIGHTING) {
       -      DisplayFightMessage("");
       +      DisplayFightMessage(NULL);
           } else {
              Jet();
           }
 (DIR) diff --git a/src/message.c b/src/message.c
       t@@ -1058,6 +1058,7 @@ void SendFightLeave(Player *Play,gboolean FightOver) {
        
        void ReceiveFightMessage(gchar *Data,gchar **AttackName,gchar **DefendName,
                                 int *DefendHealth,int *DefendBitches,
       +                         gchar **BitchName,
                                 int *BitchesKilled,int *ArmPercent,
                                 gchar *FightPoint,gboolean *CanRunHere,
                                 gboolean *Loot,gboolean *CanFire,gchar **Message) {
       t@@ -1068,6 +1069,7 @@ void ReceiveFightMessage(gchar *Data,gchar **AttackName,gchar **DefendName,
           *DefendName=GetNextWord(&pt,"");
           *DefendHealth=GetNextInt(&pt,0);
           *DefendBitches=GetNextInt(&pt,0);
       +   *BitchName=GetNextWord(&pt,"");
           *BitchesKilled=GetNextInt(&pt,0);
           *ArmPercent=GetNextInt(&pt,0);
        
       t@@ -1086,10 +1088,11 @@ void ReceiveFightMessage(gchar *Data,gchar **AttackName,gchar **DefendName,
        
        void SendFightMessage(Player *Attacker,Player *Defender,
                              int BitchesKilled,gchar FightPoint,
       -                      gboolean Loot,gboolean Broadcast,gchar *Msg) {
       +                      price_t Loot,gboolean Broadcast,gchar *Msg) {
           int ArrayInd,ArmPercent,Damage,MaxDamage,i;
           Player *To;
           GString *text;
       +   gchar *BitchName;
        
           if (!Attacker->FightArray) return;
        
       t@@ -1108,12 +1111,28 @@ void SendFightMessage(Player *Attacker,Player *Defender,
              if (!Broadcast && To!=Attacker) continue;
              g_string_truncate(text,0);
              if (HaveAbility(To,A_NEWFIGHT)) {
       -         g_string_sprintf(text,"%s^%s^%d^%d^%d^%d^%c%c%c%c^",
       +         if (Defender) {
       +            if (IsCop(Defender)) {
       +               if (Defender->Bitches.Carried==1) {
       +                  BitchName=Cop[Defender->CopIndex-1].DeputyName;
       +               } else {
       +                  BitchName=Cop[Defender->CopIndex-1].DeputiesName;
       +               }
       +            } else {
       +               if (Defender->Bitches.Carried==1) {
       +                  BitchName=Names.Bitch;
       +               } else {
       +                  BitchName=Names.Bitches;
       +               }
       +            }
       +         } else BitchName="";
       +         g_string_sprintf(text,"%s^%s^%d^%d^%s^%d^%d^%c%c%c%c^",
                                  Attacker==To ? "" : GetPlayerName(Attacker),
                                  (Defender==To || Defender==NULL)
                                               ? "" : GetPlayerName(Defender),
                                  Defender ? Defender->Health : 0,
                                  Defender ? Defender->Bitches.Carried : 0,
       +                          BitchName,
                                  BitchesKilled,ArmPercent,
                                  FightPoint,CanRunHere(To) ? '1' : '0',
                                  Loot ? '1' : '0',
       t@@ -1144,7 +1163,7 @@ void SendFightMessage(Player *Attacker,Player *Defender,
        
        void FormatFightMessage(Player *To,GString *text,Player *Attacker,
                                Player *Defender,int BitchesKilled,int ArmPercent,
       -                        gchar FightPoint,gboolean Loot) {
       +                        gchar FightPoint,price_t Loot) {
           gchar *Armament,*DefendName,*AttackName;
           int Health,Bitches;
           gchar *BitchName,*BitchesName;
       t@@ -1192,10 +1211,23 @@ void FormatFightMessage(Player *To,GString *text,Player *Attacker,
                    g_string_append(text,_("You stand there like a dummy."));
                 }
                 break;
       +      case F_FAILFLEE:
       +         if (AttackName[0]) {
       +            g_string_sprintfa(text,_("%s tries to get away, but fails."),
       +                              AttackName);
       +         } else {
       +            g_string_append(text,_("Panic! You can't get away!"));
       +         }
       +         break;
              case F_LEAVE: case F_LASTLEAVE:
                 if (Attacker->Health>0) {
                    if (AttackName[0]) {
       -               g_string_sprintfa(text,_("%s has got away!"),AttackName);
       +               if (!IsCop(Attacker) && brandom(0,100)<70 && Attacker->IsAt>=0) {
       +                  g_string_sprintfa(text,_("%s has got away to %s!"),AttackName,
       +                                    Location[(int)Attacker->IsAt].Name);
       +               } else {
       +                  g_string_sprintfa(text,_("%s has got away!"),AttackName);
       +               }
                    } else {
                       g_string_sprintfa(text,_("You got away!"));
                    }
       t@@ -1249,7 +1281,9 @@ void FormatFightMessage(Player *To,GString *text,Player *Attacker,
                    } else {
                       g_string_sprintfa(text,_("You hit %s!"),DefendName);
                    }
       -            if (Loot) {
       +            if (Loot>0) {
       +               dpg_string_sprintfa(text,_(" You find %P on the body!"),Loot);
       +            } else if (Loot<0) {
                       g_string_append(text,_(" You loot the body!"));
                    }
                 }
 (DIR) diff --git a/src/message.h b/src/message.h
       t@@ -100,6 +100,7 @@
        #define F_RELOAD       'R'
        #define F_LEAVE        'L'
        #define F_LASTLEAVE    'D'
       +#define F_FAILFLEE     'F'
        #define F_MSG          'G'
        
        void SendClientMessage(Player *From,char AICode,char Code,
       t@@ -168,13 +169,14 @@ void SendOldFightPrint(Player *To,GString *text,gboolean FightOver);
        void SendFightLeave(Player *Play,gboolean FightOver);
        void ReceiveFightMessage(gchar *Data,gchar **AttackName,gchar **DefendName,
                                 int *DefendHealth,int *DefendBitches,
       +                         gchar **BitchName,
                                 int *BitchesKilled,int *ArmPercent,
                                 gchar *FightPoint,gboolean *CanRunHere,
                                 gboolean *Loot,gboolean *CanFire,gchar **Message);
        void SendFightMessage(Player *Attacker,Player *Defender,
                              int BitchesKilled,gchar FightPoint,
       -                      gboolean Loot,gboolean Broadcast,gchar *Msg);
       +                      price_t Loot,gboolean Broadcast,gchar *Msg);
        void FormatFightMessage(Player *To,GString *text,Player *Attacker,
                                Player *Defender,int BitchesKilled,int ArmPercent,
       -                        gchar FightPoint,gboolean Loot);
       +                        gchar FightPoint,price_t Loot);
        #endif
 (DIR) diff --git a/src/serverside.c b/src/serverside.c
       t@@ -300,7 +300,7 @@ void HandleServerMessage(gchar *buf,Player *Play) {
                 i=atoi(Data);
                 if (Play->EventNum==E_FIGHT || Play->EventNum==E_FIGHTASK) {
                    if (CanRunHere(Play)) break;
       -            else RunFromCombat(Play);
       +            else RunFromCombat(Play,i);
                 }
                 if (NumTurns>0 && Play->Turn>=NumTurns && Play->EventNum!=E_FINISH) {
                    FinishGame(Play,_("Your dealing time is up..."));
       t@@ -348,7 +348,7 @@ void HandleServerMessage(gchar *buf,Player *Play) {
                 BuyObject(Play,Data);
                 break;
              case C_FIGHTACT:
       -         if (Data[0]=='R') RunFromCombat(Play); else Fire(Play);
       +         if (Data[0]=='R') RunFromCombat(Play,-1); else Fire(Play);
                 break;
              case C_ANSWER:
                 HandleAnswer(Play,To,Data);
       t@@ -1196,14 +1196,16 @@ void CopsAttackPlayer(Player *Play) {
           FirstServer=AddPlayer(0,Cops,FirstServer);
           SetPlayerName(Cops,Cop[CopIndex-1].Name);
           Cops->CopIndex=CopIndex;
       -   Cops->Cash=Cops->Debt=0;
       +   Cops->Cash=brandom(100,2000);
       +   Cops->Debt=Cops->Bank=0;
        
           NumDeputy=brandom(Cop[CopIndex-1].MinDeputies,
                             Cop[CopIndex-1].MaxDeputies);
           Cops->Bitches.Carried=NumDeputy;
           GunIndex=Cop[CopIndex-1].GunIndex;
           if (GunIndex>=NumGun) GunIndex=NumGun-1;
       -   Cops->Guns[GunIndex].Carried=NumDeputy+1;
       +   Cops->Guns[GunIndex].Carried=(NumDeputy*Cop[CopIndex-1].DeputyGun)+
       +                                Cop[CopIndex-1].CopGun;
           Cops->Health=100;
        
           Play->EventNum++;
       t@@ -1221,12 +1223,16 @@ void AttackPlayer(Player *Play,Player *Attacked) {
        
           if (Play->FightArray && Attacked->FightArray) {
              if (Play->FightArray==Attacked->FightArray) {
       -         g_warning(_("Players are already in a fight!"));
       +         g_error(_("Players are already in a fight!"));
              } else {
       -         g_warning(_("Players are already in separate fights!"));
       +         g_error(_("Players are already in separate fights!"));
              }
              return;
           }
       +   if (NumGun==0) {
       +      g_error(_("Cannot start fight - no guns to use!"));
       +      return;
       +   }
        
           if (!Play->FightArray && !Attacked->FightArray) {
              FightArray = g_ptr_array_new();
       t@@ -1258,7 +1264,7 @@ gboolean IsOpponent(Player *Play,Player *Other) {
        }
        
        void HandleDamage(Player *Defend,Player *Attack,int Damage,
       -                  int *BitchesKilled,gboolean *Loot) {
       +                  int *BitchesKilled,price_t *Loot) {
           Inventory *Guns,*Drugs;
           price_t Bounty;
        
       t@@ -1274,7 +1280,8 @@ void HandleDamage(Player *Defend,Player *Attack,int Damage,
              Defend->Health=0;
           } else if (Defend->Bitches.Carried>0 &&
                      Defend->Health<=Damage) {
       -      LoseBitch(Defend,Guns,Drugs);
       +      if (IsCop(Defend)) LoseBitch(Defend,NULL,NULL);
       +      else LoseBitch(Defend,Guns,Drugs);
              Defend->Health=100;
              *BitchesKilled=1;
           } else {
       t@@ -1290,7 +1297,7 @@ void HandleDamage(Player *Defend,Player *Attack,int Damage,
           }
           Attack->Cash+=Bounty;
           if (Bounty>0 || !IsInventoryClear(Guns,Drugs)) {
       -      *Loot=TRUE;
       +      if (Bounty>0) *Loot=Bounty; else *Loot=-1;
              SendPlayerData(Attack);
           }
           g_free(Guns); g_free(Drugs);
       t@@ -1341,13 +1348,16 @@ void DoReturnFire(Player *Play) {
           }
        }
        
       -void RunFromCombat(Player *Play) {
       +void RunFromCombat(Player *Play,int ToLocation) {
        /* Withdraws player "Play" from combat, and levies any penalties on */
       -/* the player for this cowardly act, if applicable                  */
       +/* the player for this cowardly act, if applicable. If "ToLocation" */
       +/* is >=0, then it identifies the location that the player is       */
       +/* trying to run to.                                                */
           int EscapeProb,RandNum;
           int ArrayInd;
           gboolean FightingCop=FALSE;
           Player *Defend;
       +   char BackupAt;
        
           if (!Play || !Play->FightArray) return;
        
       t@@ -1366,10 +1376,13 @@ void RunFromCombat(Player *Play) {
                 }
                 if (FightingCop) Play->CopIndex--;
              }
       +      BackupAt=Play->IsAt;
       +      Play->IsAt=(char)ToLocation;
              WithdrawFromCombat(Play);
       +      Play->IsAt=BackupAt;
              Play->EventNum=Play->ResyncNum; SendEvent(Play);
           } else {
       -      SendFightMessage(Play,NULL,0,F_MSG,FALSE,FALSE,_("You can't get away!"));
       +      SendFightMessage(Play,NULL,0,F_FAILFLEE,FALSE,TRUE,NULL);
              AllowNextShooter(Play);
              DoReturnFire(Play);
           }
       t@@ -1450,13 +1463,16 @@ static Player *GetFireTarget(Player *Play) {
        }
        
        static int GetArmour(Player *Play) {
       +   int Armour;
           if (IsCop(Play)) {
       -      if (Play->Bitches.Carried==0) return Cop[Play->CopIndex-1].Armour;
       -      else return Cop[Play->CopIndex-1].DeputyArmour;
       +      if (Play->Bitches.Carried==0) Armour=Cop[Play->CopIndex-1].Armour;
       +      else Armour=Cop[Play->CopIndex-1].DeputyArmour;
           } else {
       -      if (Play->Bitches.Carried==0) return PlayerArmour;
       -      else return BitchArmour;
       +      if (Play->Bitches.Carried==0) Armour=PlayerArmour;
       +      else Armour=BitchArmour;
           }
       +   if (Armour==0) Armour=1;
       +   return Armour;
        }
        
        void Fire(Player *Play) {
       t@@ -1465,7 +1481,7 @@ void Fire(Player *Play) {
           int Damage,i,j;
           int AttackRating,DefendRating;
           int BitchesKilled;
       -   gboolean Loot;
       +   price_t Loot;
           gchar FightPoint;
           Player *Defend;
        
       t@@ -1477,14 +1493,15 @@ void Fire(Player *Play) {
        
           Defend = GetFireTarget(Play);
           if (Defend) {
       -      Damage=0; BitchesKilled=0; Loot=FALSE;
       +      Damage=0; BitchesKilled=0; Loot=0;
              if (TotalGunsCarried(Play)>0) {
                 GetFightRatings(Play,Defend,&AttackRating,&DefendRating);
                 if (brandom(0,AttackRating)>brandom(0,DefendRating)) {
                    FightPoint=F_HIT;
                    for (i=0;i<NumGun;i++) for (j=0;j<Play->Guns[i].Carried;j++) {
       -               Damage+=brandom(0,Gun[i].Damage)*100/GetArmour(Play);
       +               Damage+=brandom(0,Gun[i].Damage);
                    }
       +            Damage=Damage*100/GetArmour(Defend);
                    if (Damage==0) Damage=1;
                    HandleDamage(Defend,Play,Damage,&BitchesKilled,&Loot);
                 } else FightPoint=F_MISS;
       t@@ -1823,7 +1840,7 @@ void HandleAnswer(Player *From,Player *To,char *answer) {
           if ((From->EventNum==E_FIGHT || From->EventNum==E_FIGHTASK) &&
               CanRunHere(From)) {
              From->EventNum=E_FIGHT;
       -      if (answer[0]=='R' || answer[0]=='Y') RunFromCombat(From);
       +      if (answer[0]=='R' || answer[0]=='Y') RunFromCombat(From,-1);
              else Fire(From);
           } else if (answer[0]=='Y') switch (From->EventNum) { 
              case E_OFFOBJECT:
       t@@ -1944,7 +1961,6 @@ void BuyObject(Player *From,char *data) {
        /* Objects can be sold if the amount given in "data" is negative, and */
        /* given away if their current price is zero.                         */
           char *cp,*type;
       -   gchar *lone,*deputy;
           int index,i,amount;
           cp=data;
           type=GetNextWord(&cp,"");
       t@@ -1967,14 +1983,9 @@ void BuyObject(Player *From,char *data) {
        
                 if (!Sanitized && (From->Drugs[index].Price==0 &&
                     brandom(0,100)<Location[(int)From->IsAt].PolicePresence)) {
       -            lone=g_strdup_printf(_("YN^Officer %%s spots you dropping %s, and "
       -                                 "chases you!"),Names.Drugs);
       -            deputy=g_strdup_printf(_("YN^Officer %%s and %%d of his deputies "
       -                                   "spot you dropping %s, and chase you!"),
       -                                   Names.Drugs);
       +            SendPrintMessage(NULL,C_NONE,From,
       +                             _("The cops spot you dropping drugs!"));
                    CopsAttackPlayer(From);
       -/*          StartOfficerHardass(From,From->EventNum,lone,deputy);*/
       -            g_free(lone); g_free(deputy);
                 }
              }
           } else if (strcmp(type,"gun")==0) {
 (DIR) diff --git a/src/serverside.h b/src/serverside.h
       t@@ -72,7 +72,7 @@ void AttackPlayer(Player *Play,Player *Attacked);
        gboolean IsOpponent(Player *Play,Player *Other);
        void Fire(Player *Play);
        void WithdrawFromCombat(Player *Play);
       -void RunFromCombat(Player *Play);
       +void RunFromCombat(Player *Play,int ToLocation);
        gboolean CanPlayerFire(Player *Play);
        gboolean CanRunHere(Player *Play);
        Player *GetNextShooter(Player *Play);