From ef862513519e61faf177875d9e1a34a16e2d06d8 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 17 Dec 2022 23:18:18 +0200 Subject: [PATCH 37/37] Store array of extra specific clean times on terrains Internal structures reorganization only, not yet exposed to users. See osdn #46304 Signed-off-by: Marko Lindqvist --- client/gui-qt/helpdlg.cpp | 9 ++++--- client/helpdata.c | 26 ++++++++++---------- client/packhand.c | 8 ++++-- common/actions.c | 8 +++--- common/networking/packets.def | 9 +++++-- common/terrain.c | 42 ++++++++++++-------------------- common/terrain.h | 14 ++++++++--- server/ruleset.c | 46 ++++++++++++++++++++++++++--------- tools/civmanual.c | 3 ++- tools/ruleutil/rulesave.c | 4 +-- 10 files changed, 101 insertions(+), 68 deletions(-) diff --git a/client/gui-qt/helpdlg.cpp b/client/gui-qt/helpdlg.cpp index 4828efa7dd..893874d40e 100644 --- a/client/gui-qt/helpdlg.cpp +++ b/client/gui-qt/helpdlg.cpp @@ -1587,9 +1587,10 @@ struct terrain *help_widget::terrain_max_values() Terrain_type_id i, count; struct terrain *terrain; struct terrain *max = new struct terrain; + max->base_time = 0; - max->clean_fallout_time = 0; - max->clean_pollution_time = 0; + max->_retire.clean_fallout_time = 0; + max->_retire.clean_pollution_time = 0; max->defense_bonus = 0; max->irrigation_food_incr = 0; max->irrigation_time = 0; @@ -1617,8 +1618,8 @@ struct terrain *help_widget::terrain_max_values() #define SET_MAX(v) \ max->v = max->v > terrain->v ? max->v : terrain->v SET_MAX(base_time); - SET_MAX(clean_fallout_time); - SET_MAX(clean_pollution_time); + SET_MAX(_retire.clean_fallout_time); + SET_MAX(_retire.clean_pollution_time); SET_MAX(defense_bonus); SET_MAX(irrigation_food_incr); SET_MAX(irrigation_time); diff --git a/client/helpdata.c b/client/helpdata.c index 3d458de17c..8b801c18d3 100644 --- a/client/helpdata.c +++ b/client/helpdata.c @@ -269,21 +269,21 @@ static bool insert_generated_text(char *outbuf, size_t outlen, const char *name) (pterrain->transform_result == T_NONE) ? "-" : transform_time, transform_result); - if (clean_pollution_time != 0 && pterrain->clean_pollution_time != 0) { + if (clean_pollution_time != 0 && pterrain->_retire.clean_pollution_time != 0) { if (clean_pollution_time < 0) { - clean_pollution_time = pterrain->clean_pollution_time; + clean_pollution_time = pterrain->_retire.clean_pollution_time; } else { - if (clean_pollution_time != pterrain->clean_pollution_time) { - clean_pollution_time = 0; /* give up */ + if (clean_pollution_time != pterrain->_retire.clean_pollution_time) { + clean_pollution_time = 0; /* Give up */ } } } - if (clean_fallout_time != 0 && pterrain->clean_fallout_time != 0) { + if (clean_fallout_time != 0 && pterrain->_retire.clean_fallout_time != 0) { if (clean_fallout_time < 0) { - clean_fallout_time = pterrain->clean_fallout_time; + clean_fallout_time = pterrain->_retire.clean_fallout_time; } else { - if (clean_fallout_time != pterrain->clean_fallout_time) { - clean_fallout_time = 0; /* give up */ + if (clean_fallout_time != pterrain->_retire.clean_fallout_time) { + clean_fallout_time = 0; /* Give up */ } } } @@ -292,7 +292,7 @@ static bool insert_generated_text(char *outbuf, size_t outlen, const char *name) pillage_time = pterrain->pillage_time; } else { if (pillage_time != pterrain->pillage_time) { - pillage_time = 0; /* give up */ + pillage_time = 0; /* Give up */ } } } @@ -3850,13 +3850,13 @@ void helptext_extra(char *buf, size_t bufsz, struct player *pplayer, int terr_clean_time = -1; if (is_extra_removed_by(pextra, ERM_CLEANPOLLUTION) - && pterrain->clean_pollution_time != 0) { - terr_clean_time = pterrain->clean_pollution_time + && pterrain->_retire.clean_pollution_time != 0) { + terr_clean_time = pterrain->_retire.clean_pollution_time * pextra->removal_time_factor; } if (is_extra_removed_by(pextra, ERM_CLEANFALLOUT) - && pterrain->clean_fallout_time != 0) { - int terr_clean_fall_time = pterrain->clean_fallout_time + && pterrain->_retire.clean_fallout_time != 0) { + int terr_clean_fall_time = pterrain->_retire.clean_fallout_time * pextra->removal_time_factor; if (terr_clean_time > 0 diff --git a/client/packhand.c b/client/packhand.c index e155bed2ff..5ed82fee2e 100644 --- a/client/packhand.c +++ b/client/packhand.c @@ -4025,8 +4025,12 @@ void handle_ruleset_terrain(const struct packet_ruleset_terrain *p) pterrain->transform_time = p->transform_time; pterrain->placing_time = p->placing_time; pterrain->pillage_time = p->pillage_time; - pterrain->clean_pollution_time = p->clean_pollution_time; - pterrain->clean_fallout_time = p->clean_fallout_time; + pterrain->_retire.clean_pollution_time = p->clean_pollution_time; + pterrain->_retire.clean_fallout_time = p->clean_fallout_time; + + for (j = 0; j < p->extra_count; j++) { + pterrain->extra_removal_times[j] = p->extra_removal_times[j]; + } pterrain->flags = p->flags; diff --git a/common/actions.c b/common/actions.c index 471289d16b..0c8e18d6cc 100644 --- a/common/actions.c +++ b/common/actions.c @@ -4381,12 +4381,12 @@ is_action_possible(const action_id wanted_action, actor->unit); } - if (pextra != NULL && pterrain->clean_pollution_time > 0 + if (pextra != NULL && pterrain->_retire.clean_pollution_time > 0 && can_remove_extra(pextra, actor->unit, target->tile)) { return TRI_YES; } - if (fextra != NULL && pterrain->clean_fallout_time > 0 + if (fextra != NULL && pterrain->_retire.clean_fallout_time > 0 && can_remove_extra(fextra, actor->unit, target->tile)) { return TRI_YES; } @@ -4399,7 +4399,7 @@ is_action_possible(const action_id wanted_action, const struct extra_type *pextra; pterrain = tile_terrain(target->tile); - if (pterrain->clean_pollution_time == 0) { + if (pterrain->_retire.clean_pollution_time == 0) { return TRI_NO; } @@ -4439,7 +4439,7 @@ is_action_possible(const action_id wanted_action, const struct extra_type *pextra; pterrain = tile_terrain(target->tile); - if (pterrain->clean_fallout_time == 0) { + if (pterrain->_retire.clean_fallout_time == 0) { return TRI_NO; } diff --git a/common/networking/packets.def b/common/networking/packets.def index 9675e64d0b..9a75f5c329 100644 --- a/common/networking/packets.def +++ b/common/networking/packets.def @@ -1710,6 +1710,11 @@ PACKET_RULESET_TERRAIN = 151; sc, lsend UINT8 clean_fallout_time; UINT8 pillage_time; + # extra_count = game.control.num_extra_types, but generated packets code does not + # support getting array length from outside packet. + UINT8 extra_count; + UINT8 extra_removal_times[MAX_EXTRA_TYPES:extra_count]; + UINT8 color_red; UINT8 color_green; UINT8 color_blue; @@ -1929,8 +1934,8 @@ end /************************************************************************** Ruleset control values: single values, all of which are needed before - sending other ruleset data. After sending this packet, resend every - other part of the rulesets. (Terrain ruleset has enough info for its + sending other ruleset data. After sending this packet, resend every + other part of the rulesets. (Terrain ruleset has enough info for its own "control" packet, done separately.) **************************************************************************/ PACKET_RULESET_CONTROL = 155; sc, lsend diff --git a/common/terrain.c b/common/terrain.c index 2321f159fd..6b63c366b7 100644 --- a/common/terrain.c +++ b/common/terrain.c @@ -44,11 +44,17 @@ void terrains_init(void) int i; for (i = 0; i < ARRAY_SIZE(civ_terrains); i++) { + int j; + /* Can't use terrain_by_number here because it does a bounds check. */ civ_terrains[i].item_number = i; civ_terrains[i].ruledit_disabled = FALSE; civ_terrains[i].rgb = NULL; civ_terrains[i].animal = NULL; + + for (j = 0; j < MAX_EXTRA_TYPES; j++) { + civ_terrains[i].extra_removal_times[j] = 0; + } } } @@ -759,42 +765,26 @@ int terrain_extra_removal_time(const struct terrain *pterrain, case ACTIVITY_CLEAN: { if (tgt == NULL) { - if (pterrain->clean_pollution_time > 0 - && pterrain->clean_fallout_time > 0) { - return MIN(pterrain->clean_pollution_time, pterrain->clean_fallout_time) + if (pterrain->_retire.clean_pollution_time > 0 + && pterrain->_retire.clean_fallout_time > 0) { + return MIN(pterrain->_retire.clean_pollution_time, + pterrain->_retire.clean_fallout_time) * factor; } - if (pterrain->clean_pollution_time > 0) { - return pterrain->clean_pollution_time * factor; + if (pterrain->_retire.clean_pollution_time > 0) { + return pterrain->_retire.clean_pollution_time * factor; } - return pterrain->clean_fallout_time * factor; - } - - if (is_extra_removed_by(tgt, ERM_CLEANPOLLUTION)) { - if (!is_extra_removed_by(tgt, ERM_CLEANFALLOUT)) { - return pterrain->clean_pollution_time * factor; - } - - /* Has both removal causes */ - if (pterrain->clean_pollution_time > 0 - && pterrain->clean_fallout_time > 0) { - return MIN(pterrain->clean_pollution_time, pterrain->clean_fallout_time) - * factor; - } - - if (pterrain->clean_pollution_time > 0) { - return pterrain->clean_pollution_time * factor; - } + return pterrain->_retire.clean_fallout_time * factor; } - return pterrain->clean_fallout_time * factor; + return pterrain->extra_removal_times[extra_index(tgt)] * factor; } case ACTIVITY_POLLUTION: - return pterrain->clean_pollution_time * factor; + return pterrain->_retire.clean_pollution_time * factor; case ACTIVITY_FALLOUT: - return pterrain->clean_fallout_time * factor; + return pterrain->_retire.clean_fallout_time * factor; case ACTIVITY_PILLAGE: return pterrain->pillage_time * factor; default: diff --git a/common/terrain.h b/common/terrain.h index 9829a93e7c..395499cd4e 100644 --- a/common/terrain.h +++ b/common/terrain.h @@ -225,11 +225,19 @@ struct terrain { int placing_time; struct terrain *transform_result; + int transform_time; - int clean_pollution_time; - int clean_fallout_time; + + struct { + int clean_pollution_time; + int clean_fallout_time; + } _retire; + int pillage_time; + /* Currently only clean times, but named for future */ + int extra_removal_times[MAX_EXTRA_TYPES]; + const struct unit_type *animal; /* May be NULL if the transformation is impossible. */ @@ -393,4 +401,4 @@ const struct terrain *terrain_array_last(void); } #endif /* __cplusplus */ -#endif /* FC__TERRAIN_H */ +#endif /* FC__TERRAIN_H */ diff --git a/server/ruleset.c b/server/ruleset.c index 7a9754f189..b0ba11363d 100644 --- a/server/ruleset.c +++ b/server/ruleset.c @@ -3485,18 +3485,18 @@ static bool load_ruleset_terrain(struct section_file *file, break; } - pterrain->placing_time = 1; /* default */ + pterrain->placing_time = 1; /* Default */ lookup_time(file, &pterrain->placing_time, tsection, "placing_time", filename, NULL, &ok); - pterrain->pillage_time = 1; /* default */ + pterrain->pillage_time = 1; /* Default */ lookup_time(file, &pterrain->pillage_time, tsection, "pillage_time", filename, NULL, &ok); - pterrain->clean_pollution_time = 3; /* default */ - lookup_time(file, &pterrain->clean_pollution_time, + pterrain->_retire.clean_pollution_time = 3; /* Default */ + lookup_time(file, &pterrain->_retire.clean_pollution_time, tsection, "clean_pollution_time", filename, NULL, &ok); - pterrain->clean_fallout_time = 3; /* default */ - lookup_time(file, &pterrain->clean_fallout_time, + pterrain->_retire.clean_fallout_time = 3; /* Default */ + lookup_time(file, &pterrain->_retire.clean_fallout_time, tsection, "clean_fallout_time", filename, NULL, &ok); if (!lookup_terrain(file, "warmer_wetter_result", filename, pterrain, @@ -3536,6 +3536,7 @@ static bool load_ruleset_terrain(struct section_file *file, { enum mapgen_terrain_property mtp; + for (mtp = mapgen_terrain_property_begin(); mtp != mapgen_terrain_property_end(); mtp = mapgen_terrain_property_next(mtp)) { @@ -3566,9 +3567,10 @@ static bool load_ruleset_terrain(struct section_file *file, break; } - /* get terrain color */ + /* Get terrain color */ { fc_assert_ret_val(pterrain->rgb == NULL, FALSE); + if (!rgbcolor_load(file, &pterrain->rgb, "%s.color", tsection)) { ruleset_error(NULL, LOG_ERROR, "Missing terrain color definition: %s", @@ -3583,13 +3585,14 @@ static bool load_ruleset_terrain(struct section_file *file, } if (ok) { - /* extra details */ + /* Extra details */ extra_type_iterate(pextra) { BV_CLR_ALL(pextra->conflicts); } extra_type_iterate_end; extra_type_iterate(pextra) { - const char *section = &extra_sections[extra_index(pextra) * MAX_SECTION_LABEL]; + int eidx = extra_index(pextra); + const char *section = &extra_sections[eidx * MAX_SECTION_LABEL]; const char **slist; struct requirement_vector *reqs; const char *catname; @@ -3666,6 +3669,22 @@ static bool load_ruleset_terrain(struct section_file *file, } else { pextra->rmcauses |= (1 << rmcause); extra_to_removed_by_list(pextra, rmcause); + + terrain_type_iterate(pterr) { + int cleantime = 0; + + if (rmcause == ERM_CLEANPOLLUTION) { + cleantime = pterr->_retire.clean_pollution_time; + } else if (rmcause == ERM_CLEANFALLOUT) { + cleantime = pterr->_retire.clean_fallout_time; + } + + if (cleantime > 0 + && (pterr->extra_removal_times[eidx] == 0 + || cleantime < pterr->extra_removal_times[eidx])) { + pterr->extra_removal_times[eidx] = cleantime; + } + } terrain_type_iterate_end; } } @@ -8381,8 +8400,13 @@ static void send_ruleset_terrain(struct conn_list *dest) packet.placing_time = pterrain->placing_time; packet.pillage_time = pterrain->pillage_time; packet.transform_time = pterrain->transform_time; - packet.clean_pollution_time = pterrain->clean_pollution_time; - packet.clean_fallout_time = pterrain->clean_fallout_time; + packet.clean_pollution_time = pterrain->_retire.clean_pollution_time; + packet.clean_fallout_time = pterrain->_retire.clean_fallout_time; + + packet.extra_count = game.control.num_extra_types; + for (i = 0; i < game.control.num_extra_types; i++) { + packet.extra_removal_times[i] = pterrain->extra_removal_times[i]; + } packet.flags = pterrain->flags; diff --git a/tools/civmanual.c b/tools/civmanual.c index 3003766777..934264ed2e 100644 --- a/tools/civmanual.c +++ b/tools/civmanual.c @@ -558,7 +558,8 @@ static bool manual_command(struct tag_types *tag_info) pterrain->road_output_incr_pct[O_TRADE]); fprintf(doc, "%d / %d", - pterrain->clean_pollution_time, pterrain->clean_fallout_time); + pterrain->_retire.clean_pollution_time, + pterrain->_retire.clean_fallout_time); ri = 0; if (game.control.num_road_types > 0) { diff --git a/tools/ruleutil/rulesave.c b/tools/ruleutil/rulesave.c index c5526984e1..b1bde303ae 100644 --- a/tools/ruleutil/rulesave.c +++ b/tools/ruleutil/rulesave.c @@ -2569,9 +2569,9 @@ static bool save_terrain_ruleset(const char *filename, const char *name) "%s.placing_time", path); secfile_insert_int(sfile, pterr->pillage_time, "%s.pillage_time", path); - secfile_insert_int(sfile, pterr->clean_pollution_time, + secfile_insert_int(sfile, pterr->_retire.clean_pollution_time, "%s.clean_pollution_time", path); - secfile_insert_int(sfile, pterr->clean_fallout_time, + secfile_insert_int(sfile, pterr->_retire.clean_fallout_time, "%s.clean_fallout_time", path); save_terrain_ref(sfile, pterr->warmer_wetter_result, pterr, path, -- 2.35.1