Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2003:
[Freeciv-Dev] Re: (PR#4095) Allied Victory :-)
Home

[Freeciv-Dev] Re: (PR#4095) Allied Victory :-)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: ChrisK@xxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#4095) Allied Victory :-)
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Fri, 2 May 2003 10:23:10 -0700
Reply-to: rt@xxxxxxxxxxxxxx

On Fri, 2 May 2003, Per I. Mathisen wrote:
> There is no perfect solution for this which isn't rather extensive. So how
> about this attached patch.

Uh, wrong patch. I mean this patch.

  - Per

Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.171
diff -u -r1.171 unit.c
--- common/unit.c       11 Mar 2003 17:59:26 -0000      1.171
+++ common/unit.c       2 May 2003 16:27:03 -0000
@@ -1244,9 +1244,11 @@
   8) there are no peaceful but un-allied units on the target tile
   9) there is not a peaceful but un-allied city on the target tile
   10) there is no non-allied unit blocking (zoc) [or igzoc is true]
+  11) we are not a transport stacked with units not allied to units
+      or city on target tile (we might take them with us and core dump)
 **************************************************************************/
 enum unit_move_result test_unit_move_to_tile(Unit_Type_id type,
-                                            struct player *unit_owner,
+                                            struct player *owner,
                                             enum unit_activity activity,
                                             bool connecting, int src_x,
                                             int src_y, int dest_x,
@@ -1277,14 +1279,14 @@
   ptotile = map_get_tile(dest_x, dest_y);
 
   /* 4) */
-  if (is_non_allied_unit_tile(ptotile, unit_owner)) {
+  if (is_non_allied_unit_tile(ptotile, owner)) {
     return MR_DESTINATION_OCCUPIED_BY_NON_ALLIED_UNIT;
   }
 
   if (unit_types[type].move_type == LAND_MOVING) {
     /* 5) */
     if (is_ocean(ptotile->terrain) &&
-       ground_unit_transporter_capacity(dest_x, dest_y, unit_owner) <= 0) {
+       ground_unit_transporter_capacity(dest_x, dest_y, owner) <= 0) {
       return MR_NO_SEA_TRANSPORTER_CAPACITY;
     }
 
@@ -1292,7 +1294,7 @@
     if (is_ocean(pfromtile->terrain)) {
       /* 6) */
       if (!unit_type_flag(type, F_MARINES)
-         && is_enemy_city_tile(ptotile, unit_owner)) {
+         && is_enemy_city_tile(ptotile, owner)) {
        return MR_BAD_TYPE_FOR_CITY_TAKE_OVER;
       }
     }
@@ -1300,28 +1302,42 @@
     /* 7) */
     if (!is_ocean(ptotile->terrain)
        && ptotile->terrain != T_UNKNOWN
-       && !is_allied_city_tile(ptotile, unit_owner)) {
+       && !is_allied_city_tile(ptotile, owner)) {
       return MR_DESTINATION_OCCUPIED_BY_NON_ALLIED_CITY;
     }
   }
 
   /* 8) */
-  if (is_non_attack_unit_tile(ptotile, unit_owner)) {
+  if (is_non_attack_unit_tile(ptotile, owner)) {
     return MR_NO_WAR;
   }
 
   /* 9) */
   pcity = ptotile->city;
-  if (pcity && pplayers_non_attack(city_owner(pcity), unit_owner)) {
+  if (pcity && pplayers_non_attack(city_owner(pcity), owner)) {
     return MR_NO_WAR;
   }
 
   /* 10) */
   zoc = igzoc
-      || can_step_taken_wrt_to_zoc(type, unit_owner, src_x,
+      || can_step_taken_wrt_to_zoc(type, owner, src_x,
                                   src_y, dest_x, dest_y);
   if (!zoc) {
     return MR_ZOC;
+  }
+
+  /* 11) */
+  /* We cannot move a transport into a city or tile that holds
+   * units not allied with any units we are stacked with. This
+   * check is not perfect, several false positives possible,
+   * but it will err on the side of caution to avoid core dumps. */
+  if (unit_types[type].transport_capacity > 0) {
+    unit_list_iterate(pfromtile->units, aunit) {
+      if (is_non_allied_unit_tile(ptotile, unit_owner(aunit))
+          || is_non_allied_city_tile(ptotile, unit_owner(aunit))) {
+        return MR_BAD_TRANSPORT;
+      }
+    } unit_list_iterate_end;
   }
 
   return MR_OK;
Index: common/unit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v
retrieving revision 1.96
diff -u -r1.96 unit.h
--- common/unit.h       11 Mar 2003 17:59:26 -0000      1.96
+++ common/unit.h       2 May 2003 16:27:03 -0000
@@ -67,7 +67,7 @@
   MR_BAD_ACTIVITY, MR_BAD_DESTINATION, MR_BAD_MAP_POSITION,
   MR_DESTINATION_OCCUPIED_BY_NON_ALLIED_UNIT,
   MR_NO_SEA_TRANSPORTER_CAPACITY,
-  MR_DESTINATION_OCCUPIED_BY_NON_ALLIED_CITY
+  MR_DESTINATION_OCCUPIED_BY_NON_ALLIED_CITY, MR_BAD_TRANSPORT
 };
 
 enum add_build_city_result {
@@ -252,7 +252,7 @@
 bool can_unit_move_to_tile(struct unit *punit, int dest_x, int dest_y,
                           bool igzoc);
 enum unit_move_result test_unit_move_to_tile(Unit_Type_id type,
-                                            struct player *unit_owner,
+                                            struct player *owner,
                                             enum unit_activity activity,
                                             bool connecting, int src_x,
                                             int src_y, int dest_x,
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.257
diff -u -r1.257 unithand.c
--- server/unithand.c   4 Apr 2003 16:03:08 -0000       1.257
+++ server/unithand.c   2 May 2003 16:27:04 -0000
@@ -915,6 +915,10 @@
     notify_player_ex(unit_owner(punit), src_x, src_y, E_NOEVENT,
                     _("Game: %s can only move into your own zone of control."),
                     unit_type(punit)->name);
+  } else if (reason == MR_BAD_TRANSPORT) {
+    notify_player_ex(unit_owner(punit), src_x, src_y, E_NOEVENT,
+                     _("Game: %s may carry illegal cargo into target tile."),
+                     unit_type(punit)->name);
   }
   return FALSE;
 }
@@ -1056,8 +1060,8 @@
     return FALSE;
   }
 
-  /* If there is a city it is empty.
-     If not it would have been caught in the attack case. */
+  /* If there is a non-allied city it is empty. If not it would have been 
+   * caught in the attack case. */
   if (pcity && !pplayers_allied(city_owner(pcity), unit_owner(punit))) {
     if (is_air_unit(punit) || !is_military_unit(punit) || 
is_sailing_unit(punit)) {
       notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,

[Prev in Thread] Current Thread [Next in Thread]