From d1ce74374e724631c913338fa124cf98641eabe9 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] - Introduce checkpoint value and counter req type diff --git a/ai/default/daieffects.c b/ai/default/daieffects.c index 3a140e6510..2ee8fc230a 100644 --- a/ai/default/daieffects.c +++ b/ai/default/daieffects.c @@ -716,6 +716,8 @@ bool dai_can_requirement_be_met_in_city(const struct requirement *preq, const struct city *pcity) { switch (preq->source.kind) { + case VUT_COUNTER: + return FALSE; case VUT_GOVERNMENT: /* We can't meet a government requirement if we have a better one. */ return !have_better_government(pplayer, preq->source.value.govern); 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..aeda3d68b9 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,13 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, case VUT_NONE: return FALSE; + case VUT_COUNTER: + fc_strlcat(buf, prefix, bufsz); + cat_snprintf(buf, bufsz, + _("Requires %s achieve an %d value"), + counter_rule_name(preq->source.value.counter), + preq->source.value.counter->checkpoint); + break; case VUT_ADVANCE: switch (preq->range) { case REQ_RANGE_PLAYER: diff --git a/common/requirements.c b/common/requirements.c index 0329815e57..87d1bc0c0b 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_index(source->value.counter); case VUT_COUNT: break; } @@ -966,6 +978,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 +1008,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 +3268,22 @@ 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: + { + struct counter *count = req->source.value.counter; + + if (NULL == context || NULL == context->city) { + + return TRI_MAYBE; + } + else { + + eval = + (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 +3696,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 +3801,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 +4366,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 +4480,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 +4624,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_rule_name(psource->value.counter), bufsz); case VUT_TECHFLAG: cat_snprintf(buf, bufsz, _("\"%s\" tech"), tech_flag_id_translated_name(psource->value.techflag)); diff --git a/server/cityturn.c b/server/cityturn.c index 3a679b39d1..920506f314 100644 --- a/server/cityturn.c +++ b/server/cityturn.c @@ -1164,6 +1164,8 @@ 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: + 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..645cc7bdd3 100644 --- a/server/rssanity.c +++ b/server/rssanity.c @@ -363,7 +363,9 @@ static bool sanity_check_req_set(int reqs_of_type[], return FALSE; } 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