Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2003:
[Freeciv-Dev] (PR#2581) Layers Patch
Home

[Freeciv-Dev] (PR#2581) Layers Patch

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: raahul_da_man@xxxxxxxxx
Subject: [Freeciv-Dev] (PR#2581) Layers Patch
From: "Juhani Heino" <juhani.heino@xxxxxxxxxx>
Date: Sun, 20 Jul 2003 07:29:51 -0700
Reply-to: rt@xxxxxxxxxxxxxx

Sorry, I've been quite nonproductive, but for a change it's
warm in Finland   8-)

This is not final by far - I expect lots of comments again.

The same savegame still works, so you can test with it.

Quoted are some excerpts from Per's redux that applied to my work.
Other parts were already inherent or easily implemented.

> Change to units.ruleset and unit struct:
>  - Every unit gets a "layer" variable (of type char)
>  - In civ1 and civ2 rulesets, it is set to 1 for all units (default)
>  - In default ruleset, air units get 2, subs 0 and all others 1.

I deemed this unnecessary - it's enough to define layers and then use
them in default and not in civ*. I did that in this edition.

In is_same_layer it was easier to separate land from sea. Can't see
any difference in practice, because sea cargo is destroyed in the
transport's deletion routine.

>  - can_unit_attack_unit_at_tile() remains unchanged.

Should I add a separate rule for choppers?
Either add it (is_heli_unit) to rule 2, or perhaps allow them
to be attacked by enemy choppers too. Then I should revise the
priority routine too. Again, this is policy decision, and I don't
have a clue how Civ2 does here.

> Additional choose best defender rules:
>  - A unit always attacks an opponent in the same layer, if there is 
any.

Missiles don't attack air units. In this version they ignore
defending planes, which I consider reasonable.
In this version missiles are also ignored as targets - they will
be attacked only if there isn't anything better. And I think
that should be even prevented in can_unit_attack_unit_at_tile().
As for subs, see below.
Can't think of other exceptions now.

>  - Otherwise, a unit always attacks a unit in the highest layer where 
it
> can find a unit that it can attack.

Didn't quite understand this, I think. 
Planes attack subs only if there are no surface ships - that can be
easily arranged - but are there other cases? Or is this preparing
for future?

So far I was lazy and didn't separate subs in priority. They are so
poor defending that surface ships will be chosen first usually.

>  - Cargo transported by a transporter which resides in a different 
layer
> are unaffected if their transporter is killed, so they should be
> un-sentried. We assume that they scramble into their own layer when
> attacked. At the moment, this only applies to carriers and air units.

But what if a ship sinks the carrier? If the planes escape,
the helptext (and of course, the unit removal) must be revised.

And now we are back at the good old strafing... if the fighter
defeats the scrambling plane, all of them and missiles are destroyed.
Speak up if you oppose this.

-- 
Juhani Heino
Finnish translator and now hacking too
--- ai/aitools.c.orig   Thu Jul  3 23:45:01 2003
+++ ai/aitools.c        Thu Jul  3 23:45:50 2003
@@ -415,6 +415,12 @@
   if (is_stack_vulnerable(pdef->x, pdef->y)) {
     /* lotsa people die */
     unit_list_iterate(map_get_tile(pdef->x, pdef->y)->units, aunit) {
+      /* 3rd row: on sea, cargo would be lost anyway */
+      if (game.rgame.layered_combat
+          && !is_same_layer(pdef, aunit)
+          && (!is_sailing_unit(pdef) || is_sailing_unit(aunit))) {
+        continue;
+      }
       victim_cost += unit_type(aunit)->build_cost;
     } unit_list_iterate_end;
   } else {
--- client/packhand.c.orig      Thu Jul  3 23:39:56 2003
+++ client/packhand.c   Thu Jul  3 23:45:50 2003
@@ -2352,6 +2352,7 @@
   game.rgame.min_dist_bw_cities = packet->min_dist_bw_cities;
   game.rgame.init_vis_radius_sq = packet->init_vis_radius_sq;
   game.rgame.hut_overflight = packet->hut_overflight;
+  game.rgame.layered_combat = packet->layered_combat;
   game.rgame.pillage_select = packet->pillage_select;
   game.rgame.nuke_contamination = packet->nuke_contamination;
   game.rgame.granary_food_ini = packet->granary_food_ini;
--- common/combat.c.orig        Thu Jul  3 23:39:56 2003
+++ common/combat.c     Sun Jul 20 00:41:54 2003
@@ -561,14 +561,74 @@
 }
 
 /**************************************************************************
+ In layered combat, gives the target priority. The battle will be
+ (or won't begin at all, as may be specified elsewhere) with
+ a target with the biggest number, see get_defender below.
+ Ships are preferred a little because they are generally easier
+ targets from air.
+ If you change this function, remember missiles. They must target
+ sea or land units, ain't no Sidewinders   8-)
+ Here it's assumed that helicopters can be attacked only by fighters
+ (cities are a different case for all air units), that's how I read
+ the help text.  --Juhani
+**************************************************************************/
+int layer_priority(struct unit *attacker, struct unit *defender)
+{
+  if (is_heli_unit(defender)) {
+    if (unit_flag(attacker, F_FIGHTER)) {
+      return 40;
+    }
+    return 0;
+  }
+
+  if (is_air_unit(defender)) {
+    if (unit_flag(defender, F_MISSILE)
+        || unit_flag(attacker, F_MISSILE)) {
+      return 0;
+    }
+
+    /* Fighter will attack aircraft first. And a defending fighter
+     * "grabs" the battle on air layer - if the attacking plane
+     * can't engage it, there won't be an attack at all.
+     */
+    if (unit_flag(attacker, F_FIGHTER)
+        || (unit_flag(defender, F_FIGHTER)
+            && is_air_unit(attacker))) {
+      return 50;
+    }
+    return 0;
+  }
+
+  if (is_ground_unit(defender)) {
+    if (unit_flag(attacker, F_NO_LAND_ATTACK)) {
+      return 0;
+    }
+    if (is_ground_unit(attacker)) {
+      return 30;
+    }
+    return 10;
+  }
+
+  if (is_sailing_unit(defender)) {
+    if (is_sailing_unit(attacker)) {
+      return 30;
+    }
+    if (is_ground_unit(attacker)) {
+      return 0;
+    }
+    return 20;
+  }
+  freelog(LOG_ERROR, "layer_priority bug: probably a new movetype");
+  assert(FALSE);
+}
+
+/**************************************************************************
 Finds the best defender on the square, given an attacker.
 
-This is simply done by calling win_chance with all the possible defenders
-in turn.
-This functions could be improved to take the value of the unit into
-account. It currently uses build cost as a modifier in case the chances of
-2 units are identical, but this is crude as build cost does not neccesarily
-have anything to do with the value of a unit.
+This function could be improved to take the value of the unit into
+account. It currently uses build cost as a modifier in case the
+chances of 2 units are identical, but this is crude as build cost
+does not necessarily have anything to do with the value of a unit.
 It would be nice if the function was a bit more fuzzy about prioritizing,
 making it able to fx choose a 1a/9d unit over a 10a/10d unit. It should
 also be able to spare units without full hp's to some extend, as these
@@ -578,28 +638,42 @@
 {
   struct unit *bestdef = NULL;
   int bestvalue = -1, count = 0, best_cost = 0, rating_of_best = 0;
+  int priority = 0;
   struct player *att_owner = unit_owner(attacker);
+  bool change;
+  bool outside = is_stack_vulnerable(x, y);
+  int build_cost, defense_rating, unit_def;
 
   unit_list_iterate(map_get_tile(x, y)->units, defender) {
     if (pplayers_allied(att_owner, unit_owner(defender)))
       continue;
-    count++;
     if (unit_can_defend_here(defender)) {
-      bool change = FALSE;
-      int build_cost = unit_type(defender)->build_cost;
-      int defense_rating = get_defense_rating(attacker, defender);
+      freelog(LOG_DEBUG, "get_defender considering %s",
+                         unit_name(defender->type));
+      if (outside
+          && game.rgame.layered_combat
+          && layer_priority(attacker, defender) < priority) {
+        continue;
+      }
+      count++;
+      change = FALSE;
+      build_cost = unit_type(defender)->build_cost;
+      defense_rating = get_defense_rating(attacker, defender);
 
-      /* This will make units roughly evenly good defenders look alike. */
-      int unit_def = (int) (100000 * (1 - unit_win_chance(attacker, 
defender)));
+      unit_def = (int) (30000 * (1 - unit_win_chance(attacker, defender)));
       assert(unit_def >= 0);
 
-      if (unit_def > bestvalue) {
+      if (outside
+          && game.rgame.layered_combat
+          && layer_priority(attacker, defender) > priority) {
+        change = TRUE;
+      } else if (unit_def > bestvalue) {
        change = TRUE;
       } else if (unit_def == bestvalue) {
-       if (build_cost < best_cost) {
+       if (rating_of_best < defense_rating) {
          change = TRUE;
-       } else if (build_cost == best_cost) {
-         if (rating_of_best < defense_rating) {        
+       } else if (rating_of_best == defense_rating) {
+         if (build_cost < best_cost) { 
            change = TRUE;
          }
        }
@@ -610,6 +684,11 @@
        bestdef = defender;
        best_cost = build_cost;
        rating_of_best = defense_rating;
+        priority = layer_priority(attacker, defender);
+        freelog(LOG_DEBUG, "get_defender preferring so far %s "
+                "with unit_def=%i layer=%i def_rating=%i",
+                unit_name(defender->type), unit_def,
+                priority, defense_rating);
       }
     }
   } unit_list_iterate_end;
--- common/combat.h.orig        Thu Jul  3 23:39:56 2003
+++ common/combat.h     Thu Jul  3 23:45:50 2003
@@ -53,6 +53,7 @@
 int get_virtual_defense_power(Unit_Type_id att_type, Unit_Type_id def_type,
                              int x, int y, bool fortified, bool veteran);
 int get_total_attack_power(struct unit *attacker, struct unit *defender);
+int layer_priority(struct unit *attacker, struct unit *defender);
 
 struct unit *get_defender(struct unit *attacker, int x, int y);
 struct unit *get_attacker(struct unit *defender, int x, int y);
--- common/game.h.orig  Thu Jul  3 23:45:01 2003
+++ common/game.h       Thu Jul  3 23:45:50 2003
@@ -187,6 +187,7 @@
     int min_dist_bw_cities;
     int init_vis_radius_sq;
     int hut_overflight;
+    bool layered_combat;
     bool pillage_select;
     int nuke_contamination;
     int granary_food_ini;
--- common/packets.c.orig       Thu Jul  3 23:39:56 2003
+++ common/packets.c    Thu Jul  3 23:45:50 2003
@@ -2750,6 +2750,7 @@
   dio_put_uint8(&dout, packet->min_dist_bw_cities);
   dio_put_uint8(&dout, packet->init_vis_radius_sq);
   dio_put_uint8(&dout, packet->hut_overflight);
+  dio_put_bool8(&dout, packet->layered_combat);
   dio_put_bool8(&dout, packet->pillage_select);
   dio_put_uint8(&dout, packet->nuke_contamination);
   dio_put_uint8(&dout, packet->granary_food_ini);
@@ -2775,6 +2776,7 @@
   dio_get_uint8(&din, &packet->min_dist_bw_cities);
   dio_get_uint8(&din, &packet->init_vis_radius_sq);
   dio_get_uint8(&din, &packet->hut_overflight);
+  dio_get_bool8(&din, &packet->layered_combat);
   dio_get_bool8(&din, &packet->pillage_select);
   dio_get_uint8(&din, &packet->nuke_contamination);
   dio_get_uint8(&din, &packet->granary_food_ini);
--- common/packets.h.orig       Thu Jul  3 23:39:56 2003
+++ common/packets.h    Thu Jul  3 23:45:50 2003
@@ -820,6 +820,7 @@
   int min_dist_bw_cities;
   int init_vis_radius_sq;
   int hut_overflight;
+  bool layered_combat;
   bool pillage_select;
   int nuke_contamination;
   int granary_food_ini;
--- common/unit.c.orig  Thu Jul  3 23:39:56 2003
+++ common/unit.c       Sat Jul  5 01:55:20 2003
@@ -308,6 +308,15 @@
 bool is_air_units_transport(struct unit *punit)
 {
   return (get_transporter_capacity(punit) > 0
+         && unit_flag(punit, F_CARRIER));
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+bool is_missile_transport(struct unit *punit)
+{
+  return (get_transporter_capacity(punit) > 0
          && (unit_flag(punit, F_MISSILE_CARRIER)
              || unit_flag(punit, F_CARRIER)));
 }
@@ -321,6 +330,16 @@
 }
 
 /**************************************************************************
+  Is this a submarine? Perhaps there are better ways to check it,
+  I didn't want to use unitname directly.
+**************************************************************************/
+bool is_sub(struct unit *punit)
+{
+  return (unit_flag(punit, F_PARTIAL_INVIS)
+          && unit_type(punit)->move_type == SEA_MOVING);
+}
+
+/**************************************************************************
 ...
 **************************************************************************/
 bool is_air_unit(struct unit *punit)
@@ -342,6 +361,26 @@
 bool is_ground_unit(struct unit *punit)
 {
   return (unit_type(punit)->move_type == LAND_MOVING);
+}
+
+/**************************************************************************
+  Do the units belong in the same layer?  (air, land, sea, submarine)
+**************************************************************************/
+bool is_same_layer(struct unit *punit, struct unit *aunit)
+{
+  if ((is_heli_unit(punit) && is_air_unit(aunit))
+      || (is_heli_unit(aunit) && is_air_unit(punit))) {
+    return TRUE;
+  }
+
+  if (is_sub(punit)) {
+    if (is_sub(aunit)) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  return (unit_type(punit)->move_type == unit_type(aunit)->move_type);
 }
 
 /**************************************************************************
--- common/unit.h.orig  Thu Jul  3 23:45:01 2003
+++ common/unit.h       Sat Jul  5 01:45:30 2003
@@ -213,9 +213,11 @@
 bool is_field_unit(struct unit *punit);              /* ships+aero */
 bool is_hiding_unit(struct unit *punit);
 bool is_sailing_unit(struct unit *punit);
+bool is_sub(struct unit *punit);
 bool is_air_unit(struct unit *punit);
 bool is_heli_unit(struct unit *punit);
 bool is_ground_unit(struct unit *punit);
+bool is_same_layer(struct unit *punit, struct unit *aunit);
 bool can_unit_add_to_city (struct unit *punit);
 bool can_unit_build_city (struct unit *punit);
 bool can_unit_add_or_build_city (struct unit *punit);
@@ -227,6 +229,7 @@
 int get_transporter_capacity(struct unit *punit);
 bool is_ground_units_transport(struct unit *punit);
 bool is_air_units_transport(struct unit *punit);
+bool is_missile_transport(struct unit *punit);
 int missile_carrier_capacity(int x, int y, struct player *pplayer,
                             bool count_units_with_extra_fuel);
 int airunit_carrier_capacity(int x, int y, struct player *pplayer,
--- data/civ1/game.ruleset.orig Sat Jul  5 00:33:10 2003
+++ data/civ1/game.ruleset      Sat Jul  5 00:36:17 2003
@@ -34,6 +34,13 @@
 ;   "Frighten" - Tribe frightened and disbands; hut disappears.
 hut_overflight         = "Nothing"
 
+; Whether only units of a single layer (air, land, sea, sub) are
+; destroyed when the defender loses. For example, a fighter
+; attacks bombers on a square that has also enemy land units.
+; Even if the bombers are destroyed, the land units remain
+; intact. In Civ1 this is disabled, so they will die too.
+layered_combat          = 0
+
 ; Whether player gets to select which terrain improvement to pillage.
 pillage_select         = 0
 
--- data/civ2/game.ruleset.orig Sat Jul  5 00:36:26 2003
+++ data/civ2/game.ruleset      Sat Jul  5 00:37:29 2003
@@ -29,6 +29,13 @@
 ; Square of initially visible radius (true distance).
 init_vis_radius_sq     = 5
 
+; Whether only units of a single layer (air, land, sea, sub) are
+; destroyed when the defender loses. For example, a fighter
+; attacks bombers on a square that has also enemy land units.
+; Even if the bombers are destroyed, the land units remain
+; intact. In Civ2 this is disabled, so they will die too.
+layered_combat          = 0
+
 ; What happens when a hut is overflown:
 ;   "Nothing"  - Just fly over; hut remains.
 ;   "Frighten" - Tribe frightened and disbands; hut disappears.
--- data/default/game.ruleset.orig      Thu Jul  3 23:45:01 2003
+++ data/default/game.ruleset   Thu Jul  3 23:45:50 2003
@@ -34,6 +34,13 @@
 ;   "Frighten" - Tribe frightened and disbands; hut disappears.
 hut_overflight         = "Frighten"
 
+; Whether only units of a single layer (air, land, sea, sub) are
+; destroyed when the defender loses. For example, a fighter
+; attacks bombers on a square that has also enemy land units.
+; Even if the bombers are destroyed, the land units remain
+; intact. If this was disabled, they would die too.
+layered_combat          = 1
+
 ; Whether player gets to select which terrain improvement to pillage.
 pillage_select         = 1
 
--- data/helpdata.txt.orig      Thu Jul  3 23:45:01 2003
+++ data/helpdata.txt   Thu Jul  3 23:45:50 2003
@@ -978,7 +978,11 @@
 "), _("\
 If the defender loses, and is not inside a city or fortress, all \
 other units at the defender's location are destroyed along with the \
-defender.\
+defender. But if the rule layered.combat is enabled (by default it \
+is), this means only units on the same layer (land, sea, air). For \
+example, if you attack a bomber, any land unit beneath is unharmed. \
+If you sink a ship, its cargo (ground units, or any air unit if it \
+is a carrier, or missiles if it is a sub) is lost too. \
 ")
 
 [help_combat_example_1]
--- server/ruleset.c.orig       Thu Jul  3 23:39:56 2003
+++ server/ruleset.c    Thu Jul  3 23:45:51 2003
@@ -2410,8 +2410,11 @@
     game.rgame.hut_overflight = OVERFLIGHT_FRIGHTEN;
   }
 
+  game.rgame.layered_combat = 
+    secfile_lookup_bool(&file, "civstyle.layered_combat" );
+
   game.rgame.pillage_select =
-      secfile_lookup_bool(&file, "civstyle.pillage_select");
+    secfile_lookup_bool(&file, "civstyle.pillage_select");
 
   sval = secfile_lookup_str(&file, "civstyle.nuke_contamination" );
   if (mystrcasecmp(sval, "Pollution") == 0) {
@@ -2813,6 +2816,7 @@
   misc_p.min_dist_bw_cities = game.rgame.min_dist_bw_cities;
   misc_p.init_vis_radius_sq = game.rgame.init_vis_radius_sq;
   misc_p.hut_overflight = game.rgame.hut_overflight;
+  misc_p.layered_combat = game.rgame.layered_combat;
   misc_p.pillage_select = game.rgame.pillage_select;
   misc_p.nuke_contamination = game.rgame.nuke_contamination;
   misc_p.granary_food_ini = game.rgame.granary_food_ini;
--- server/unittools.c.orig     Thu Jul  3 23:39:57 2003
+++ server/unittools.c  Thu Jul  3 23:45:51 2003
@@ -1608,20 +1608,38 @@
                         bool wipe_cargo)
 {
   /* No need to remove air units as they can still fly away */
-  if (is_ground_units_transport(punit)
+
+  /* I disagree: now that I'm implementing layered combat, that
+   * would mean planes escaping unscathed from destroyed carrier.
+   * Helpfile hints otherwise, so I'll include air units. Use
+   * wipe_cargo value FALSE if the situation is different.  --Juhani  */
+
+  bool air = is_air_units_transport(punit);
+  bool ground = is_ground_units_transport(punit);
+  bool missile = is_missile_transport(punit);
+
+  if ((air || ground || missile)
       && is_ocean(map_get_terrain(punit->x, punit->y))
       && wipe_cargo) {
     int x = punit->x;
     int y = punit->y;
 
-    int capacity =
-       ground_unit_transporter_capacity(x, y, unit_owner(punit));
+    int capacity;
+    if (air) {
+      capacity = airunit_carrier_capacity(x, y, unit_owner(punit), TRUE);
+    } else if (missile) {
+      capacity = missile_carrier_capacity(x, y, unit_owner(punit), TRUE);
+    } else {
+      capacity = ground_unit_transporter_capacity(x, y, unit_owner(punit));
+    }
     capacity -= get_transporter_capacity(punit);
 
     unit_list_iterate(map_get_tile(x, y)->units, pcargo) {
       if (capacity >= 0)
        break;
-      if (is_ground_unit(pcargo)) {
+      if ((ground && is_ground_unit(pcargo))
+          || (air && is_air_unit(pcargo))
+          || (missile && unit_flag(pcargo, F_MISSILE))) {
        if (iter && ((struct unit*)ITERATOR_PTR((*iter))) == pcargo) {
          freelog(LOG_DEBUG, "iterating over %s in wipe_unit_safe",
                  unit_name(pcargo->type));
@@ -1671,6 +1689,7 @@
   char *loc_str = get_location_str_in(pplayer, punit->x, punit->y);
   int num_killed[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
   int ransom, unitcount = 0;
+  struct unit *original = punit;
   
   /* barbarian leader ransom hack */
   if( is_barbarian(pplayer) && unit_has_role(punit->type, L_BARBARIAN_LEADER)
@@ -1687,13 +1706,15 @@
   }
 
   if (unitcount == 0) {
-    unit_list_iterate(map_get_tile(punit->x, punit->y)->units, vunit)
+    unit_list_iterate(map_get_tile(punit->x, punit->y)->units, vunit) {
+      if (game.rgame.layered_combat && !is_same_layer(original, vunit))
+        continue;
       if (pplayers_at_war(unit_owner(pkiller), unit_owner(vunit)))
        unitcount++;
-    unit_list_iterate_end;
+    } unit_list_iterate_end;
   }
 
-  if (!is_stack_vulnerable(punit->x,punit->y) || unitcount == 1) {
+  if (!is_stack_vulnerable(punit->x, punit->y) || unitcount == 1) {
     notify_player_ex(pplayer, punit->x, punit->y, E_UNIT_LOST,
                     _("Game: %s lost to an attack by %s's %s%s."),
                     unit_type(punit)->name, destroyer->name,
@@ -1714,10 +1735,12 @@
     }
 
     /* count killed units */
-    unit_list_iterate((map_get_tile(punit->x ,punit->y)->units), vunit)
+    unit_list_iterate((map_get_tile(punit->x, punit->y)->units), vunit) {
+      if (game.rgame.layered_combat && !is_same_layer(original, vunit))
+        continue;
       if (pplayers_at_war(unit_owner(pkiller), unit_owner(vunit)))
        num_killed[vunit->owner]++;
-    unit_list_iterate_end;
+    } unit_list_iterate_end;
 
     /* inform the owners */
     for (i = 0; i<MAX_NUM_PLAYERS+MAX_NUM_BARBARIANS; i++) {
@@ -1735,6 +1758,8 @@
 
     /* remove the units */
     unit_list_iterate(map_get_tile(punit->x, punit->y)->units, punit2) {
+      if (game.rgame.layered_combat && !is_same_layer(original, punit2))
+        continue;
       if (pplayers_at_war(unit_owner(pkiller), unit_owner(punit2))) {
        notify_player_ex(unit_owner(punit2), 
                         punit2->x, punit2->y, E_UNIT_LOST,
@@ -1746,10 +1771,15 @@
                get_nation_name_plural(unit_owner(punit2)->nation),
                unit_type(punit2)->name,
                get_nation_name_plural(destroyer->nation));
-       wipe_unit_spec_safe(punit2, NULL, FALSE);
+        if (original != punit2) {
+          /* myiter was recommended in HACKING and indeed it avoided
+           * a segfault I got with the previous code */
+          wipe_unit_spec_safe(punit2, &myiter, TRUE);
+        }
       }
-    }
-    unit_list_iterate_end;
+    } unit_list_iterate_end;
+    /* Finally remove the original loser - couldn't do it in iteration */
+    wipe_unit(original);
   }
 }
 
@@ -2429,7 +2459,8 @@
     }
     return;
     /*** Allocate air and missile units ***/
-  } else if (is_air_units_transport(ptrans)) {
+  } else if (is_air_units_transport(ptrans)
+             || is_missile_transport(ptrans)) {
     struct player_tile *plrtile =
        map_get_player_tile(x, y, unit_owner(ptrans));
     bool is_refuel_point =
@@ -2437,8 +2468,8 @@
        || (contains_special(plrtile->special, S_AIRBASE)
            && !is_non_allied_unit_tile(map_get_tile(x, y),
                                        unit_owner(ptrans)));
-    bool missiles_only = unit_flag(ptrans, F_MISSILE_CARRIER)
-      && !unit_flag(ptrans, F_CARRIER);
+    bool missiles_only = is_missile_transport(ptrans)
+                         && !unit_flag(ptrans, F_CARRIER);
 
     /* Make sure we can transport the units marked as being transported by 
ptrans */
     unit_list_iterate(ptile->units, pcargo) {

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#2581) Layers Patch, Juhani Heino <=