From f5ba4c66335c65c1a11690d412117aebbcb12ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awomir=20Lach?= Date: Sun, 20 Feb 2022 17:55:23 +0100 Subject: [PATCH] =?UTF-8?q?!OSDN=2041120=20S=C5=82awomir=20Lach=20-=20Intr?= =?UTF-8?q?oduce=20checkpoint=20value=20and=20counter=20req=20type=20-=20D?= =?UTF-8?q?ocument=20some=20new=20ruleset=20creator=20possibilities?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/ai/default/daieffects.c b/ai/default/daieffects.c index 4157b572b2..24fb690e6a 100644 --- a/ai/default/daieffects.c +++ b/ai/default/daieffects.c @@ -810,6 +810,7 @@ bool dai_can_requirement_be_met_in_city(const struct requirement *preq, return TRUE; case VUT_NONE: + case VUT_COUNTER: case VUT_UTYPE: case VUT_UTFLAG: case VUT_UCLASS: diff --git a/common/counters.c b/common/counters.c index ae5cebdce6..728a113d23 100644 --- a/common/counters.c +++ b/common/counters.c @@ -25,7 +25,7 @@ static struct counter counters[MAX_COUNTERS] = { - { (struct name_translation) NAME_INIT, COUNTER_OWNED, CTGT_CITY, 0 } + { (struct name_translation) NAME_INIT, COUNTER_OWNED, CTGT_CITY, 5, 0 } }; static struct counter *counters_city[MAX_COUNTERS]; diff --git a/common/counters.h b/common/counters.h index 934cb9a899..f29924a585 100644 --- a/common/counters.h +++ b/common/counters.h @@ -32,6 +32,7 @@ struct counter struct name_translation name; enum counter_type type; enum counter_target target; + int checkpoint; int def; /* default value for each entity of given type * for this counter */ diff --git a/common/fc_types.h b/common/fc_types.h index 0c700b515c..567666245e 100644 --- a/common/fc_types.h +++ b/common/fc_types.h @@ -608,6 +608,7 @@ enum req_problem_type { * Used in the network protocol. */ typedef union { struct advance *advance; + struct counter *counter; struct government *govern; const struct impr_type *building; struct nation_type *nation; @@ -765,6 +766,8 @@ typedef union { #define SPECENUM_VALUE48NAME "DiplRelUnitAnyOther" #define SPECENUM_VALUE49 VUT_MINLATITUDE #define SPECENUM_VALUE49NAME "MinLatitude" +#define SPECENUM_VALUE50 VUT_COUNTER +#define SPECENUM_VALUE50NAME "Counter" /* Keep this last. */ #define SPECENUM_COUNT VUT_COUNT #include "specenum_gen.h" diff --git a/common/reqtext.c b/common/reqtext.c index 78cbcc62af..3f53205b6d 100644 --- a/common/reqtext.c +++ b/common/reqtext.c @@ -23,6 +23,7 @@ #include "achievements.h" #include "actions.h" #include "calendar.h" +#include "counters.h" #include "extras.h" #include "government.h" #include "map.h" @@ -54,6 +55,23 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, case VUT_NONE: return FALSE; + case VUT_COUNTER: + if (preq->present) { + + fc_strlcat(buf, prefix, bufsz); + cat_snprintf(buf, bufsz, + _("Requires counter %s to achieve at minimum %d value"), + counter_rule_name(preq->source.value.counter), + preq->source.value.counter->checkpoint); + } else { + + fc_strlcat(buf, prefix, bufsz); + cat_snprintf(buf, bufsz, + _("Requires counter %s to achieve at maximum %d value"), + counter_rule_name(preq->source.value.counter), + preq->source.value.counter->checkpoint - 1); + } + break; case VUT_ADVANCE: switch (preq->range) { case REQ_RANGE_PLAYER: diff --git a/common/requirements.c b/common/requirements.c index 1de5882bac..4f419e68a0 100644 --- a/common/requirements.c +++ b/common/requirements.c @@ -26,6 +26,7 @@ #include "achievements.h" #include "calendar.h" #include "citizens.h" +#include "counters.h" #include "culture.h" #include "game.h" #include "government.h" @@ -385,6 +386,12 @@ void universal_value_from_str(struct universal *source, const char *value) return; } break; + case VUT_COUNTER: + source->value.counter = counter_by_rule_name(value); + if (source->value.counter != NULL) { + return; + } + break; case VUT_COUNT: break; } @@ -586,6 +593,9 @@ struct universal universal_by_number(const enum universals_n kind, case VUT_CITYSTATUS: source.value.citystatus = value; return source; + case VUT_COUNTER: + source.value.counter = counter_by_id(value); + return source; case VUT_MINLATITUDE: source.value.latitude = value; return source; @@ -712,6 +722,8 @@ int universal_number(const struct universal *source) return source->value.citytile; case VUT_CITYSTATUS: return source->value.citystatus; + case VUT_COUNTER: + return counter_id(source->value.counter); case VUT_MINLATITUDE: return source->value.latitude; case VUT_COUNT: @@ -816,6 +828,7 @@ struct requirement req_from_str(const char *type, const char *range, case VUT_MINLATITUDE: req.range = REQ_RANGE_TILE; break; + case VUT_COUNTER: case VUT_MINSIZE: case VUT_MINCULTURE: case VUT_MINFOREIGNPCT: @@ -980,6 +993,9 @@ struct requirement req_from_str(const char *type, const char *range, /* TODO: Support other ranges too. */ invalid = req.range != REQ_RANGE_LOCAL; break; + case VUT_COUNTER: + invalid = req.range != REQ_RANGE_CITY; + break; case VUT_IMPROVEMENT: /* Valid ranges depend on the building genus (wonder/improvement), * which might not have been loaded from the ruleset yet. @@ -1007,6 +1023,7 @@ struct requirement req_from_str(const char *type, const char *range, case VUT_ADVANCE: invalid = survives && req.range != REQ_RANGE_WORLD; break; + case VUT_COUNTER: case VUT_IMPR_GENUS: case VUT_GOVERNMENT: case VUT_TERRAIN: @@ -3287,6 +3304,18 @@ bool is_req_active(const struct req_context *context, eval = is_techflag_in_range(context->player, req->range, req->source.value.techflag); break; + case VUT_COUNTER: + if (NULL == context || NULL == context->city) { + return TRI_MAYBE; + } else { + struct counter *count = req->source.value.counter; + + eval = + BOOL_TO_TRISTATE(count->checkpoint <= + context->city->counter_values[ + counter_index(count)]); + } + break; case VUT_GOVERNMENT: /* The requirement is filled if the player is using the government. */ if (context->player == NULL) { @@ -3708,6 +3737,7 @@ bool is_req_unchanging(const struct requirement *req) case VUT_NATIONGROUP: return (req->range != REQ_RANGE_ALLIANCE); case VUT_ADVANCE: + case VUT_COUNTER: case VUT_TECHFLAG: case VUT_GOVERNMENT: case VUT_ACHIEVEMENT: @@ -3817,6 +3847,7 @@ bool universal_never_there(const struct universal *source) * MAP_MAX_LATITUDE. Otherwise, everything is MAP_MAX_LATITUDE / 2. */ return (wld.map.alltemperate && source->value.latitude > (MAP_MAX_LATITUDE / 2)); + case VUT_COUNTER: case VUT_OTYPE: case VUT_SPECIALIST: case VUT_AI_LEVEL: @@ -4381,6 +4412,8 @@ bool are_universals_equal(const struct universal *psource1, switch (psource1->kind) { case VUT_NONE: return TRUE; + case VUT_COUNTER: + return psource1->value.counter == psource2->value.counter; case VUT_ADVANCE: return psource1->value.advance == psource2->value.advance; case VUT_TECHFLAG: @@ -4495,6 +4528,8 @@ const char *universal_rule_name(const struct universal *psource) switch (psource->kind) { case VUT_NONE: return "(none)"; + case VUT_COUNTER: + return counter_rule_name(psource->value.counter); case VUT_CITYTILE: return citytile_type_name(psource->value.citytile); case VUT_CITYSTATUS: @@ -4641,6 +4676,9 @@ const char *universal_name_translation(const struct universal *psource, case VUT_ADVANCE: fc_strlcat(buf, advance_name_translation(psource->value.advance), bufsz); return buf; + case VUT_COUNTER: + fc_strlcat(buf, counter_name_translation(psource->value.counter), bufsz); + return buf; case VUT_TECHFLAG: cat_snprintf(buf, bufsz, _("\"%s\" tech"), tech_flag_id_translated_name(psource->value.techflag)); diff --git a/doc/README.effects b/doc/README.effects index 8bc9472461..b1803f237d 100644 --- a/doc/README.effects +++ b/doc/README.effects @@ -54,6 +54,7 @@ Tech: World, Alliance, Team, Player TechFlag: World, Alliance, Team, Player MinTechs: World, Player Achievement: World, Alliance, Team, Player +Counter: City Gov: Player Building: World, Alliance, Team, Player, Continent, Traderoute, City, Local BuildingGenus: Local diff --git a/server/cityturn.c b/server/cityturn.c index a17e0f7fa8..40a530e75e 100644 --- a/server/cityturn.c +++ b/server/cityturn.c @@ -38,6 +38,7 @@ #include "calendar.h" #include "citizens.h" #include "city.h" +#include "counters.h" #include "culture.h" #include "events.h" #include "disaster.h" @@ -1164,6 +1165,21 @@ static bool worklist_item_postpone_req_vec(struct universal *target, if (!is_req_active(&city_ctxt, NULL, preq, RPT_POSSIBLE)) { known = TRUE; switch (preq->source.kind) { + case VUT_COUNTER: + if (preq->present) { + notify_player(pplayer, city_tile(pcity), + E_CITY_CANTBUILD, ftc_server, + _("%s can't build %s from the worklist; " + "counter %s value's checkpoint do not met " + "Postponing..."), + city_link(pcity), + tgt_name, + counter_name_translation + (preq->source.value.counter)); + } else { + purge = TRUE; + } + break; case VUT_ADVANCE: if (preq->present) { notify_player(pplayer, city_tile(pcity), diff --git a/server/rssanity.c b/server/rssanity.c index 8640b1b0e4..7e19fc9711 100644 --- a/server/rssanity.c +++ b/server/rssanity.c @@ -365,6 +365,9 @@ static bool sanity_check_req_set(int reqs_of_type[], } break; + case VUT_COUNTER: + /* Can have multiple, since many counters (also of the same range) + * can met checkpoint */ case VUT_SERVERSETTING: /* Can have multiple, since there are many settings. */ case VUT_TOPO: diff --git a/tools/ruledit/univ_value.c b/tools/ruledit/univ_value.c index cb18f04b9a..9b23557ae8 100644 --- a/tools/ruledit/univ_value.c +++ b/tools/ruledit/univ_value.c @@ -17,6 +17,7 @@ /* common */ #include "achievements.h" +#include "counters.h" #include "game.h" #include "government.h" #include "requirements.h" @@ -49,6 +50,12 @@ bool universal_value_initial(struct universal *src) } src->value.advance = advance_by_number(A_NONE); return TRUE; + case VUT_COUNTER: + if (counters_get_city_counters_count() <= 0) { + return FALSE; + } + src->value.counter = counter_by_index(0, CTGT_CITY); + return TRUE; case VUT_GOVERNMENT: src->value.govern = game.government_during_revolution; return TRUE; @@ -243,6 +250,11 @@ void universal_kind_values(struct universal *univ, cb(advance_rule_name(padv), univ->value.advance == padv, data); } advance_re_active_iterate_end; break; + case VUT_COUNTER: + city_counters_iterate(pcount) { + cb(counter_rule_name(pcount), univ->value.counter == pcount, data); + } city_counters_iterate_end; + break; case VUT_GOVERNMENT: governments_re_active_iterate(pgov) { cb(government_rule_name(pgov), univ->value.govern == pgov, data); -- 2.35.1