From 4a8152d4d63bfbd6f5a9e0bdbbda2e776c5aa89e Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Wed, 5 Jun 2024 16:59:36 +0300 Subject: [PATCH 07/53] 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/reqtext.c | 75 ++++++++++++++++++---------- common/requirements.c | 56 +++++++++++++++++---- doc/README.effects | 4 ++ gen_headers/enums/fc_types_enums.def | 1 + server/cityturn.c | 1 + server/ruleset/rssanity.c | 2 + tools/ruledit/univ_value.c | 2 + 9 files changed, 113 insertions(+), 40 deletions(-) diff --git a/ai/default/daieffects.c b/ai/default/daieffects.c index 9dcfbfdff6..4e86a218fc 100644 --- a/ai/default/daieffects.c +++ b/ai/default/daieffects.c @@ -818,15 +818,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 2cb0782fd2..63e074a0b9 100644 --- a/ai/default/daimilitary.c +++ b/ai/default/daimilitary.c @@ -366,6 +366,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/reqtext.c b/common/reqtext.c index d6af4e9cac..4d84ba0575 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 a9b58eb778..80b4d50ba4 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; @@ -683,6 +686,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; @@ -921,6 +925,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; @@ -1105,6 +1110,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: @@ -1373,6 +1379,7 @@ struct requirement req_from_str(const char *type, const char *range, && req.range == REQ_RANGE_TILE); 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 @@ -1392,6 +1399,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; @@ -1559,7 +1567,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 @@ -1591,7 +1600,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 @@ -1782,6 +1792,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) { @@ -1798,14 +1809,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); } @@ -1914,9 +1927,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) { @@ -2239,13 +2253,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; } @@ -6182,6 +6199,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}, @@ -6633,7 +6651,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))) @@ -6723,6 +6741,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: @@ -7321,6 +7340,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; @@ -7479,6 +7499,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); @@ -7645,6 +7666,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), @@ -8003,6 +8034,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); @@ -8256,6 +8288,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; } @@ -8548,6 +8581,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 8606a4af24..7fa8b4a9c1 100644 --- a/doc/README.effects +++ b/doc/README.effects @@ -68,6 +68,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 @@ -123,6 +125,8 @@ MaxDistanceSq: Tile MaxRegionTiles: Continent, Adjacent, CAdjacent +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/gen_headers/enums/fc_types_enums.def b/gen_headers/enums/fc_types_enums.def index d97dfb96b3..473737c034 100644 --- a/gen_headers/enums/fc_types_enums.def +++ b/gen_headers/enums/fc_types_enums.def @@ -88,6 +88,7 @@ values PLAYER_STATE "PlayerState" ROADFLAG "RoadFlag" SERVERSETTING "ServerSetting" + SITE "Site" SPECIALIST "Specialist" STYLE "Style" TECHFLAG "TechFlag" diff --git a/server/cityturn.c b/server/cityturn.c index f4cc7ed048..641216115c 100644 --- a/server/cityturn.c +++ b/server/cityturn.c @@ -1261,6 +1261,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/ruleset/rssanity.c b/server/ruleset/rssanity.c index ace3cd9bb1..7e9651132c 100644 --- a/server/ruleset/rssanity.c +++ b/server/ruleset/rssanity.c @@ -173,6 +173,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. */ @@ -430,6 +431,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 c2d164765c..d158d3fa36 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; } @@ -296,6 +297,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