Author: persia
Date: Thu Jun 26 11:11:09 2014
New Revision: 25271

URL: http://svn.gna.org/viewcvs/freeciv?rev=25271&view=rev
Log:
Use gen-move compatible bodyguard filter

Add caching of relevant unit_class and unit_type checks

See patch #4649

Modified:
    trunk/ai/default/aiunit.c
    trunk/ai/default/aiunit.h
    trunk/common/unittype.c
    trunk/common/unittype.h

Modified: trunk/ai/default/aiunit.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/ai/default/aiunit.c?rev=25271&r1=25270&r2=25271&view=diff
==============================================================================
--- trunk/ai/default/aiunit.c   (original)
+++ trunk/ai/default/aiunit.c   Thu Jun 26 11:11:09 2014
@@ -676,10 +676,10 @@
   and building want estimation code. Returns desirability for using this
   unit as a bodyguard or for defending a city.
 
-  We do not consider units with higher movement than us, or units that have
-  different move type than us, as potential charges. Nor do we attempt to
-  bodyguard units with higher defence than us, or military units with higher
-  attack than us.
+  We do not consider units with higher movement than us, or units that are
+  native to terrains or extras not native to us, as potential charges. Nor
+  do we attempt to bodyguard units with higher defence than us, or military
+  units with lower attack than us that are not transports.
 ****************************************************************************/
 int look_for_charge(struct ai_type *ait, struct player *pplayer,
                     struct unit *punit,
@@ -693,6 +693,7 @@
   int def, best_def = -1;
   /* Arbitrary: 3 turns. */
   const int max_move_cost = 3 * unit_move_rate(punit);
+  struct unit_type_ai *utai = utype_ai_data(unit_type(punit), ait);
 
   *aunit = NULL;
   *acity = NULL;
@@ -716,16 +717,24 @@
 
     /* Consider unit bodyguard. */
     unit_list_iterate(ptile->units, buddy) {
+      bool acceptable_charge = FALSE;
+
+      unit_type_list_iterate(utai->potential_charges, charge_type) {
+        if (unit_type(punit) == charge_type) {
+          acceptable_charge = TRUE;
+        }
+      } unit_type_list_iterate_end;
+
       /* TODO: allied unit bodyguard? */
-      if (unit_owner(buddy) != pplayer
+      if (!acceptable_charge
+          || unit_owner(buddy) != pplayer
           || !aiguard_wanted(ait, buddy)
           || unit_move_rate(buddy) > unit_move_rate(punit)
           || DEFENCE_POWER(buddy) >= DEFENCE_POWER(punit)
           || (is_military_unit(buddy)
               && 0 == get_transporter_capacity(buddy)
-              && ATTACK_POWER(buddy) <= ATTACK_POWER(punit))
-          || (uclass_move_type(unit_class(buddy))
-              != uclass_move_type(unit_class(punit)))) {
+              && ATTACK_POWER(buddy) <= ATTACK_POWER(punit))) {
+
         continue;
       }
 
@@ -2964,6 +2973,7 @@
     utai->ferry = FALSE;
     utai->missile_platform = FALSE;
     utai->carries_occupiers = FALSE;
+    utai->potential_charges = unit_type_list_new();
 
     utype_set_ai_data(ptype, ait, utai);
   } unit_type_iterate_end;
@@ -3012,6 +3022,29 @@
         }
       } unit_class_iterate_end;
     }
+
+    /* Consider potential charges */
+    unit_type_iterate(pcharge) {
+      bool can_move_like_charge = FALSE;
+
+      if (0 < utype_fuel(punittype)
+          && (0 == utype_fuel(pcharge)
+              || utype_fuel(pcharge) > utype_fuel(punittype))) {
+        continue;
+      }
+
+      unit_class_list_iterate(pclass->cache.subset_movers, chgcls) {
+        if (chgcls == utype_class(pcharge)) {
+          can_move_like_charge = TRUE;
+        }
+      } unit_class_list_iterate_end;
+
+      if (can_move_like_charge) {
+        struct unit_type_ai *utai = utype_ai_data(punittype, ait);
+        unit_type_list_append(utai->potential_charges, pcharge);
+      }
+
+    } unit_type_iterate_end;
   } unit_type_iterate_end;
 }
 

