Project

General

Profile

Bug #2452 » 0001-ai-default-Set-diplomat_threat-only-if-action-pos-v2.patch

Sweet Tea Dorminy, 11/08/2026 07:21 AM

View differences:

ai/default/daimilitary.c
#include "daimilitary.h"
static bool unit_is_diplomat_threat_to(const struct unit *punit,
const struct city *pcity);
/* Size 1 city gets destroyed when conquered. It's still a good thing
* stop enemy from having it. */
#define CITY_CONQUEST_WORTH(_city_, _data_) \
......
(void) dai_wants_defender_against(ait, nmap, pplayer, pcity, utype,
vulnerability / MAX(move_time, 1));
if (utype_acts_hostile(unit_type_get(punit)) && 2 >= move_time) {
if (2 >= move_time && unit_is_diplomat_threat_to(punit, pcity)) {
city_data->diplomat_threat = TRUE;
}
......
return choice;
}
/**********************************************************************//**
Could this unit, once beside the city, perform a hostile diplomat
action against it under the current ruleset, governments and
buildings? The actor and target requirements of the enablers answer
that. Range and movement are left out on purpose: this is asked of a
unit that is still up to two moves away. Attacks, conquest and
bombardment are hostile too, but they have a military answer, not a
defensive Diplomat.
**************************************************************************/
static bool unit_is_diplomat_threat_to(const struct unit *punit,
const struct city *pcity)
{
const struct unit_type *ut = unit_type_get(punit);
const struct req_context actor_ctx = {
.player = unit_owner(punit),
.tile = unit_tile(punit),
.unit = punit,
.unittype = ut,
};
const struct req_context target_ctx = {
.player = city_owner(pcity),
.city = pcity,
.tile = city_tile(pcity),
};
action_iterate(act_id) {
const struct action *paction = action_by_number(act_id);
if (action_get_target_kind(paction) != ATK_CITY
|| !utype_can_do_action(ut, act_id)) {
continue;
}
switch (paction->result) {
case ACTRES_SPY_INCITE_CITY:
case ACTRES_SPY_POISON:
case ACTRES_SPY_SPREAD_PLAGUE:
case ACTRES_SPY_SABOTAGE_CITY:
case ACTRES_SPY_TARGETED_SABOTAGE_CITY:
case ACTRES_SPY_SABOTAGE_CITY_PRODUCTION:
case ACTRES_SPY_STEAL_TECH:
case ACTRES_SPY_TARGETED_STEAL_TECH:
case ACTRES_SPY_STEAL_GOLD:
case ACTRES_SPY_NUKE:
break;
default:
continue;
}
action_enabler_list_iterate(action_enablers_for_action(act_id),
enabler) {
if (are_reqs_active(&actor_ctx, &target_ctx, &enabler->actor_reqs,
RPT_CERTAIN)
&& are_reqs_active(&target_ctx, &actor_ctx,
&enabler->target_reqs, RPT_CERTAIN)) {
return TRUE;
}
} action_enabler_list_iterate_end;
} action_iterate_end;
return FALSE;
}
(4-4/4)