Project

General

Profile

Feature #678 » 0008-Add-Same-Terrain-Class-TileRel-requirement.patch

main v2 - Alina Lenk, 06/02/2024 12:36 PM

View differences:

common/metaknowledge.c
}
if (req->source.kind == VUT_TILE_REL) {
enum known_type needed;
if (context->tile == NULL || other_context->tile == NULL) {
/* The tile may exist but not be passed when the problem type is
* RPT_POSSIBLE. */
return prob_type == RPT_CERTAIN;
}
if (tile_get_known(other_context->tile, pov_player) == TILE_UNKNOWN) {
switch (req->source.value.tilerel) {
case TREL_REGION_SURROUNDED:
/* Too complicated to figure out */
return FALSE;
case TREL_SAME_TCLASS:
/* Evaluated based on actual terrain type's class */
needed = TILE_KNOWN_SEEN;
break;
default:
/* Only need the continent ID; known is enough */
needed = TILE_KNOWN_UNSEEN;
break;
}
if (req->source.value.tilerel == TREL_REGION_SURROUNDED) {
/* Too complicated to figure out */
if (tile_get_known(other_context->tile, pov_player) < needed) {
return FALSE;
}
......
case REQ_RANGE_ADJACENT:
/* TODO: Known tiles might be enough to determine the answer already;
* should we check on an individual requirement basis? */
if (tile_get_known(context->tile, pov_player) == TILE_UNKNOWN) {
if (tile_get_known(context->tile, pov_player) < needed) {
return FALSE;
}
range_adjc_iterate(&(wld.map), context->tile, req->range, adj_tile) {
if (tile_get_known(adj_tile, pov_player) == TILE_UNKNOWN) {
if (tile_get_known(adj_tile, pov_player) < needed) {
return FALSE;
}
} range_adjc_iterate_end;
common/reqtext.c
case VUT_TILE_REL:
switch (preq->source.value.tilerel) {
case TREL_SAME_TCLASS:
switch (preq->range) {
case REQ_RANGE_TILE:
fc_strlcat(buf, prefix, bufsz);
if (preq->present) {
fc_strlcat(buf, _("Must be on the same terrain class."),
bufsz);
} else {
fc_strlcat(buf, _("Must be on a different terrain class."),
bufsz);
}
return TRUE;
case REQ_RANGE_CADJACENT:
fc_strlcat(buf, prefix, bufsz);
if (preq->present) {
fc_strlcat(buf, _("Must be cardinally adjacent to the same "
"terrain class."),
bufsz);
} else {
fc_strlcat(buf, _("Must not be cardinally adjacent to the same "
"terrain class."),
bufsz);
}
return TRUE;
case REQ_RANGE_ADJACENT:
fc_strlcat(buf, prefix, bufsz);
if (preq->present) {
fc_strlcat(buf, _("Must be adjacent to the same terrain class."),
bufsz);
} else {
fc_strlcat(buf, _("Must not be adjacent to the same terrain "
"class."),
bufsz);
}
return TRUE;
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_LOCAL:
case REQ_RANGE_COUNT:
/* Not supported. */
break;
}
break;
case TREL_SAME_REGION:
switch (preq->range) {
case REQ_RANGE_TILE:
common/requirements.c
/* Same requirement at different ranges. Note that same range is
* already covered by are_requirements_opposites() above. */
switch (req1->source.value.tilerel) {
case TREL_SAME_TCLASS:
case TREL_SAME_REGION:
case TREL_REGION_SURROUNDED:
/* Negated req at larger range contradicts present req at
......
return FALSE;
}
}
if (req1->source.value.tilerel == TREL_REGION_SURROUNDED
|| req2->source.value.tilerel == TREL_REGION_SURROUNDED) {
if (req1->source.value.tilerel == TREL_SAME_TCLASS
&& req2->source.value.tilerel == TREL_SAME_REGION) {
/* Same region at any range implies same terrain class at that range
* and any larger range ~> contradicts negated */
return (!req1->present && req2->present
&& (req1->range >= req2->range));
} else if (req2->source.value.tilerel == TREL_SAME_TCLASS
&& req1->source.value.tilerel == TREL_SAME_REGION) {
/* Same as above */
return (req1->present && !req2->present
&& (req1->range <= req2->range));
} else if (req1->source.value.tilerel == TREL_REGION_SURROUNDED
|| req2->source.value.tilerel == TREL_REGION_SURROUNDED) {
const struct requirement *surr, *other;
if (req1->source.value.tilerel == TREL_REGION_SURROUNDED) {
surr = req1;
......
}
if (surr->present && surr->range == REQ_RANGE_TILE) {
/* Target tile must be part of a surrounded region
* ~> not the same terrain class
* ~> not the same region
* ~> not touched by a third region */
switch (other->source.value.tilerel) {
case TREL_SAME_TCLASS:
case TREL_SAME_REGION:
return (other->present && other->range == REQ_RANGE_TILE);
case TREL_ONLY_OTHER_REGION:
......
}
switch (req->source.value.tilerel) {
case TREL_SAME_TCLASS:
if (tile_terrain(other_context->tile) == T_UNKNOWN) {
return TRI_MAYBE;
}
fc_assert_ret_val_msg((req->range == REQ_RANGE_TILE
|| req->range == REQ_RANGE_CADJACENT
|| req->range == REQ_RANGE_ADJACENT),
TRI_MAYBE,
"Invalid range %d for tile relation \"%s\" req",
req->range, tilerel_type_name(TREL_SAME_TCLASS));
{
enum terrain_class cls = terrain_type_terrain_class(
tile_terrain(other_context->tile));
bool seen_unknown = FALSE;
const struct terrain *terr;
if ((terr = tile_terrain(context->tile)) == T_UNKNOWN) {
seen_unknown = TRUE;
} else if (terrain_type_terrain_class(terr) == cls) {
return TRUE;
}
range_adjc_iterate(nmap, context->tile, req->range, adj_tile) {
if ((terr = tile_terrain(adj_tile)) == T_UNKNOWN) {
seen_unknown = TRUE;
} else if (terrain_type_terrain_class(terr) == cls) {
return TRUE;
}
} range_adjc_iterate_end;
if (seen_unknown) {
return TRI_MAYBE;
} else {
return TRI_NO;
}
}
break;
case TREL_SAME_REGION:
if (tile_continent(other_context->tile) == 0) {
return TRI_MAYBE;
......
return buf;
case VUT_TILE_REL:
switch (psource->value.tilerel) {
case TREL_SAME_TCLASS:
fc_strlcat(buf, _("Same terrain class"), bufsz);
break;
case TREL_SAME_REGION:
fc_strlcat(buf, _("Same continent/ocean"), bufsz);
break;
doc/README.effects
(north pole).
TileRel is about the relation to a specific other tile; currently only available
for action enablers (see also README.actions) and a select few effects. It is
one of "Same Region" (on or adjacent to the same continent/ocean as the other
tile, depending on range), "Only Other Region" (only adjacent to tiles of its
own or the other tile's continent/ocean, not a third one; not available at Tile
range), or "Region Surrounded" (on or adjacent to a lake/island touching only
the other tile's continent/ocean).
one of "Same Terrain Class" (on or adjacent to the same terrain class as the
other tile, depending on range), "Same Region" (on or adjacent to the same
continent/ocean as the other tile), "Only Other Region" (only adjacent to tiles
of its own or the other tile's continent/ocean, not a third one; not available
at Tile range), or "Region Surrounded" (on or adjacent to a lake/island
touching only the other tile's continent/ocean).
MaxDistanceSq is about the (squared) distance between two tiles; currently
only available for action enablers (see also README.actions) and a select
few effects.
gen_headers/enums/fc_types_enums.def
ONLY_OTHER_REGION "Only Other Region"
REGION_SURROUNDED "Region Surrounded"
SAME_REGION "Same Region"
SAME_TCLASS "Same Terrain Class"
end
(2-2/2)