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