From bb8cbac6654d9d80b6d1df9a54c571b024dc0ee1 Mon Sep 17 00:00:00 2001 From: Sveinung Kvilhaugsvik Date: Mon, 22 Mar 2021 14:44:37 +0100 Subject: [PATCH] do_paradrop(): trust the action system. Trust that the action sent is correct when determining if a city conquest is legal or not in the action performer of the paradrop actions. Thanks to Marko for pointing out a bug in a previous version. See osdn #41827 --- common/actions.c | 2 +- server/unittools.c | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/common/actions.c b/common/actions.c index 48b3049123..46db850dc8 100644 --- a/common/actions.c +++ b/common/actions.c @@ -637,7 +637,7 @@ static void hard_code_oblig_hard_reqs(void) /* Why this is a hard requirement: Consistency with ACTRES_ATTACK. * Assumed by other locations in the Freeciv code. Examples: - * unit_move_to_tile_test() and unit_conquer_city(). */ + * unit_move_to_tile_test(), unit_conquer_city() and do_paradrop(). */ oblig_hard_req_register(req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL, FALSE, FALSE, TRUE, DS_WAR), FALSE, diff --git a/server/unittools.c b/server/unittools.c index 36a4801cf5..5ef60913b3 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -2866,7 +2866,24 @@ bool do_paradrop(struct unit *punit, struct tile *ptile, if (NULL != plrtile->site && plrtile->owner != NULL - && pplayers_non_attack(pplayer, plrtile->owner)) { + && !pplayers_allied(pplayer, plrtile->owner) + && !action_has_result(paction, ACTRES_PARADROP_CONQUER)) { + notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server, + /* Trans: Paratroopers ... Paradrop Unit */ + _("%s cannot conquer a city with \"%s\"."), + unit_name_translation(punit), + action_name_translation(paction)); + return FALSE; + } + + if (NULL != plrtile->site + && plrtile->owner != NULL + && (pplayers_non_attack(pplayer, plrtile->owner) + || (player_diplstate_get(pplayer, plrtile->owner)->type + == DS_ALLIANCE) + || (player_diplstate_get(pplayer, plrtile->owner)->type + == DS_TEAM)) + && action_has_result(paction, ACTRES_PARADROP_CONQUER)) { notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server, _("Cannot attack unless you declare war first.")); return FALSE; @@ -2890,12 +2907,8 @@ bool do_paradrop(struct unit *punit, struct tile *ptile, return TRUE; } - if (is_non_attack_city_tile(ptile, pplayer) - || (is_non_allied_city_tile(ptile, pplayer) - && (pplayer->ai_common.barbarian_type == ANIMAL_BARBARIAN - || !uclass_has_flag(unit_class_get(punit), - UCF_CAN_OCCUPY_CITY) - || unit_has_type_flag(punit, UTYF_CIVILIAN))) + if ((is_non_allied_city_tile(ptile, pplayer) + && !action_has_result(paction, ACTRES_PARADROP_CONQUER)) || is_non_allied_unit_tile(ptile, pplayer)) { map_show_circle(pplayer, ptile, unit_type_get(punit)->vision_radius_sq); maybe_make_contact(ptile, pplayer); -- 2.20.1