From bb237cf44ad902803e9b12487ed0cfde5cacd507 Mon Sep 17 00:00:00 2001 From: Sveinung Kvilhaugsvik Date: Tue, 23 Feb 2021 13:36:57 +0100 Subject: [PATCH 2/2] ruleup: detect more unused action enablers. Detect action enablers that are unused because no actor that fulfills its hard requirements fulfills the action's hard requirements. See osdn #41643 --- common/actions.c | 34 ++++++++++++++++++++++++++++++++++ common/actions.h | 1 + server/ruleset.c | 2 +- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/common/actions.c b/common/actions.c index 8e0b4eb62a..e5225579d7 100644 --- a/common/actions.c +++ b/common/actions.c @@ -6728,6 +6728,40 @@ bool action_enabler_utype_possible_actor(const struct action_enabler *ae, &actor_univ)); } +/**********************************************************************//** + Returns TRUE iff the specified action enabler may have an actor that it + may be enabled for in the current ruleset. An enabler can't be enabled if + no potential actor fulfills both its action's hard requirements and its + own actor requirement vector, actor_reqs. + Note that the answer may be "no" even if this function returns TRUE. It + may just be unable to detect it. + @param ae the action enabler to check + @returns TRUE if the enabler may be enabled at all +**************************************************************************/ +bool action_enabler_possible_actor(const struct action_enabler *ae) +{ + const struct action *paction = action_by_number(ae->action); + + switch (action_get_actor_kind(paction)) { + case AAK_UNIT: + unit_type_iterate(putype) { + if (action_enabler_utype_possible_actor(ae, putype)) { + /* A possible actor unit type has been found. */ + return TRUE; + } + } unit_type_iterate_end; + + /* No actor detected. */ + return FALSE; + case AAK_COUNT: + fc_assert(action_get_actor_kind(paction) != AAK_COUNT); + break; + } + + /* No actor detected. */ + return FALSE; +} + /**********************************************************************//** Returns TRUE iff the specified action has an actor that fulfills its hard requirements in the current ruleset. diff --git a/common/actions.h b/common/actions.h index fdb3ce3ad5..3c7cddd52c 100644 --- a/common/actions.h +++ b/common/actions.h @@ -727,6 +727,7 @@ const char *action_enabler_vector_by_number_name(req_vec_num_in_item vec); bool action_enabler_utype_possible_actor(const struct action_enabler *ae, const struct unit_type *act_utype); +bool action_enabler_possible_actor(const struct action_enabler *ae); struct action *action_is_blocked_by(const struct action *act, const struct unit *actor_unit, diff --git a/server/ruleset.c b/server/ruleset.c index d9836d1cfc..86a0025dc0 100644 --- a/server/ruleset.c +++ b/server/ruleset.c @@ -252,7 +252,7 @@ static int ruleset_purge_unused_enablers(void) action_enabler_list_iterate(action_enablers_for_action(paction->id), ae) { if (!ae->disabled - && (req_vec_is_impossible_to_fulfill(&ae->actor_reqs) + && (!action_enabler_possible_actor(ae) || req_vec_is_impossible_to_fulfill(&ae->target_reqs))) { ae->disabled = TRUE; purged++; -- 2.20.1