<URL: http://bugs.freeciv.org/Ticket/Display.html?id=38165 >

On 15/03/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
>
> Hi,
>
> I found a bug in the 2.1.0-beta3: spies are always executed when trying
> to establish an embassy, even if they haven't been in any contact with
> the enemy.
>
> I quickly checked the source code, and it would seem to me that the
> problem is actually that the spies are always created with the "foul"
> status:
>
> In server/cityturn.c, line 1212 units are created with 0 moves left,
> which in turn is interpreted as "already moved" in server/unittools.c
> line 1339, where spies are flagged as "foul".
>
> In the stable version the units are created with -1 moves left, so there
> it works as intended.

 It seems that units should never get foul status inside
create_unit(). It is no longer called for spies getting foul.
 Attached patch changes create_unit() to always create non-foul units.
Also, mark spies foul when they actually do something nasty.
 Untested patch for trunk. I have to check if above is true for S2_1 too.


 - ML

diff -Nurd -X.diff_ignore freeciv/server/diplomats.c freeciv/server/diplomats.c
--- freeciv/server/diplomats.c	2007-08-01 17:17:23.000000000 +0300
+++ freeciv/server/diplomats.c	2007-08-04 04:10:44.000000000 +0300
@@ -51,7 +51,7 @@
 				     struct unit *pdiplomat, struct tile *ptile);
 static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat,
 			    const struct city *pcity);
-static void maybe_cause_incident(enum diplomat_actions action, struct player *offender,
+static void maybe_cause_incident(enum diplomat_actions action, struct unit *offender_unit,
 				 struct unit *victim_unit, struct city *victim_city);
 
 /******************************************************************************
@@ -122,7 +122,7 @@
   send_city_info(NULL, pcity);
 
   /* this may cause a diplomatic incident */
-  maybe_cause_incident(SPY_POISON, pplayer, NULL, pcity);
+  maybe_cause_incident(SPY_POISON, pdiplomat, NULL, pcity);
 
   /* Now lets see if the spy survives. */
   diplomat_escape(pplayer, pdiplomat, pcity);
@@ -188,7 +188,7 @@
   }
 
   /* this may cause a diplomatic incident */
-  maybe_cause_incident(DIPLOMAT_INVESTIGATE, pplayer, NULL, pcity);
+  maybe_cause_incident(DIPLOMAT_INVESTIGATE, pdiplomat, NULL, pcity);
 
   /* Spies always survive. Diplomats never do. */
   if (!unit_has_type_flag(pdiplomat, F_SPY)) {
@@ -228,7 +228,7 @@
   lsend_packet_city_sabotage_list(player_reply_dest(pplayer), &packet);
 
   /* this may cause a diplomatic incident */
-  maybe_cause_incident(SPY_GET_SABOTAGE_LIST, pplayer, NULL, pcity);
+  maybe_cause_incident(SPY_GET_SABOTAGE_LIST, pdiplomat, NULL, pcity);
 }
 
 /******************************************************************************
@@ -308,7 +308,7 @@
   }
 
   /* this may cause a diplomatic incident */
-  maybe_cause_incident(DIPLOMAT_EMBASSY, pplayer, NULL, pcity);
+  maybe_cause_incident(DIPLOMAT_EMBASSY, pdiplomat, NULL, pcity);
 
   /* Spies always survive. Diplomats never do. */
   if (!unit_has_type_flag(pdiplomat, F_SPY)) {
@@ -386,7 +386,7 @@
 		   pplayer->name);
 
   /* this may cause a diplomatic incident */
-  maybe_cause_incident(SPY_SABOTAGE_UNIT, pplayer, pvictim, NULL);
+  maybe_cause_incident(SPY_SABOTAGE_UNIT, pdiplomat, pvictim, NULL);
 
   /* Now lets see if the spy survives. */
   diplomat_escape(pplayer, pdiplomat, NULL);
@@ -504,7 +504,7 @@
   pplayer->economic.gold -= pvictim->bribe_cost;
 
   /* This may cause a diplomatic incident */
