Project

General

Profile

Bug #1583 » 3_4-is_acton_possible-norange1.patch

Alexandr Ignatiev, 07/12/2025 01:06 AM

View differences:

common/actions.c
enum fc_tristate out;
struct action *paction = action_by_number(wanted_action);
enum action_target_kind tkind = action_get_target_kind(paction);
const struct tile *atile = nullptr, *ttile = nullptr;
if (actor == NULL) {
if (actor == nullptr) {
actor = req_context_empty();
} else {
atile = actor->tile;
}
if (target == NULL) {
if (target == nullptr) {
target = req_context_empty();
} else {
ttile = target->tile;
}
fc_assert_msg((tkind == ATK_CITY && target->city != NULL)
|| (tkind == ATK_TILE && target->tile != NULL)
|| (tkind == ATK_EXTRAS && target->tile != NULL)
|| (tkind == ATK_UNIT && target->unit != NULL)
fc_assert_msg((tkind == ATK_CITY && target->city != nullptr)
|| (tkind == ATK_TILE && ttile != nullptr)
|| (tkind == ATK_EXTRAS && ttile != nullptr)
|| (tkind == ATK_UNIT && target->unit != nullptr)
/* At this level each individual unit is tested. */
|| (tkind == ATK_STACK && target->unit != NULL)
|| (tkind == ATK_STACK && target->unit != nullptr)
|| (tkind == ATK_SELF),
"Missing target!");
/* Info leak: The player knows where their unit is. */
if (tkind != ATK_SELF
/* Info leak: The player knows where their unit/city is. */
if (nullptr != atile && nullptr != ttile
&& !action_distance_accepted(paction,
real_map_distance(actor->tile,
target->tile))) {
real_map_distance(atile, ttile))) {
/* The distance between the actor and the target isn't inside the
* action's accepted range. */
return TRI_NO;
......
}
if (action_is_blocked_by(nmap, paction, actor->unit,
target->tile, target->city, target->unit)) {
ttile, target->city, target->unit)) {
/* Allows an action to block an other action. If a blocking action is
* legal the actions it blocks becomes illegal. */
return TRI_NO;
......
|| paction->result == ACTRES_WIPE_UNITS
|| paction->result == ACTRES_COLLECT_RANSOM) {
/* Reason: Keep the old rules. */
if (!can_unit_attack_tile(actor->unit, paction, target->tile)) {
if (!can_unit_attack_tile(actor->unit, paction, ttile)) {
return TRI_NO;
}
}
......
}
if (paction->result == ACTRES_NUKE_UNITS) {
if (unit_attack_units_at_tile_result(actor->unit, paction,
target->tile)
if (unit_attack_units_at_tile_result(actor->unit, paction, ttile)
!= ATT_OK) {
/* Unreachable. */
return TRI_NO;
}
} else if (paction->result == ACTRES_PARADROP
|| paction->result == ACTRES_PARADROP_CONQUER) {
if (can_player_see_tile(actor->player, target->tile)) {
if (can_player_see_tile(actor->player, ttile)) {
/* Check for seen stuff that may kill the actor unit. */
/* Reason: Keep the old rules. Be merciful. */
/* Info leak: The player sees the target tile. */
if (!can_unit_exist_at_tile(nmap, actor->unit, target->tile)
if (!can_unit_exist_at_tile(nmap, actor->unit, ttile)
&& (!BV_ISSET(paction->sub_results, ACT_SUB_RES_MAY_EMBARK)
|| !unit_could_load_at(actor->unit, target->tile))) {
|| !unit_could_load_at(actor->unit, ttile))) {
return TRI_NO;
}
/* Reason: Keep the old rules. Be merciful. */
/* Info leak: The player sees the target tile. */
if (is_non_attack_city_tile(target->tile, actor->player)) {
if (is_non_attack_city_tile(ttile, actor->player)) {
return TRI_NO;
}
/* Reason: Be merciful. */
/* Info leak: The player sees all units checked. Invisible units are
* ignored. */
unit_list_iterate(target->tile->units, pother) {
unit_list_iterate(ttile->units, pother) {
if (can_player_see_unit(actor->player, pother)
&& !pplayers_allied(actor->player, unit_owner(pother))) {
return TRI_NO;
(2-2/2)