Author: sveinung Date: Tue Mar 28 22:01:38 2017 New Revision: 35169 URL: http://svn.gna.org/viewcvs/freeciv?rev=35169&view=rev Log: unit_get_actions: stop city existence leakage.
Stop leaking if a previously observed city still exists when responding to a request for action probabilities in handle_unit_get_actions(). See gna bug #25282 Modified: branches/S3_0/common/actions.c branches/S3_0/server/unithand.c Modified: branches/S3_0/common/actions.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S3_0/common/actions.c?rev=35169&r1=35168&r2=35169&view=diff ============================================================================== --- branches/S3_0/common/actions.c (original) +++ branches/S3_0/common/actions.c Tue Mar 28 22:01:38 2017 @@ -3072,6 +3072,12 @@ return ACTPROB_IMPOSSIBLE; } + if (!player_can_see_city_externals(unit_owner(actor_unit), target_city)) { + /* The invisible city at this tile may, as far as the player knows, not + * exist anymore. */ + return act_prob_unseen_target(action_id, actor_unit); + } + target_building = tgt_city_local_building(target_city); target_utype = tgt_city_local_utype(target_city); Modified: branches/S3_0/server/unithand.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S3_0/server/unithand.c?rev=35169&r1=35168&r2=35169&view=diff ============================================================================== --- branches/S3_0/server/unithand.c (original) +++ branches/S3_0/server/unithand.c Tue Mar 28 22:01:38 2017 @@ -1443,6 +1443,7 @@ struct city *target_city; int actor_target_distance; + const struct player_tile *plrtile; /* No potentially legal action is known yet. If none is found the player * should get an explanation. */ @@ -1498,6 +1499,11 @@ return; } + /* The player may have outdated information about the target tile. + * Limiting the player knowledge look up to the target tile is OK since + * all targets must be located at it. */ + plrtile = map_get_player_tile(target_tile, actor_player); + /* Distance between actor and target tile. */ actor_target_distance = real_map_distance(unit_tile(actor_unit), target_tile); @@ -1513,10 +1519,27 @@ switch (action_id_get_target_kind(act)) { case ATK_CITY: - if (target_city) { - /* Calculate the probabilities. */ - probabilities[act] = action_prob_vs_city(actor_unit, act, - target_city); + if (plrtile && plrtile->site) { + /* Only a known city may be targeted. */ + if (target_city) { + /* Calculate the probabilities. */ + probabilities[act] = action_prob_vs_city(actor_unit, act, + target_city); + } else if (!tile_is_seen(target_tile, actor_player) + && action_maybe_possible_actor_unit(act, actor_unit) + && action_id_distance_accepted(act, + actor_target_distance)) { + /* The target city is non existing. The player isn't aware of this + * fact because he can't see the tile it was located on. The + * actor unit it self doesn't contradict the requirements to + * perform the action. The (no longer existing) target city was + * known to be close enough. */ + probabilities[act] = ACTPROB_NOT_KNOWN; + } else { + /* The actor unit is known to be unable to act or the target city + * is known to be too far away. */ + probabilities[act] = ACTPROB_IMPOSSIBLE; + } } else { /* No target to act against. */ probabilities[act] = ACTPROB_IMPOSSIBLE; @@ -1581,8 +1604,13 @@ case ATK_CITY: /* The city should be sent as a target since it is possible to act * against it. */ - fc_assert(target_city != NULL); - target_city_id = target_city->id; + + /* All city targeted actions requires that the player is aware of + * the target city. It is therefore in the player's map. */ + fc_assert_action(plrtile, continue); + fc_assert_action(plrtile->site, continue); + + target_city_id = plrtile->site->identity; break; case ATK_UNIT: /* The unit should be sent as a target since it is possible to act _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits