Feature #678 » 0008-Add-Same-Terrain-Class-TileRel-requirement.patch
| 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
|
||
- « Previous
- 1
- 2
- Next »