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:14:13 -0700
Reply-to: rt@xxxxxxxxxxxxxx

On Mon, 28 Apr 2003, ue80@xxxxxxxxxxxxxxxxxxxxx wrote:
> > B's trireme with C's bowmen on it can move into A's city ...
...
> Not the only problem with that:
> Moving a "A-loaded" B-transport onto a C-hostile unit -> Stack with a unit
> from A, B and C will be ok, because you don't see into a loaded
> transport.
>
> Move a C-Destroyer onto the "A-loaded(horse)" B-Transport -> assert
> Defender no seaunit.

There is no perfect solution for this which isn't rather extensive. So how
about this attached patch. While it may in some very rare situations give
false positives (you didn't intend to cargo those units into that tile,
but it still will not allow you to enter the tile because you _might_
have transported them), it should be better than nothing.

The patch has not been tested.

  - 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]