From 4eae4d7cdf4906b7776288fd0365e835e7f5c674 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Wed, 29 Mar 2023 05:18:29 +0300 Subject: [PATCH 51/51] Ruleset sanity: Make Max_Rates base effect mandatory See osdn #47626 Signed-off-by: Marko Lindqvist --- server/rssanity.c | 68 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/server/rssanity.c b/server/rssanity.c index 4761b3071a..b5fb44d983 100644 --- a/server/rssanity.c +++ b/server/rssanity.c @@ -38,6 +38,22 @@ #include "rssanity.h" +/* These effects are always needed in the ruleset. + * First set are those that are mandatory even in compatibility mode. */ +enum effect_type req_base_effects[] = + { + EFT_CITY_VISION_RADIUS_SQ, + EFT_MAX_RATES, + EFT_COUNT + }; + +/* These have been made mandatory in freeciv-3.3 */ +enum effect_type req_base_effects_3_3[] = + { + /* None yet */ + EFT_COUNT + }; + /**********************************************************************//** Is non-rule data in ruleset sane? **************************************************************************/ @@ -502,7 +518,7 @@ static bool sanity_check_req_vec(rs_conversion_logger logger, typedef struct { struct { - bool city_vision_radius_sq; + bool effect_present[EFT_COUNT]; } base_effects; rs_conversion_logger logger; } els_data; @@ -516,14 +532,22 @@ static bool effect_list_sanity_cb(struct effect *peffect, void *data) * -1 disables checking */ els_data *els = (els_data *)data; struct astring astr; + int i; - /* TODO: Refactor this to be more reusable when we check - * for more than one base effect. */ - if (peffect->type == EFT_CITY_VISION_RADIUS_SQ) { - if (requirement_vector_size(&peffect->reqs) == 0) { - els->base_effects.city_vision_radius_sq = TRUE; + for (i = 0; req_base_effects[i] != EFT_COUNT; i++) { + if (peffect->type == req_base_effects[i]) { + els->base_effects.effect_present[peffect->type] = TRUE; + break; } - } else if (peffect->type == EFT_ACTION_SUCCESS_TARGET_MOVE_COST) { + } + for (i = 0; req_base_effects_3_3[i] != EFT_COUNT; i++) { + if (peffect->type == req_base_effects_3_3[i]) { + els->base_effects.effect_present[peffect->type] = TRUE; + break; + } + } + + if (peffect->type == EFT_ACTION_SUCCESS_TARGET_MOVE_COST) { /* Only unit targets can pay in move fragments. */ requirement_vector_iterate(&peffect->reqs, preq) { if (preq->source.kind == VUT_ACTION) { @@ -1064,10 +1088,32 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) ok = FALSE; } - if (!els.base_effects.city_vision_radius_sq) { - ruleset_error(logger, LOG_ERROR, - "There is no base City_Vision_Radius_Sq effect."); - ok = FALSE; + for (i = 0; req_base_effects[i] != EFT_COUNT; i++) { + if (!els.base_effects.effect_present[req_base_effects[i]]) { + ruleset_error(logger, LOG_ERROR, + "There is no base %s effect.", + effect_type_name(req_base_effects[i])); + ok = FALSE; + } + } + for (i = 0; req_base_effects_3_3[i] != EFT_COUNT; i++) { + if (!els.base_effects.effect_present[req_base_effects_3_3[i]]) { + const char *ename = effect_type_name(req_base_effects_3_3[i]); + + if (compat != NULL && compat->compat_mode && compat->version < RSFORMAT_3_3) { + log_deprecation("There is no base %s effect.", ename); + if (compat->log_cb != NULL) { + char buf[512]; + + fc_snprintf(buf, sizeof(buf), _("Missing base %s effect. Please add one."), ename); + compat->log_cb(buf); + } + } else { + ruleset_error(logger, LOG_ERROR, + "There is no base %s effect.", ename); + ok = FALSE; + } + } } if (!sanity_check_boolean_effects(logger)) { -- 2.39.2