From ced05585797d45074cd5e32d6ff82493775b5d37 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!44345=20S=C5=82awomir=20Lach=20=20Add=20ruleset=20(save/load)=20counters-related=20co?= =?UTF-8?q?de?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/common/counters.c b/common/counters.c index aa3f647c15..3ad331e482 100644 --- a/common/counters.c +++ b/common/counters.c @@ -25,7 +25,7 @@ static struct counter counters[MAX_COUNTERS] = { - { (struct name_translation) NAME_INIT, CB_CITY_OWNED_TURNS, CTGT_CITY, 5, 0 } + }; static struct counter *counters_city[MAX_COUNTERS]; @@ -36,22 +36,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 +66,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 e805d89321..fd03fd2e62 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" @@ -108,6 +109,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)) @@ -1410,6 +1412,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; } @@ -7560,6 +7595,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 cd8b515173..16ed8214c6 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" @@ -1647,6 +1648,21 @@ static bool save_game_ruleset(const char *filename, const char *name) "trade.goods_selection"); } + 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; + /* Goods */ comment_goods(sfile); -- 2.36.1