From 0c7623e3cd3cc0925f6f35f38d8fb7259b91257a Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Tue, 30 May 2023 23:36:51 +0300 Subject: [PATCH 31/31] Add support for CityStatus value "Transferred" See osdn #48115 Signed-off-by: Marko Lindqvist --- ai/default/daieffects.c | 6 +++++ ai/default/daimilitary.c | 3 ++- common/fc_types.h | 2 ++ common/reqtext.c | 3 +++ common/requirements.c | 54 +++++++++++++++++++++++++++++++++++++--- doc/README.effects | 5 +++- server/cityturn.c | 5 +++- 7 files changed, 72 insertions(+), 6 deletions(-) diff --git a/ai/default/daieffects.c b/ai/default/daieffects.c index 886276fe56..5579f5b271 100644 --- a/ai/default/daieffects.c +++ b/ai/default/daieffects.c @@ -821,6 +821,12 @@ bool dai_can_requirement_be_met_in_city(const struct requirement *preq, } else { return city_owner(pcity) != pcity->original; } + } else if (preq->source.value.citystatus == CITYS_TRANSFERRED) { + if ((preq->present && pcity->acquire_t == CACQ_FOUNDED) + || (!preq->present && pcity->acquire_t != CACQ_FOUNDED)) { + /* Would change only when the AI loses the city */ + return FALSE; + } } } break; diff --git a/ai/default/daimilitary.c b/ai/default/daimilitary.c index c9af011198..49b3f2055e 100644 --- a/ai/default/daimilitary.c +++ b/ai/default/daimilitary.c @@ -415,7 +415,8 @@ tactical_req_cb(const struct req_context *context, return tri_req_active_turns(n_data, 5 /* WAG */, context, other_player, req); case VUT_CITYSTATUS: - if (CITYS_OWNED_BY_ORIGINAL != req->source.value.citystatus) { + if (CITYS_OWNED_BY_ORIGINAL != req->source.value.citystatus + && CITYS_TRANSFERRED != req->source.value.citystatus) { return TRI_MAYBE; } fc__fallthrough; diff --git a/common/fc_types.h b/common/fc_types.h index 34332e10a4..31d71745d3 100644 --- a/common/fc_types.h +++ b/common/fc_types.h @@ -573,6 +573,8 @@ const char *ai_level_name_update_cb(const char *old); #define SPECENUM_VALUE2NAME "Disorder" #define SPECENUM_VALUE3 CITYS_CELEBRATION #define SPECENUM_VALUE3NAME "Celebration" +#define SPECENUM_VALUE4 CITYS_TRANSFERRED +#define SPECENUM_VALUE4NAME "Transferred" #define SPECENUM_COUNT CITYS_LAST #include "specenum_gen.h" diff --git a/common/reqtext.c b/common/reqtext.c index c3631b3e99..77d90f72c4 100644 --- a/common/reqtext.c +++ b/common/reqtext.c @@ -3024,6 +3024,9 @@ bool req_text_insert(char *buf, size_t bufsz, struct player *pplayer, case CITYS_CELEBRATION: city_property = _("celebration"); break; + case CITYS_TRANSFERRED: + city_property = _("transferred"); + break; case CITYS_LAST: fc_assert(preq->source.value.citystatus != CITYS_LAST); break; diff --git a/common/requirements.c b/common/requirements.c index 5025b38b0d..695b65d668 100644 --- a/common/requirements.c +++ b/common/requirements.c @@ -156,7 +156,7 @@ static enum req_unchanging_status #define REQUC_CITYTILE unchanging_citytile /**********************************************************************//** - Special CityStatus case handler. Changes easily save for OwnedByOriginal + Special CityStatus case handler. Changes easily save for owner. **************************************************************************/ static enum req_unchanging_status unchanging_citystatus(enum req_unchanging_status def, @@ -164,10 +164,13 @@ static enum req_unchanging_status const struct requirement *req) { fc_assert_ret_val(VUT_CITYSTATUS == req->source.kind, REQUCH_NO); - if (CITYS_OWNED_BY_ORIGINAL == req->source.value.citystatus - && REQ_RANGE_CITY == req->range) { + + if (REQ_RANGE_CITY == req->range + && (CITYS_OWNED_BY_ORIGINAL == req->source.value.citystatus + || CITYS_TRANSFERRED == req->source.value.citystatus)) { return REQUCH_CTRL; } + return def; } #define REQUC_CITYSTATUS unchanging_citystatus @@ -4768,6 +4771,47 @@ is_citystatus_req_active(const struct req_context *context, return TRI_MAYBE; + case CITYS_TRANSFERRED: + switch (req->range) { + case REQ_RANGE_CITY: + return BOOL_TO_TRISTATE(context->city->acquire_t != CACQ_FOUNDED); + case REQ_RANGE_TRADEROUTE: + { + enum fc_tristate ret; + + if (context->city->acquire_t != CACQ_FOUNDED) { + return TRI_YES; + } + + ret = TRI_NO; + trade_partners_iterate(context->city, trade_partner) { + if (trade_partner == NULL) { + ret = TRI_MAYBE; + } else if (trade_partner->acquire_t != CACQ_FOUNDED) { + return TRI_YES; + } + } trade_partners_iterate_end; + + return ret; + } + case REQ_RANGE_LOCAL: + case REQ_RANGE_TILE: + case REQ_RANGE_CADJACENT: + case REQ_RANGE_ADJACENT: + case REQ_RANGE_CONTINENT: + case REQ_RANGE_PLAYER: + case REQ_RANGE_TEAM: + case REQ_RANGE_ALLIANCE: + case REQ_RANGE_WORLD: + case REQ_RANGE_COUNT: + break; + } + + fc_assert_msg(FALSE, "Invalid range %d for citystatus Transferred.", + req->range); + + return TRI_MAYBE; + case CITYS_LAST: break; } @@ -6753,6 +6797,10 @@ const char *universal_name_translation(const struct universal *psource, case CITYS_CELEBRATION: fc_strlcat(buf, _("Celebration"), bufsz); break; + case CITYS_TRANSFERRED: + /* TRANS: CityStatus value - city has changed hands */ + fc_strlcat(buf, _("Transferred"), bufsz); + break; case CITYS_LAST: fc_assert(psource->value.citystatus != CITYS_LAST); fc_strlcat(buf, "error", bufsz); diff --git a/doc/README.effects b/doc/README.effects index 2b943bd596..22e5bc2036 100644 --- a/doc/README.effects +++ b/doc/README.effects @@ -121,7 +121,10 @@ CityTile is "Center" (city center), "Claimed" (tile owned by any player), is a port, it's a tile of the nearby ocean but not of its continent). MinLatitude and MaxLatitude are numbers from -1000 (south pole) to 1000 (north pole). -CityStatus is "OwnedByOriginal", "Starved", "Disorder", or "Celebration" +CityStatus is "OwnedByOriginal", "Transferred", "Starved", + "Disorder", or "Celebration" + The difference between "OwnedByOriginal" and "Transferred" is that + former is fullfilled also for liberated cities. DiplRel is a diplomatic relationship. MaxUnitsOnTile is about the number of units present on a tile. UnitState is "Transported", "Transporting", "OnNativeTile", "OnLivableTile", diff --git a/server/cityturn.c b/server/cityturn.c index 0521456468..b9c3a31503 100644 --- a/server/cityturn.c +++ b/server/cityturn.c @@ -1882,7 +1882,10 @@ static bool worklist_item_postpone_req_vec(struct universal *target, log_error("worklist_change_build_target() has bogus preq"); break; case VUT_CITYSTATUS: - if (preq->source.value.citystatus == CITYS_OWNED_BY_ORIGINAL) { + if (preq->source.value.citystatus == CITYS_TRANSFERRED) { + /* If there's a change, it will invalidate worklist anyway. */ + purge = TRUE; + } else if (preq->source.value.citystatus == CITYS_OWNED_BY_ORIGINAL) { if (preq->range == REQ_RANGE_CITY || preq->range == REQ_RANGE_TILE) { /* Can't change at these ranges */ purge = TRUE; -- 2.39.2