-  maybe_cause_incident(DIPLOMAT_BRIBE, pplayer, pvictim, NULL);
+  maybe_cause_incident(DIPLOMAT_BRIBE, pdiplomat, pvictim, NULL);
 
   /* Be sure to wipe the converted unit! */
   victim_tile = pvictim->tile;
@@ -644,7 +644,7 @@
 		     unit_name_translation(pdiplomat),
 		     pcity->name);
     /* this may cause a diplomatic incident */
-    maybe_cause_incident(DIPLOMAT_STEAL, pplayer, NULL, pcity);
+    maybe_cause_incident(DIPLOMAT_STEAL, pdiplomat, NULL, pcity);
     wipe_unit(pdiplomat);
     return;
   } 
@@ -667,7 +667,7 @@
   (pcity->steal)++;
 
   /* this may cause a diplomatic incident */
-  maybe_cause_incident(DIPLOMAT_STEAL, pplayer, NULL, pcity);
+  maybe_cause_incident(DIPLOMAT_STEAL, pdiplomat, NULL, pcity);
 
   /* Check if a spy survives her mission. Diplomats never do. */
   diplomat_escape(pplayer, pdiplomat, pcity);
@@ -778,7 +778,7 @@
   steal_a_tech (pplayer, cplayer, A_UNSET);
 
   /* this may cause a diplomatic incident */
-  maybe_cause_incident(DIPLOMAT_INCITE, pplayer, NULL, pcity);
+  maybe_cause_incident(DIPLOMAT_INCITE, pdiplomat, NULL, pcity);
 
   /* Transfer city and units supported by this city (that
      are within one square of the city) to the new owner.
@@ -1036,7 +1036,7 @@
   send_city_info(NULL, pcity);
 
   /* this may cause a diplomatic incident */
-  maybe_cause_incident(DIPLOMAT_SABOTAGE, pplayer, NULL, pcity);
+  maybe_cause_incident(DIPLOMAT_SABOTAGE, pdiplomat, NULL, pcity);
 
   /* Check if a spy survives her mission. Diplomats never do. */
   diplomat_escape(pplayer, pdiplomat, pcity);
@@ -1270,9 +1270,10 @@
 /**************************************************************************
 ...
 **************************************************************************/
-static void maybe_cause_incident(enum diplomat_actions action, struct player *offender,
+static void maybe_cause_incident(enum diplomat_actions action, struct unit *offender_unit,
  				 struct unit *victim_unit, struct city *victim_city)
 {
+  struct player *offender = unit_owner(offender_unit);
   struct player *victim_player = 0;
   struct tile *victim_tile = NULL;
 
@@ -1331,10 +1332,24 @@
  	 get inside this "if" */
       die("Bug in maybe_cause_incident()");
     }
+    offender_unit->foul = TRUE;
     victim_player->diplstates[player_index(offender)].has_reason_to_cancel = 2;
     ai_incident_diplomat(offender, victim_player);
     send_player_info(offender, NULL);
     send_player_info(victim_player, NULL);
+  } else { /* Players at war */
+    switch (action) {
+     case DIPLOMAT_MOVE:
+     case DIPLOMAT_EMBASSY:
+     case DIPLOMAT_INVESTIGATE:
+     case SPY_GET_SABOTAGE_LIST:
+       break; /* These are not considered offences */
+     case DIPLOMAT_ANY_ACTION:
+       break; /* This is not real action */
+     default:
+       offender_unit->foul = TRUE;
+       break;
+    }
   }
 
   return;
diff -Nurd -X.diff_ignore freeciv/server/unittools.c freeciv/server/unittools.c
--- freeciv/server/unittools.c	2007-08-01 17:17:23.000000000 +0300
+++ freeciv/server/unittools.c	2007-08-04 04:12:02.000000000 +0300
@@ -1365,9 +1365,7 @@
    * (Otherwise could pass moved arg too...)  --dwp */
   punit->moved = (moves_left >= 0);
 
-  /* See if this is a spy that has been moved (corrupt and therefore 
-   * unable to establish an embassy. */
-  punit->foul = (moves_left != -1 && unit_has_type_flag(punit, F_SPY));
+  punit->foul = FALSE;
 
   unit_list_prepend(pplayer->units, punit);
   unit_list_prepend(ptile->units, punit);
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to