Author: cazfi Date: Thu Aug 4 14:53:47 2016 New Revision: 33455 URL: http://svn.gna.org/viewcvs/freeciv?rev=33455&view=rev Log: Fixed AI trade route evaluation to use correct speculated homecity instead of unit's current homecity.
See bug #24663 Modified: trunk/common/actions.c trunk/common/actions.h trunk/common/aicore/caravan.c Modified: trunk/common/actions.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.c?rev=33455&r1=33454&r2=33455&view=diff ============================================================================== --- trunk/common/actions.c (original) +++ trunk/common/actions.c Thu Aug 4 14:53:47 2016 @@ -1,4 +1,4 @@ -/********************************************************************** +/*********************************************************************** Freeciv - Copyright (C) 1996-2013 - Freeciv Development Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1126,7 +1126,8 @@ const struct unit_type *actor_unittype, const struct output_type *actor_output, const struct specialist *actor_specialist, - const bool omniscient) + const bool omniscient, + const struct city *homecity) { if (!action_actor_utype_hard_reqs_ok(wanted_action, actor_unittype)) { /* Info leak: The actor player knows the type of his unit. */ @@ -1142,7 +1143,7 @@ * city. The Freeciv code assumes this applies to Enter Marketplace * too. */ /* Info leak: The actor player knowns his unit's home city. */ - if (!game_city_by_number(actor_unit->homecity)) { + if (homecity == NULL) { return TRI_NO; } @@ -1249,7 +1250,8 @@ const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, - const bool omniscient) + const bool omniscient, + const struct city *homecity) { bool can_see_tgt_unit; bool can_see_tgt_tile; @@ -1312,7 +1314,7 @@ actor_player, actor_city, actor_building, actor_tile, actor_unit, actor_unittype, actor_output, actor_specialist, - omniscient); + omniscient, homecity); if (out == TRI_NO) { /* Illegal because of a hard actor requirement. */ @@ -1383,25 +1385,21 @@ case ACTION_TRADE_ROUTE: case ACTION_MARKETPLACE: { - const struct city *actor_homecity; - - actor_homecity = game_city_by_number(actor_unit->homecity); - /* Checked in action_hard_reqs_actor() */ - fc_assert_ret_val(actor_homecity != NULL, TRI_NO); + fc_assert_ret_val(homecity != NULL, TRI_NO); /* Can't establish a trade route or enter the market place if the * cities can't trade at all. */ /* TODO: Should this restriction (and the above restriction that the * actor unit must have a home city) be kept for Enter Marketplace? */ - if (!can_cities_trade(actor_homecity, target_city)) { + if (!can_cities_trade(homecity, target_city)) { return TRI_NO; } /* There are more restrictions on establishing a trade route than on * entering the market place. */ - if (wanted_action == ACTION_TRADE_ROUTE && - !can_establish_trade_route(actor_homecity, target_city)) { + if (wanted_action == ACTION_TRADE_ROUTE + && !can_establish_trade_route(homecity, target_city)) { return TRI_NO; } } @@ -1571,7 +1569,7 @@ case ACTION_HOME_CITY: /* Reason: can't change to what is. */ /* Info leak: The player knows his unit's current home city. */ - if (actor_unit->homecity == target_city->id) { + if (homecity->id == target_city->id) { /* This is already the unit's home city. */ return TRI_NO; } @@ -1718,7 +1716,8 @@ const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, - const struct specialist *target_specialist) + const struct specialist *target_specialist, + const struct city *homecity) { enum fc_tristate possible; @@ -1731,7 +1730,7 @@ target_building, target_tile, target_unit, target_unittype, target_output, target_specialist, - TRUE); + TRUE, homecity); if (possible != TRI_YES) { /* This context is omniscient. Should be yes or no. */ @@ -1770,6 +1769,22 @@ const struct unit *actor_unit, const struct city *target_city) { + return is_action_enabled_unit_on_city_full(wanted_action, actor_unit, + target_city, + game_city_by_number(actor_unit->homecity)); +} + +/************************************************************************** + Returns TRUE if actor_unit can do wanted_action to target_city as far as + action enablers are concerned. + + See note in is_action_enabled for why the action may still be disabled. +**************************************************************************/ +bool is_action_enabled_unit_on_city_full(const enum gen_action wanted_action, + const struct unit *actor_unit, + const struct city *target_city, + const struct city *homecity) +{ struct tile *actor_tile = unit_tile(actor_unit); struct impr_type *target_building; struct unit_type *target_utype; @@ -1808,7 +1823,7 @@ NULL, NULL, city_owner(target_city), target_city, target_building, city_tile(target_city), - NULL, target_utype, NULL, NULL); + NULL, target_utype, NULL, NULL, homecity); } /************************************************************************** @@ -1856,7 +1871,8 @@ tile_city(unit_tile(target_unit)), NULL, unit_tile(target_unit), target_unit, unit_type_get(target_unit), - NULL, NULL); + NULL, NULL, + game_city_by_number(actor_unit->homecity)); } /************************************************************************** @@ -1870,6 +1886,7 @@ const struct tile *target_tile) { struct tile *actor_tile = unit_tile(actor_unit); + struct city *homecity; if (actor_unit == NULL || target_tile == NULL || unit_list_size(target_tile->units) == 0) { @@ -1895,6 +1912,8 @@ /* No point in continuing. */ return FALSE; } + + homecity = game_city_by_number(actor_unit->homecity); unit_list_iterate(target_tile->units, target_unit) { if (!is_action_enabled(wanted_action, @@ -1906,7 +1925,7 @@ tile_city(unit_tile(target_unit)), NULL, unit_tile(target_unit), target_unit, unit_type_get(target_unit), - NULL, NULL)) { + NULL, NULL, homecity)) { /* One unit makes it impossible for all units. */ return FALSE; } @@ -1958,7 +1977,8 @@ actor_unit, unit_type_get(actor_unit), NULL, NULL, tile_owner(target_tile), NULL, NULL, - target_tile, NULL, NULL, NULL, NULL); + target_tile, NULL, NULL, NULL, NULL, + game_city_by_number(actor_unit->homecity)); } /************************************************************************** @@ -2002,7 +2022,8 @@ NULL, actor_tile, actor_unit, unit_type_get(actor_unit), NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + game_city_by_number(actor_unit->homecity)); } /************************************************************************** @@ -2271,9 +2292,9 @@ { int known; struct act_prob chance; - const struct unit_type *actor_unittype; const struct unit_type *target_unittype; + const struct city *homecity; if (actor_unittype_p == NULL && actor_unit != NULL) { actor_unittype = unit_type_get(actor_unit); @@ -2285,6 +2306,12 @@ target_unittype = unit_type_get(target_unit); } else { target_unittype = target_unittype_p; + } + + if (actor_unit != NULL) { + homecity = game_city_by_number(actor_unit->homecity); + } else { + homecity = NULL; } known = is_action_possible(wanted_action, @@ -2296,7 +2323,7 @@ target_building, target_tile, target_unit, target_unittype, target_output, target_specialist, - FALSE); + FALSE, homecity); if (known == TRI_NO) { /* The action enablers are irrelevant since the action it self is @@ -2918,7 +2945,7 @@ is provided. **************************************************************************/ bool action_maybe_possible_actor_unit(const int action_id, - const struct unit* actor_unit) + const struct unit *actor_unit) { const struct player *actor_player = unit_owner(actor_unit); const struct tile *actor_tile = unit_tile(actor_unit); @@ -2937,7 +2964,8 @@ result = action_hard_reqs_actor(action_id, actor_player, actor_city, NULL, actor_tile, actor_unit, actor_unittype, - NULL, NULL, FALSE); + NULL, NULL, FALSE, + game_city_by_number(actor_unit->homecity)); if (result == TRI_NO) { /* The hard requirements aren't fulfilled. */ Modified: trunk/common/actions.h URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.h?rev=33455&r1=33454&r2=33455&view=diff ============================================================================== --- trunk/common/actions.h (original) +++ trunk/common/actions.h Thu Aug 4 14:53:47 2016 @@ -1,4 +1,4 @@ -/********************************************************************** +/*********************************************************************** Freeciv - Copyright (C) 1996-2013 - Freeciv Development Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -339,6 +339,11 @@ const struct unit *actor_unit, const struct city *target_city); +bool is_action_enabled_unit_on_city_full(const enum gen_action wanted_action, + const struct unit *actor_unit, + const struct city *target_city, + const struct city *homecity); + bool is_action_enabled_unit_on_unit(const enum gen_action wanted_action, const struct unit *actor_unit, const struct unit *target_unit); Modified: trunk/common/aicore/caravan.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/aicore/caravan.c?rev=33455&r1=33454&r2=33455&view=diff ============================================================================== --- trunk/common/aicore/caravan.c (original) +++ trunk/common/aicore/caravan.c Thu Aug 4 14:53:47 2016 @@ -485,12 +485,15 @@ * theoretically possible case. (More than one city is rare.) The * computations are therefore worth it. */ - if (!(is_action_enabled_unit_on_city(ACTION_HELP_WONDER, - caravan, dest) - || is_action_enabled_unit_on_city(ACTION_TRADE_ROUTE, - caravan, dest) - || is_action_enabled_unit_on_city(ACTION_MARKETPLACE, - caravan, dest))) { + if (!(is_action_enabled_unit_on_city_full(ACTION_HELP_WONDER, + caravan, dest, + src) + || is_action_enabled_unit_on_city_full(ACTION_TRADE_ROUTE, + caravan, dest, + src) + || is_action_enabled_unit_on_city_full(ACTION_MARKETPLACE, + caravan, dest, + src))) { /* No caravan action is possible against this target. */ caravan_result_init_zero(result); return FALSE; _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits