From b62d13f2b48568c52f1cb79dcccf2570ec196c1f Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Fri, 15 Apr 2022 18:50:24 +0300 Subject: [PATCH 14/28] rssanity: Check that there is base City_Vision_Radius_Sq effect Requested by ddeanbrown See osdn #43647 Signed-off-by: Marko Lindqvist --- doc/README.effects | 2 ++ server/rssanity.c | 37 +++++++++++++++++++++++++++++++++---- server/rssanity.h | 5 ++++- server/ruleset.c | 2 +- tools/ruledit/tab_misc.cpp | 2 +- 5 files changed, 41 insertions(+), 7 deletions(-) diff --git a/doc/README.effects b/doc/README.effects index 2fb8b57f99..d6dfc47b62 100644 --- a/doc/README.effects +++ b/doc/README.effects @@ -459,6 +459,8 @@ per turn. City_Vision_Radius_Sq Increase city vision radius in squared distance by amount tiles. + There must be a base effect present in the ruleset; + one with no requirements at all, i.e., always active Unit_Vision_Radius_Sq Increase unit vision radius in squared distance by amount tiles. diff --git a/server/rssanity.c b/server/rssanity.c index 9cf2c3ce74..9dc6d748dd 100644 --- a/server/rssanity.c +++ b/server/rssanity.c @@ -494,6 +494,12 @@ static bool sanity_check_req_vec(const struct requirement_vector *preqs, return TRUE; } +typedef struct { + struct { + bool city_vision_radius_sq; + } base_effects; +} els_data; + /**********************************************************************//** Sanity check callback for iterating effects cache. **************************************************************************/ @@ -501,8 +507,15 @@ static bool effect_list_sanity_cb(struct effect *peffect, void *data) { int one_tile = -1; /* TODO: Determine correct value from effect. * -1 disables checking */ + els_data *els = (els_data *)data; - if (peffect->type == EFT_ACTION_SUCCESS_TARGET_MOVE_COST) { + /* TODO: Refactor this to more be more reusable when we check + * for more tha 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; + } + } else 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) { @@ -784,7 +797,7 @@ static bool sanity_check_boolean_effects(void) Returns TRUE iff everything ok. **************************************************************************/ -bool sanity_check_ruleset_data(bool ignore_retired) +bool sanity_check_ruleset_data(struct rscompat_info *compat) { int num_utypes; int i; @@ -793,6 +806,7 @@ bool sanity_check_ruleset_data(bool ignore_retired) * one. */ bool default_gov_failed = FALSE; bool obsoleted_by_loop = FALSE; + els_data els; if (!sanity_check_metadata()) { ok = FALSE; @@ -1002,12 +1016,27 @@ bool sanity_check_ruleset_data(bool ignore_retired) } } unit_type_iterate_end; + memset(&els, 0, sizeof(els)); + /* Check requirement sets against conflicting requirements. * For effects check also other sanity in the same iteration */ - if (!iterate_effect_cache(effect_list_sanity_cb, NULL)) { + if (!iterate_effect_cache(effect_list_sanity_cb, &els)) { ok = FALSE; } + if (!els.base_effects.city_vision_radius_sq) { + if (compat != NULL && compat->compat_mode && compat->version < RSFORMAT_3_1) { + log_deprecation("There is no base City_Vision_Radius_Sq effect."); + if (compat->log_cb != NULL) { + compat->log_cb(_("Missing base City_Vision_Radius_Sq effect. Please add one.")); + } + } else { + ruleset_error(LOG_ERROR, + "There is no base City_Vision_Radius_Sq effect."); + ok = FALSE; + } + } + if (!sanity_check_boolean_effects()) { ok = FALSE; } @@ -1225,7 +1254,7 @@ bool sanity_check_ruleset_data(bool ignore_retired) } } requirement_vector_iterate_end; - if (!ignore_retired) { + if (compat == NULL || !compat->compat_mode) { /* Support for letting some of the following hard requirements be * implicit were retired in Freeciv 3.0. Others were retired later. * Make sure that the opposite of each hard action requirement diff --git a/server/rssanity.h b/server/rssanity.h index 9f24257e5c..dbf0759506 100644 --- a/server/rssanity.h +++ b/server/rssanity.h @@ -20,9 +20,12 @@ extern "C" { /* common */ #include "fc_types.h" +/* server */ +#include "rscompat.h" + bool autoadjust_ruleset_data(void); bool autolock_settings(void); -bool sanity_check_ruleset_data(bool ignore_retired); +bool sanity_check_ruleset_data(struct rscompat_info *compat); bool sanity_check_server_setting_value_in_req(ssetv ssetval); diff --git a/server/ruleset.c b/server/ruleset.c index f46343439d..5bdfa50632 100644 --- a/server/ruleset.c +++ b/server/ruleset.c @@ -9346,7 +9346,7 @@ static bool load_rulesetdir(const char *rsdir, bool compat_mode, actions_rs_pre_san_gen(); ok = autoadjust_ruleset_data() - && sanity_check_ruleset_data(compat_info.compat_mode); + && sanity_check_ruleset_data(&compat_info); } if (ok) { diff --git a/tools/ruledit/tab_misc.cpp b/tools/ruledit/tab_misc.cpp index 76261ebb90..57090667eb 100644 --- a/tools/ruledit/tab_misc.cpp +++ b/tools/ruledit/tab_misc.cpp @@ -285,7 +285,7 @@ void tab_misc::save_now() strncpy(game.control.version, ba_bytes.data(), sizeof(game.control.version) - 1); - if (!autoadjust_ruleset_data() || !sanity_check_ruleset_data(false)) { + if (!autoadjust_ruleset_data() || !sanity_check_ruleset_data(NULL)) { QMessageBox *box = new QMessageBox(); box->setText("Current data fails sanity checks. Save anyway?"); -- 2.35.1