From 71a2117e298a3023c8640f1ab281b771381f80ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awomir=20Lach?= Date: Thu, 31 Mar 2022 17:15:28 +0200 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 bce8c56d67..156582fddb 100644 --- a/ai/default/daieffects.c +++ b/ai/default/daieffects.c @@ -811,6 +811,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 1ac5624bab..d6eecdad5f 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; @@ -767,6 +768,9 @@ typedef union { #define SPECENUM_VALUE49NAME "MinLatitude" #define SPECENUM_VALUE50 VUT_MAXLATITUDE #define SPECENUM_VALUE50NAME "MaxLatitude" +#define SPECENUM_VALUE51 VUT_COUNTER +#define SPECENUM_VALUE51NAME "Counter" + /* Keep this last. */ #define SPECENUM_COUNT VUT_COUNT #include "specenum_gen.h" diff --git a/common/reqtext.c b/common/reqtext.c index 66beace99b..28f342c489 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 be less than %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 5f62badaa7..512eefe67b 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" @@ -386,6 +387,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; } @@ -587,6 +594,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: case VUT_MAXLATITUDE: source.value.latitude = value; @@ -714,6 +724,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: case VUT_MAXLATITUDE: return source->value.latitude; @@ -820,6 +832,7 @@ struct requirement req_from_str(const char *type, const char *range, case VUT_MAXLATITUDE: req.range = REQ_RANGE_TILE; break; + case VUT_COUNTER: case VUT_MINSIZE: case VUT_MINCULTURE: case VUT_MINFOREIGNPCT: @@ -994,6 +1007,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. @@ -1021,6 +1037,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: @@ -3416,6 +3433,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) { + eval = 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) { @@ -3836,6 +3865,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: @@ -3944,6 +3974,7 @@ bool universal_never_there(const struct universal *source) return source->value.latitude > MAP_MAX_REAL_LATITUDE(wld.map); case VUT_MAXLATITUDE: return source->value.latitude < MAP_MIN_REAL_LATITUDE(wld.map); + case VUT_COUNTER: case VUT_OTYPE: case VUT_SPECIALIST: case VUT_AI_LEVEL: @@ -4508,6 +4539,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: @@ -4623,6 +4656,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: @@ -4770,6 +4805,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 a45498fac6..ff02ba3c71 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 adbad7b099..51cb1032ad 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 1901e72e1b..08bcae0516 100644 --- a/server/rssanity.c +++ b/server/rssanity.c @@ -371,6 +371,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 d1771a8780..5bd9bd5477 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; @@ -244,6 +251,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