From a3dc229298bed8545a54c06435c2fbb7c4c4b3e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awomir=20Lach?= Date: Sun, 17 Apr 2022 10:34:26 +0200 Subject: [PATCH] =?UTF-8?q?OSDN!41121=20S=C5=82awomir=20Lach=20=20-=20Add=20routines=20to=20load=20counters=20from=20?= =?UTF-8?q?ruleset=20Basic=20routines=20to=20load=20counter=20definitions?= =?UTF-8?q?=20from=20ruleset=20are=20added=20by=20this=20patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit !OSDN 44345 - SÅ‚awomir Lach Add (partial?; untested) the possibility of saving city counters diff --git a/common/counters.c b/common/counters.c index aa3f647c15..5c50bcff7e 100644 --- a/common/counters.c +++ b/common/counters.c @@ -23,10 +23,7 @@ #include "counters.h" -static struct counter counters[MAX_COUNTERS] = -{ - { (struct name_translation) NAME_INIT, CB_CITY_OWNED_TURNS, CTGT_CITY, 5, 0 } -}; +static struct counter counters[MAX_COUNTERS]; static struct counter *counters_city[MAX_COUNTERS]; static int number_city_counters; @@ -36,22 +33,7 @@ static int number_city_counters; ****************************************************************************/ void counters_init(void) { - int i; - number_city_counters = 0; - - name_set(&counters[0].name, NULL, N_("?counter:Owned")); - - for (i = 0; i < MAX_COUNTERS; i++) { - - if (counters[i].type == CB_CITY_OWNED_TURNS) { - /* City counter type */ - counters_city[number_city_counters] = &counters[i]; - counters[i].index = number_city_counters; - counters[i].target = CTGT_CITY; - number_city_counters++; - } - } } @@ -81,6 +63,17 @@ struct counter *counter_by_id(int id) return &counters[id]; } +/************************************************************************//** + Attaching given counter type to array containing counter type + related to cities. Counter must be present in array for + each counter in game, but we do not check this. +****************************************************************************/ +void attach_city_counter(struct counter *counter) +{ + counters_city[number_city_counters] = counter; + number_city_counters++; +} + /************************************************************************//** Return id of a given counter ****************************************************************************/ diff --git a/common/counters.h b/common/counters.h index 1848e9e9d2..394c1e1e83 100644 --- a/common/counters.h +++ b/common/counters.h @@ -58,6 +58,7 @@ struct counter *counter_by_translated_name(const char *name); int counter_index(struct counter *pcount); struct counter *counter_by_index(int index, enum counter_target target); int counters_get_city_counters_count(void); +void attach_city_counter(struct counter *counter); #define city_counters_iterate(pcount) { \ int _i_##pcount; \ diff --git a/server/ruleset.c b/server/ruleset.c index fc3b5d8537..8ae8025e3e 100644 --- a/server/ruleset.c +++ b/server/ruleset.c @@ -38,6 +38,7 @@ #include "base.h" #include "capability.h" #include "city.h" +#include "counters.h" #include "effects.h" #include "extras.h" #include "fc_types.h" @@ -109,6 +110,7 @@ #define ACHIEVEMENT_SECTION_PREFIX "achievement_" #define ACTION_ENABLER_SECTION_PREFIX "actionenabler_" #define MULTIPLIER_SECTION_PREFIX "multiplier_" +#define COUNTER_SECTION_PREFIX "counter_" #define check_name(name) (check_strlen(name, MAX_LEN_NAME, NULL)) #define check_cityname(name) (check_strlen(name, MAX_LEN_CITYNAME, NULL)) @@ -1411,6 +1413,39 @@ static bool load_game_names(struct section_file *file, section_list_destroy(sec); } + if (ok) { + + sec = secfile_sections_by_name_prefix(file, COUNTER_SECTION_PREFIX); + + nval = (NULL != sec ? section_list_size(sec) : 0); + if (nval > MAX_COUNTERS) { + size_t num = nval; + + ruleset_error(LOG_ERROR, + "\"%s\": Too many counters (" SIZE_T_PRINTF ", max %d)", + filename, num, MAX_COUNTERS); + ok = FALSE; + } + + if (ok) { + int count_idx; + + for (count_idx = 0; count_idx < nval; count_idx++) { + struct counter *pcount = counter_by_id(count_idx); + const char *sec_name + = section_name(section_list_get(sec, counter_index(pcount))); + + if (!ruleset_load_names(&pcount->name, NULL, file, sec_name)) { + ruleset_error(LOG_ERROR, "\"%s\": Cannot load counters names", + filename); + ok = FALSE; + break; + } + } + } + section_list_destroy(sec); + } + return ok; } @@ -7615,6 +7650,57 @@ static bool load_ruleset_game(struct section_file *file, bool act, section_list_destroy(sec); } + if (ok) { + sec = secfile_sections_by_name_prefix(file, COUNTER_SECTION_PREFIX); + + if (sec != NULL) { + int num = section_list_size(sec); + int curr; + + for (curr = 0; curr < num; curr++) { + + struct counter *pcount = counter_by_id(curr); + const char *sec_name = section_name(section_list_get(sec, curr)); + const char *counter_type = secfile_lookup_str_default(file, NULL, + "%s.type", + sec_name); + + enum counter_behaviour cb = counter_behaviour_by_name(counter_type, + fc_strcasecmp); + if (!counter_behaviour_is_valid(cb)) { + ruleset_error(LOG_ERROR, "\"%s\" unknown counter type \"%s\".", + filename, counter_type); + ok = FALSE; + break; + } + + if (!ruleset_load_names(&pcount->name, NULL, file, sec_name)) { + ruleset_error(LOG_ERROR, "\"%s\": Cannot load counter names", + filename); + ok = FALSE; + break; + } + + pcount->type = cb; + if (!secfile_lookup_int(file, &pcount->checkpoint, + "%s.checkpoint", sec_name)) { + + ruleset_error(LOG_ERROR, "\"%s\": No checkpoint value", + filename); + ok = FALSE; + break; + } + + pcount->target = CTGT_CITY; + pcount->index = curr; + pcount->def = secfile_lookup_int_default(file, 0, + "%s.def", + sec_name); + attach_city_counter(pcount); + } + } + } + /* secfile_check_unused() is not here, but only after also settings section * has been loaded. */ diff --git a/tools/ruleutil/rulesave.c b/tools/ruleutil/rulesave.c index 5f75e9aa81..282ae3e639 100644 --- a/tools/ruleutil/rulesave.c +++ b/tools/ruleutil/rulesave.c @@ -21,6 +21,7 @@ /* common */ #include "achievements.h" +#include "counters.h" #include "game.h" #include "government.h" #include "map.h" @@ -1720,6 +1721,21 @@ static bool save_game_ruleset(const char *filename, const char *name) } } + sect_idx = 0; + city_counters_iterate(pcounter) { + char path[512]; + + fc_snprintf(path, sizeof(path), "counter_%d", sect_idx++); + + save_name_translation(sfile, &(pcounter->name), path); + + save_default_int(sfile, pcounter->def, 0, path, "default"); + save_default_int(sfile, pcounter->checkpoint, 0, path, "checkpoint"); + + secfile_insert_str(sfile, counter_behaviour_name(pcounter->type), "%s.type", path); + + } city_counters_iterate_end; + locks = FALSE; settings_iterate(SSET_ALL, pset) { if (setting_locked(pset)) { -- 2.36.1