From 269d472a2ef375f10dce5745d7214298ca4d1068 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Mon, 13 May 2024 02:28:32 +0300 Subject: [PATCH 69/69] Add requirement type "Site" It's like Buinding, except that the requirement is fulfilled even after the building has obsoleted. Original request for obsoleteion avoidance by Lexxie Solution idea bu ihnatus See osdn #42905 Signed-off-by: Marko Lindqvist --- ai/default/daieffects.c | 11 ++++-- ai/default/daimilitary.c | 1 + common/fc_types.h | 4 +- common/reqtext.c | 75 +++++++++++++++++++++++++------------- common/requirements.c | 56 ++++++++++++++++++++++------ doc/README.effects | 4 ++ server/cityturn.c | 1 + server/rssanity.c | 2 + tools/ruledit/univ_value.c | 2 + 9 files changed, 115 insertions(+), 41 deletions(-) diff --git a/ai/default/daieffects.c b/ai/default/daieffects.c index acd32b3f88..f68cda87b2 100644 --- a/ai/default/daieffects.c +++ b/ai/default/daieffects.c @@ -788,15 +788,20 @@ bool dai_can_requirement_be_met_in_city(const struct requirement *preq, /* We can't meet a government requirement if we have a better one. */ return !have_better_government(pplayer, preq->source.value.govern); - case VUT_IMPROVEMENT: { + case VUT_IMPROVEMENT: + case VUT_SITE: + { const struct impr_type *pimprove = preq->source.value.building; - if (preq->present && improvement_obsolete(pplayer, pimprove, pcity)) { + if (preq->present + && preq->source.kind == VUT_IMPROVEMENT + && improvement_obsolete(pplayer, pimprove, pcity)) { /* Would need to unobsolete a building, which is too hard. */ return FALSE; } else if (!preq->present && pcity != NULL && I_NEVER < pcity->built[improvement_index(pimprove)].turn - && !can_improvement_go_obsolete(pimprove)) { + && (preq->source.kind != VUT_IMPROVEMENT + || !can_improvement_go_obsolete(pimprove))) { /* Would need to unbuild an unobsoleteable building, which is too hard. */ return FALSE; } else if (preq->present) { diff --git a/ai/default/daimilitary.c b/ai/default/daimilitary.c index 0254f55edb..7ffeb2c82a 100644 --- a/ai/default/daimilitary.c +++ b/ai/default/daimilitary.c @@ -367,6 +367,7 @@ tactical_req_cb(const struct req_context *context, { switch (req->source.kind) { case VUT_IMPROVEMENT: + case VUT_SITE: { const struct impr_type *b = req->source.value.building; diff --git a/common/fc_types.h b/common/fc_types.h index 64ee83b126..3b4eff5409 100644 --- a/common/fc_types.h +++ b/common/fc_types.h @@ -894,6 +894,8 @@ typedef union { #define SPECENUM_VALUE56NAME "PlayerState" #define SPECENUM_VALUE57 VUT_FORM_AGE #define SPECENUM_VALUE57NAME "FormAge" +#define SPECENUM_VALUE58 VUT_SITE +#define SPECENUM_VALUE58NAME "Site" /* Keep this last. */ #define SPECENUM_COUNT VUT_COUNT @@ -902,7 +904,7 @@ typedef union { /* Used in the network protocol. */ struct universal { universals_u value; - enum universals_n kind; /* formerly .type and .is_unit */ + enum universals_n kind; /* Formerly .type and .is_unit */ }; /* Used in the network protocol. */ diff --git a/common/reqtext.c b/common/reqtext.c index b86b2d1835..bdf306d340 100644 --- a/common/reqtext.c +++ b/common/reqtext.c @@ -410,13 +410,15 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, break; case VUT_IMPROVEMENT: + case VUT_SITE: switch (preq->range) { case REQ_RANGE_WORLD: if (is_great_wonder(preq->source.value.building)) { fc_strlcat(buf, prefix, bufsz); if (preq->survives) { if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Requires that %s was built at some point, " @@ -432,7 +434,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Prevented if %s has ever been built, " @@ -450,7 +453,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, } else { /* Non-surviving requirement */ if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Requires %s to be owned by any player " @@ -465,7 +469,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Prevented if %s is currently owned by " @@ -484,14 +489,15 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, } return TRUE; } - /* non-great-wonder world-ranged requirements not supported */ + /* Non-great-wonder world-ranged requirements not supported */ break; case REQ_RANGE_ALLIANCE: if (is_wonder(preq->source.value.building)) { fc_strlcat(buf, prefix, bufsz); if (preq->survives) { if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Requires someone who is currently allied to " @@ -508,7 +514,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Prevented if someone currently allied to you " @@ -528,7 +535,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, } else { /* Non-surviving requirement */ if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Requires someone allied to you to own %s, " @@ -544,7 +552,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Prevented if someone allied to you owns %s, " @@ -562,14 +571,15 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, } return TRUE; } - /* non-wonder alliance-ranged requirements not supported */ + /* Non-wonder alliance-ranged requirements not supported */ break; case REQ_RANGE_TEAM: if (is_wonder(preq->source.value.building)) { fc_strlcat(buf, prefix, bufsz); if (preq->survives) { if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Requires someone on your team to have " @@ -586,7 +596,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Prevented if someone on your team has ever " @@ -605,7 +616,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, } else { /* Non-surviving requirement */ if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Requires someone on your team to own %s, " @@ -621,7 +633,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Prevented if someone on your team owns %s, " @@ -639,14 +652,15 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, } return TRUE; } - /* non-wonder team-ranged requirements not supported */ + /* Non-wonder team-ranged requirements not supported */ break; case REQ_RANGE_PLAYER: if (is_wonder(preq->source.value.building)) { fc_strlcat(buf, prefix, bufsz); if (preq->survives) { if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Requires you to have built %s at some point, " @@ -662,7 +676,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Prevented if you have ever built %s, " @@ -680,7 +695,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, } else { /* Non-surviving requirement */ if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Requires you to own %s, which must not " @@ -695,7 +711,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Prevented if you own %s, unless it is " @@ -713,13 +730,14 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, } return TRUE; } - /* non-wonder player-ranged requirements not supported */ + /* Non-wonder player-ranged requirements not supported */ break; case REQ_RANGE_CONTINENT: if (is_wonder(preq->source.value.building)) { fc_strlcat(buf, prefix, bufsz); if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Requires %s in one of your cities on the same " @@ -735,7 +753,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { cat_snprintf(buf, bufsz, /* TRANS: %s is a wonder */ _("Prevented if %s is in one of your cities on the " @@ -758,7 +777,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, case REQ_RANGE_TRADE_ROUTE: fc_strlcat(buf, prefix, bufsz); if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { /* Should only apply to wonders */ cat_snprintf(buf, bufsz, /* TRANS: %s is a building or wonder */ @@ -774,7 +794,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { /* Should only apply to wonders */ cat_snprintf(buf, bufsz, /* TRANS: %s is a building or wonder */ @@ -794,7 +815,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, case REQ_RANGE_CITY: fc_strlcat(buf, prefix, bufsz); if (preq->present) { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { /* Should only apply to wonders */ cat_snprintf(buf, bufsz, /* TRANS: %s is a building or wonder */ @@ -809,7 +831,8 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, (preq->source.value.building)); } } else { - if (can_improvement_go_obsolete(preq->source.value.building)) { + if (preq->source.kind == VUT_IMPROVEMENT + && can_improvement_go_obsolete(preq->source.value.building)) { /* Should only apply to wonders */ cat_snprintf(buf, bufsz, /* TRANS: %s is a building or wonder */ diff --git a/common/requirements.c b/common/requirements.c index 311fbc676e..b41a9dc0aa 100644 --- a/common/requirements.c +++ b/common/requirements.c @@ -195,13 +195,15 @@ static enum req_unchanging_status { const struct impr_type *b = req->source.value.building; - fc_assert_ret_val(VUT_IMPROVEMENT == req->source.kind, REQUCH_NO); + fc_assert_ret_val(VUT_IMPROVEMENT == req->source.kind + || VUT_SITE == req->source.kind, REQUCH_NO); if (REQ_RANGE_LOCAL == req->range) { /* Likely, won't be questioned for an obsolete building */ return REQUCH_YES; } - if (improvement_obsolete(context->player, b, context->city)) { + if (req->source.kind == VUT_IMPROVEMENT + && improvement_obsolete(context->player, b, context->city)) { /* FIXME: sometimes can unobsolete, but considering it * may sometimes put the function on endless recursion */ return REQUCH_ACT; /* Mostly about techs */ @@ -315,6 +317,7 @@ void universal_value_from_str(struct universal *source, const char *value) } break; case VUT_IMPROVEMENT: + case VUT_SITE: source->value.building = improvement_by_rule_name(value); if (source->value.building != NULL) { return; @@ -659,6 +662,7 @@ struct universal universal_by_number(const enum universals_n kind, } break; case VUT_IMPROVEMENT: + case VUT_SITE: source.value.building = improvement_by_number(value); if (source.value.building != NULL) { return source; @@ -885,6 +889,7 @@ int universal_number(const struct universal *source) case VUT_STYLE: return style_number(source->value.style); case VUT_IMPROVEMENT: + case VUT_SITE: return improvement_number(source->value.building); case VUT_IMPR_GENUS: return source->value.impr_genus; @@ -1061,6 +1066,7 @@ struct requirement req_from_str(const char *type, const char *range, case VUT_COUNT: break; case VUT_IMPROVEMENT: + case VUT_SITE: case VUT_IMPR_GENUS: case VUT_IMPR_FLAG: case VUT_UTYPE: @@ -1294,6 +1300,7 @@ struct requirement req_from_str(const char *type, const char *range, invalid = (req.range != REQ_RANGE_PLAYER); break; case VUT_IMPROVEMENT: + case VUT_SITE: /* Valid ranges depend on the building genus (wonder/improvement), * which might not have been loaded from the ruleset yet. * So we allow anything here, and do a proper check once ruleset @@ -1313,6 +1320,7 @@ struct requirement req_from_str(const char *type, const char *range, /* Check 'survives'. */ switch (req.source.kind) { case VUT_IMPROVEMENT: + case VUT_SITE: /* See buildings_in_range(). */ invalid = survives && req.range <= REQ_RANGE_CONTINENT; break; @@ -1476,7 +1484,8 @@ static bool impr_contra_genus(const struct requirement *impr_req, const struct requirement *genus_req) { /* The input is sane. */ - fc_assert_ret_val(impr_req->source.kind == VUT_IMPROVEMENT, FALSE); + fc_assert_ret_val(impr_req->source.kind == VUT_IMPROVEMENT + || impr_req->source.kind == VUT_SITE, FALSE); fc_assert_ret_val(genus_req->source.kind == VUT_IMPR_GENUS, FALSE); if (impr_req->range == REQ_RANGE_LOCAL @@ -1508,7 +1517,8 @@ static bool impr_contra_flag(const struct requirement *impr_req, const struct requirement *flag_req) { /* The input is sane. */ - fc_assert_ret_val(impr_req->source.kind == VUT_IMPROVEMENT, FALSE); + fc_assert_ret_val(impr_req->source.kind == VUT_IMPROVEMENT + || impr_req->source.kind == VUT_SITE, FALSE); fc_assert_ret_val(flag_req->source.kind == VUT_IMPR_FLAG, FALSE); if (impr_req->range == REQ_RANGE_LOCAL @@ -1677,6 +1687,7 @@ bool are_requirements_contradictions(const struct requirement *req1, switch (req1->source.kind) { case VUT_IMPROVEMENT: + case VUT_SITE: if (req2->source.kind == VUT_IMPR_GENUS) { return impr_contra_genus(req1, req2); } else if (req2->source.kind == VUT_IMPR_FLAG) { @@ -1693,14 +1704,16 @@ bool are_requirements_contradictions(const struct requirement *req1, /* No special knowledge. */ return FALSE; case VUT_IMPR_GENUS: - if (req2->source.kind == VUT_IMPROVEMENT) { + if (req2->source.kind == VUT_IMPROVEMENT + || req2->source.kind == VUT_SITE) { return impr_contra_genus(req2, req1); } /* No special knowledge. */ return FALSE; case VUT_IMPR_FLAG: - if (req2->source.kind == VUT_IMPROVEMENT) { + if (req2->source.kind == VUT_IMPROVEMENT + || req2->source.kind == VUT_SITE) { return impr_contra_flag(req2, req1); } @@ -1820,9 +1833,10 @@ bool are_requirements_contradictions(const struct requirement *req1, case VUT_CITYTILE: if (req2->source.kind == VUT_CITYTILE) { return city_center_contra(req1, req2) - || city_center_contra(req2, req1); + || city_center_contra(req2, req1); } else if (req1->source.value.citytile == CITYT_CENTER - && req2->source.kind == VUT_IMPROVEMENT + && (req2->source.kind == VUT_IMPROVEMENT + || req2->source.kind == VUT_SITE) && REQ_RANGE_TILE == req2->range && REQ_RANGE_TILE == req1->range && req2->present) { @@ -2055,13 +2069,16 @@ is_building_req_active(const struct civ_map *nmap, { const struct impr_type *building; - IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_IMPROVEMENT); + /* Can't use this assertion, as both VUT_IMPROVEMENT and VUT_SITE + * are handled here. */ + /* IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_IMPROVEMENT); */ building = req->source.value.building; /* Check if it's certain that the building is obsolete given the * specification we have */ - if (improvement_obsolete(context->player, building, context->city)) { + if (req->source.kind == VUT_IMPROVEMENT + && improvement_obsolete(context->player, building, context->city)) { return TRI_NO; } @@ -5362,6 +5379,7 @@ static struct req_def req_definitions[VUT_COUNT] = { [VUT_GOOD] = {is_good_req_active, REQUCH_NO}, [VUT_GOVERNMENT] = {is_gov_req_active, REQUCH_NO}, [VUT_IMPROVEMENT] = {is_building_req_active, REQUCH_NO, REQUC_IMPR}, + [VUT_SITE] = {is_building_req_active, REQUCH_NO, REQUC_IMPR}, [VUT_IMPR_GENUS] = {is_buildinggenus_req_active, REQUCH_YES}, [VUT_IMPR_FLAG] = {is_buildingflag_req_active, REQUCH_YES}, [VUT_PLAYER_FLAG] = {is_plr_flag_req_active, REQUCH_NO}, @@ -5801,7 +5819,7 @@ enum req_unchanging_status enum req_unchanging_status u = is_req_unchanging(context, req); if (REQUCH_NO != u) { - /* presence is precalculated */ + /* Presence is precalculated */ bool auto_present = (req->survives && !(VUT_IMPROVEMENT == req->source.kind && can_improvement_go_obsolete(req->source.value.building))) @@ -5891,6 +5909,7 @@ bool universal_never_there(const struct universal *source) case VUT_GOVERNMENT: case VUT_ACHIEVEMENT: case VUT_IMPROVEMENT: + case VUT_SITE: case VUT_IMPR_GENUS: case VUT_IMPR_FLAG: case VUT_PLAYER_FLAG: @@ -6485,6 +6504,7 @@ bool are_universals_equal(const struct universal *psource1, case VUT_STYLE: return psource1->value.style == psource2->value.style; case VUT_IMPROVEMENT: + case VUT_SITE: return psource1->value.building == psource2->value.building; case VUT_IMPR_GENUS: return psource1->value.impr_genus == psource2->value.impr_genus; @@ -6633,6 +6653,7 @@ const char *universal_rule_name(const struct universal *psource) case VUT_STYLE: return style_rule_name(psource->value.style); case VUT_IMPROVEMENT: + case VUT_SITE: return improvement_rule_name(psource->value.building); case VUT_IMPR_GENUS: return impr_genus_id_name(psource->value.impr_genus); @@ -6787,6 +6808,16 @@ const char *universal_name_translation(const struct universal *psource, fc_strlcat(buf, improvement_name_translation(psource->value.building), bufsz); return buf; + case VUT_SITE: + { + char local_buf[1024]; + + fc_snprintf(local_buf, sizeof(local_buf), _("%s site"), + improvement_name_translation(psource->value.building)); + fc_strlcat(buf, local_buf, bufsz); + } + + return buf; case VUT_IMPR_GENUS: fc_strlcat(buf, impr_genus_id_translated_name(psource->value.impr_genus), @@ -7112,6 +7143,7 @@ int universal_build_shield_cost(const struct city *pcity, { switch (target->kind) { case VUT_IMPROVEMENT: + case VUT_SITE: return impr_build_shield_cost(pcity, target->value.building); case VUT_UTYPE: return utype_build_shield_cost(pcity, NULL, target->value.utype); @@ -7365,6 +7397,7 @@ static enum req_item_found improvement_found(const struct requirement *preq, switch (preq->source.kind) { case VUT_IMPROVEMENT: + case VUT_SITE: if (source->value.building == preq->source.value.building) { return ITF_YES; } @@ -7657,6 +7690,7 @@ void universal_found_functions_init(void) universal_found_function[VUT_GOVERNMENT] = &government_found; universal_found_function[VUT_NATION] = &nation_found; universal_found_function[VUT_IMPROVEMENT] = &improvement_found; + universal_found_function[VUT_SITE] = &improvement_found; universal_found_function[VUT_UCLASS] = &unit_class_found; universal_found_function[VUT_UTYPE] = &unit_type_found; universal_found_function[VUT_ACTIVITY] = &unit_activity_found; diff --git a/doc/README.effects b/doc/README.effects index f003922eb9..276b2e14cc 100644 --- a/doc/README.effects +++ b/doc/README.effects @@ -65,6 +65,8 @@ Building: World, Alliance, Team, Player, Continent, Traderoute, City, Tile, Local BuildingFlag: Local, Tile, City BuildingGenus: Local +Site: World, Alliance, Team, Player, Continent, Traderoute, City, + Tile, Local Extra: Local, Tile, Adjacent, CAdjacent, Traderoute, City RoadFlag: Local, Tile, Adjacent, CAdjacent, Traderoute, City ExtraFlag: Local, Tile, Adjacent, CAdjacent, Traderoute, City @@ -117,6 +119,8 @@ MinVeteran: Local MinHitPoints: Local +Site is like Building, except that the requirement is fulfilled even after + the building is obsoleted. MinSize is the minimum size of a city required. AI is ai player difficulty level. TerrainClass is either "Land" or "Oceanic". diff --git a/server/cityturn.c b/server/cityturn.c index 849d5bff1a..5b1fff272f 100644 --- a/server/cityturn.c +++ b/server/cityturn.c @@ -1262,6 +1262,7 @@ static bool worklist_item_postpone_req_vec(struct universal *target, } break; case VUT_IMPROVEMENT: + case VUT_SITE: if (preq->range == REQ_RANGE_LOCAL) { /* Building itself is never going to change */ purge = TRUE; diff --git a/server/rssanity.c b/server/rssanity.c index aceef4dc09..0d4b388a13 100644 --- a/server/rssanity.c +++ b/server/rssanity.c @@ -172,6 +172,7 @@ static bool sanity_check_req_individual(rs_conversion_logger logger, { switch (preq->source.kind) { case VUT_IMPROVEMENT: + case VUT_SITE: /* This check corresponds to what is_req_active() will support. * It can't be done in req_from_str(), as we may not have * loaded all building information at that time. */ @@ -429,6 +430,7 @@ static bool sanity_check_req_set(rs_conversion_logger logger, case VUT_ADVANCE: case VUT_TECHFLAG: case VUT_IMPROVEMENT: + case VUT_SITE: case VUT_UNITSTATE: case VUT_CITYTILE: case VUT_GOOD: diff --git a/tools/ruledit/univ_value.c b/tools/ruledit/univ_value.c index cf1e6d9f01..2ab348f63a 100644 --- a/tools/ruledit/univ_value.c +++ b/tools/ruledit/univ_value.c @@ -61,6 +61,7 @@ bool universal_value_initial(struct universal *src) src->value.govern = game.government_during_revolution; return TRUE; case VUT_IMPROVEMENT: + case VUT_SITE: if (game.control.num_impr_types <= 0) { return FALSE; } @@ -284,6 +285,7 @@ void universal_kind_values(struct universal *univ, } governments_re_active_iterate_end; break; case VUT_IMPROVEMENT: + case VUT_SITE: improvement_re_active_iterate(pimpr) { cb(improvement_rule_name(pimpr), univ->value.building == pimpr, data); } improvement_re_active_iterate_end; -- 2.43.0