From c745a5c6b0221874f785ad07c219167ef8108128 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Tue, 2 Apr 2024 23:51:13 +0300 Subject: [PATCH 59/59] Add support for UnitClass requirements on Tile - Adjacent ranges Requested by alienvalkyrie See osdn #43704 Signed-off-by: Marko Lindqvist --- common/requirements.c | 64 ++++++++++++++++++++++++++++++++++----- doc/README.effects | 2 +- server/ruleset/rssanity.c | 2 +- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/common/requirements.c b/common/requirements.c index 898a2431a3..7746f536ca 100644 --- a/common/requirements.c +++ b/common/requirements.c @@ -1240,7 +1240,6 @@ struct requirement req_from_str(const char *type, const char *range, && req.range != REQ_RANGE_ALLIANCE && req.range != REQ_RANGE_WORLD); break; - case VUT_UCLASS: case VUT_UCFLAG: case VUT_MINVETERAN: case VUT_UNITSTATE: @@ -1254,6 +1253,7 @@ struct requirement req_from_str(const char *type, const char *range, break; case VUT_UTYPE: case VUT_UTFLAG: + case VUT_UCLASS: invalid = (req.range != REQ_RANGE_LOCAL && req.range != REQ_RANGE_TILE && req.range != REQ_RANGE_CADJACENT @@ -4234,14 +4234,64 @@ is_unitclass_req_active(const struct civ_map *nmap, pclass = req->source.value.uclass; - if (req->range != REQ_RANGE_LOCAL) { - return TRI_NO; - } - if (!context->unittype) { - return TRI_MAYBE; + switch (req->range) { + case REQ_RANGE_LOCAL: + if (!context->unittype) { + return TRI_MAYBE; + } + return BOOL_TO_TRISTATE(utype_class(context->unittype) == pclass); + case REQ_RANGE_TILE: + case REQ_RANGE_CADJACENT: + case REQ_RANGE_ADJACENT: + if (context->tile == nullptr) { + return TRI_MAYBE; + } + + unit_list_iterate(context->tile->units, punit) { + if (unit_class_get(punit) == pclass) { + return TRI_YES; + } + } unit_list_iterate_end; + + if (req->range == REQ_RANGE_TILE) { + return TRI_NO; + } + + if (req->range == REQ_RANGE_CADJACENT) { + cardinal_adjc_iterate(nmap, context->tile, adjc_tile) { + unit_list_iterate(adjc_tile->units, punit) { + if (unit_class_get(punit) == pclass) { + return TRI_YES; + } + } unit_list_iterate_end; + } cardinal_adjc_iterate_end; + } else { + fc_assert(req->range == REQ_RANGE_ADJACENT); + + adjc_iterate(nmap, context->tile, adjc_tile) { + unit_list_iterate(adjc_tile->units, punit) { + if (unit_class_get(punit) == pclass) { + return TRI_YES; + } + } unit_list_iterate_end; + } adjc_iterate_end; + } + + return TRI_NO; + + case REQ_RANGE_CITY: + case REQ_RANGE_TRADE_ROUTE: + case REQ_RANGE_CONTINENT: + case REQ_RANGE_PLAYER: + case REQ_RANGE_TEAM: + case REQ_RANGE_ALLIANCE: + case REQ_RANGE_WORLD: + case REQ_RANGE_COUNT: + fc_assert(FALSE); + break; } - return BOOL_TO_TRISTATE(utype_class(context->unittype) == pclass); + return TRI_NO; } /**********************************************************************//** diff --git a/doc/README.effects b/doc/README.effects index 6497cb6d2a..9c269531d0 100644 --- a/doc/README.effects +++ b/doc/README.effects @@ -73,7 +73,7 @@ Terrain: Tile, Adjacent, CAdjacent, Traderoute, City Good: City UnitType: Local, Tile, CAdjacent, Adjacent UnitFlag: Local, Tile, CAdjacent, Adjacent -UnitClass: Local +UnitClass: Local, Tile, CAdjacent, Adjacent UnitClassFlag: Local Nation: World, Alliance, Team, Player NationGroup: World, Alliance, Team, Player diff --git a/server/ruleset/rssanity.c b/server/ruleset/rssanity.c index 65c7cf20a5..671f2d79e2 100644 --- a/server/ruleset/rssanity.c +++ b/server/ruleset/rssanity.c @@ -336,7 +336,6 @@ static bool sanity_check_req_set(rs_conversion_logger logger, /* Multiple requirements of the same type */ switch (preq->source.kind) { case VUT_GOVERNMENT: - case VUT_UCLASS: case VUT_ACTION: case VUT_ACTIVITY: case VUT_OTYPE: @@ -434,6 +433,7 @@ static bool sanity_check_req_set(rs_conversion_logger logger, case VUT_CITYTILE: case VUT_GOOD: case VUT_UTYPE: + case VUT_UCLASS: /* Can check different properties. */ case VUT_UTFLAG: case VUT_UCFLAG: -- 2.43.0