From 7690d315f615eb774b6a06752fe3286d0355fea3 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-=20=20I?= =?UTF-8?q?ntroduce=20checkpoint=20value=20and=20counter=20req=20type=20-?= =?UTF-8?q?=20=20Document=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 3a140e6510..8e1c95b832 100644 --- a/ai/default/daieffects.c +++ b/ai/default/daieffects.c @@ -809,6 +809,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 6688703df2..a63adee69f 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 62fd8e6ab7..46729ab926 100644 --- a/common/counters.h +++ b/common/counters.h @@ -33,6 +33,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 8f3285a256..6354b7b912 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; @@ -762,6 +763,8 @@ typedef union { #define SPECENUM_VALUE47NAME "DiplRelUnitAny" #define SPECENUM_VALUE48 VUT_DIPLREL_UNITANY_O #define SPECENUM_VALUE48NAME "DiplRelUnitAnyOther" +#define SPECENUM_VALUE49 VUT_COUNTER +#define SPECENUM_VALUE49NAME "Counter" /* Keep this last. */ #define SPECENUM_COUNT VUT_COUNT #include "specenum_gen.h" diff --git a/common/reqtext.c b/common/reqtext.c index a9ff2b9994..ca528aefaa 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,25 @@ 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 0329815e57..cb7aa372e2 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" @@ -378,6 +379,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; } @@ -579,6 +586,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_COUNT: break; } @@ -702,6 +712,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_COUNT: break; } @@ -803,6 +815,7 @@ struct requirement req_from_str(const char *type, const char *range, case VUT_MAXTILEUNITS: req.range = REQ_RANGE_TILE; break; + case VUT_COUNTER: case VUT_MINSIZE: case VUT_MINCULTURE: case VUT_MINFOREIGNPCT: @@ -966,6 +979,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. @@ -993,6 +1009,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: @@ -3252,6 +3269,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) { @@ -3664,6 +3693,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: @@ -3768,6 +3798,7 @@ bool universal_never_there(const struct universal *source) return !uclass_flag_is_in_use(source->value.unitclassflag); case VUT_EXTRAFLAG: return !extra_flag_is_in_use(source->value.extraflag); + case VUT_COUNTER: case VUT_OTYPE: case VUT_SPECIALIST: case VUT_AI_LEVEL: @@ -4332,6 +4363,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: @@ -4444,6 +4477,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: @@ -4586,6 +4621,8 @@ 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); 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 174a43bad8..1a98a24c0d 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 3a679b39d1..0f6935e065 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,22 @@ 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 { + /* While techs can be unlearned, this isn't useful feedback */ + 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 2969c34548..bd03ea5b07 100644 --- a/server/rssanity.c +++ b/server/rssanity.c @@ -364,6 +364,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: -- 2.35.1