Modified: trunk/ai/default/aiunit.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/ai/default/aiunit.h?rev=25271&r1=25270&r2=25271&view=diff
==============================================================================
--- trunk/ai/default/aiunit.h   (original)
+++ trunk/ai/default/aiunit.h   Thu Jun 26 11:11:09 2014
@@ -51,6 +51,7 @@
   bool ferry;
   bool missile_platform;
   bool carries_occupiers;
+  struct unit_type_list *potential_charges;
 };
 
 /* Simple military macros */

Modified: trunk/common/unittype.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.c?rev=25271&r1=25270&r2=25271&view=diff
==============================================================================
--- trunk/common/unittype.c     (original)
+++ trunk/common/unittype.c     Thu Jun 26 11:11:09 2014
@@ -1119,6 +1119,7 @@
     unit_classes[i].item_number = i;
     unit_classes[i].cache.refuel_bases = NULL;
     unit_classes[i].cache.native_tile_extras = NULL;
+    unit_classes[i].cache.subset_movers = NULL;
   }
 }
 
@@ -1137,6 +1138,9 @@
     if (unit_classes[i].cache.native_tile_extras != NULL) {
       extra_type_list_destroy(unit_classes[i].cache.native_tile_extras);
       unit_classes[i].cache.native_tile_extras = NULL;
+    }
+    if (unit_classes[i].cache.subset_movers != NULL) {
+      unit_class_list_destroy(unit_classes[i].cache.subset_movers);
     }
   }
 }
@@ -1291,6 +1295,7 @@
 {
   pclass->cache.refuel_bases = extra_type_list_new();
   pclass->cache.native_tile_extras = extra_type_list_new();
+  pclass->cache.subset_movers = unit_class_list_new();
 
   extra_type_iterate(pextra) {
     if (is_native_extra_to_uclass(pextra, pclass)) {
@@ -1302,4 +1307,28 @@
       }
     }
   } extra_type_iterate_end;
-}
+
+  unit_class_iterate(pcharge) {
+    bool subset_mover = TRUE;
+
+    terrain_type_iterate(pterrain) {
+      if (BV_ISSET(pterrain->native_to, uclass_index(pcharge))
+          && !BV_ISSET(pterrain->native_to, uclass_index(pclass))) {
+        subset_mover = FALSE;
+      }
+    } terrain_type_iterate_end;
+
+    if (subset_mover) {
+      extra_type_iterate(pextra) {
+        if (is_native_extra_to_uclass(pextra, pcharge)
+            && !is_native_extra_to_uclass(pextra, pclass)) {
+          subset_mover = FALSE;
+        }
+      } extra_type_list_iterate_end;
+    }
+
+    if (subset_mover) {
+      unit_class_list_append(pclass->cache.subset_movers, pcharge);
+    }
+  } unit_class_iterate_end;
+}

Modified: trunk/common/unittype.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.h?rev=25271&r1=25270&r2=25271&view=diff
==============================================================================
--- trunk/common/unittype.h     (original)
+++ trunk/common/unittype.h     Thu Jun 26 11:11:09 2014
@@ -92,6 +92,7 @@
 enum move_level { MOVE_NONE, MOVE_PARTIAL, MOVE_FULL };
 
 struct extra_type_list;
+struct unit_class_list;
 
 struct unit_class {
   Unit_Class_id item_number;
@@ -111,6 +112,7 @@
   struct {
     struct extra_type_list *refuel_bases;
     struct extra_type_list *native_tile_extras;
+    struct unit_class_list *subset_movers;
   } cache;
 };
 
@@ -619,6 +621,22 @@
   }                                                                    \
 }
 
+#define SPECLIST_TAG unit_class
+#define SPECLIST_TYPE struct unit_class
+#include "speclist.h"
+
+#define unit_class_list_iterate(uclass_list, pclass) \
+  TYPED_LIST_ITERATE(struct unit_class, uclass_list, pclass)
+#define unit_class_list_iterate_end LIST_ITERATE_END
+
+#define SPECLIST_TAG unit_type
+#define SPECLIST_TYPE struct unit_type
+#include "speclist.h"
+
+#define unit_type_list_iterate(utype_list, ptype) \
+  TYPED_LIST_ITERATE(struct unit_type, utype_list, ptype)
+#define unit_type_list_iterate_end LIST_ITERATE_END
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to