Project

General

Profile

Feature #1505 » 0082-Add-MaxTopUnitsOnTile-requirement-type.patch

Marko Lindqvist, 06/11/2025 04:36 AM

View differences:

ai/default/daieffects.c
case VUT_DIPLREL_TILE_O:
case VUT_DIPLREL_UNITANY:
case VUT_DIPLREL_UNITANY_O:
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
case VUT_MAXTILETOPUNITS:
case VUT_STYLE:
case VUT_UNITSTATE:
case VUT_ACTIVITY:
ai/default/daimilitary.c
case VUT_UNITSTATE:
case VUT_ACTIVITY:
case VUT_MINSIZE:
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
case VUT_MAXTILETOPUNITS:
case VUT_MINHP:
case VUT_MINMOVES:
case VUT_COUNTER:
common/fc_types.h
enum impr_flag_id impr_flag;
enum plr_flag_id plr_flag;
int minmoves;
int max_tile_units;
int max_tile_total_units;
int max_tile_top_units;
int minveteran;
int min_hit_points;
int age;
common/metaknowledge.c
}
}
if (req->source.kind == VUT_MAXTILEUNITS) {
if (req->source.kind == VUT_MAXTILETOTALUNITS
|| req->source.kind == VUT_MAXTILETOPUNITS) {
if (context->tile == nullptr) {
/* The tile may exist but not be passed when the problem type is
* RPT_POSSIBLE. */
common/oblig_reqs.c
* conquer a city belonging to someone they were at war with.
* Conclusion: the conquered city had to be empty.
*/
oblig_hard_req_register(req_from_values(VUT_MAXTILEUNITS, REQ_RANGE_TILE,
oblig_hard_req_register(req_from_values(VUT_MAXTILETOTALUNITS, REQ_RANGE_TILE,
FALSE, FALSE, TRUE, 0),
TRUE,
N_("All action enablers for %s must require"
common/reqtext.c
}
break;
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
switch (preq->range) {
case REQ_RANGE_TILE:
fc_strlcat(buf, prefix, bufsz);
if (preq->present) {
cat_snprintf(buf, bufsz,
PL_("At most %d unit may be present on the tile.",
"At most %d units may be present on the tile.",
preq->source.value.max_tile_units),
preq->source.value.max_tile_units);
PL_("At most %d total unit may be present on the tile.",
"At most %d total units may be present on the tile.",
preq->source.value.max_tile_total_units),
preq->source.value.max_tile_total_units);
} else {
cat_snprintf(buf, bufsz,
PL_("There must be more than %d unit present on "
PL_("There must be more than %d total unit present on "
"the tile.",
"There must be more than %d units present on "
"There must be more than %d total units present on "
"the tile.",
preq->source.value.max_tile_units),
preq->source.value.max_tile_units);
preq->source.value.max_tile_total_units),
preq->source.value.max_tile_total_units);
}
return TRUE;
case REQ_RANGE_CADJACENT:
......
if (preq->present) {
cat_snprintf(buf, bufsz,
PL_("The tile or at least one cardinally adjacent tile "
"must have %d unit or fewer.",
"must have %d total unit or fewer.",
"The tile or at least one cardinally adjacent tile "
"must have %d units or fewer.",
preq->source.value.max_tile_units),
preq->source.value.max_tile_units);
"must have %d total units or fewer.",
preq->source.value.max_tile_total_units),
preq->source.value.max_tile_total_units);
} else {
cat_snprintf(buf, bufsz,
PL_("The tile and all cardinally adjacent tiles must "
"have more than %d unit each.",
"have more than %d total unit each.",
"The tile and all cardinally adjacent tiles must "
"have more than %d units each.",
preq->source.value.max_tile_units),
preq->source.value.max_tile_units);
"have more than %d total units each.",
preq->source.value.max_tile_total_units),
preq->source.value.max_tile_total_units);
}
return TRUE;
case REQ_RANGE_ADJACENT:
......
if (preq->present) {
cat_snprintf(buf, bufsz,
PL_("The tile or at least one adjacent tile must have "
"%d unit or fewer.",
"%d total unit or fewer.",
"The tile or at least one adjacent tile must have "
"%d units or fewer.",
preq->source.value.max_tile_units),
preq->source.value.max_tile_units);
"%d total units or fewer.",
preq->source.value.max_tile_total_units),
preq->source.value.max_tile_total_units);
} else {
cat_snprintf(buf, bufsz,
PL_("The tile and all adjacent tiles must have more "
"than %d unit each.",
"than %d total unit each.",
"The tile and all adjacent tiles must have more "
"than %d units each.",
preq->source.value.max_tile_units),
preq->source.value.max_tile_units);
"than %d total units each.",
preq->source.value.max_tile_total_units),
preq->source.value.max_tile_total_units);
}
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 VUT_MAXTILETOPUNITS:
switch (preq->range) {
case REQ_RANGE_TILE:
fc_strlcat(buf, prefix, bufsz);
if (preq->present) {
cat_snprintf(buf, bufsz,
PL_("At most %d unit may be directly present on the tile.",
"At most %d units may be directly present on the tile.",
preq->source.value.max_tile_top_units),
preq->source.value.max_tile_top_units);
} else {
cat_snprintf(buf, bufsz,
PL_("There must be more than %d unit directly present on "
"the tile.",
"There must be more than %d units directly present on "
"the tile.",
preq->source.value.max_tile_top_units),
preq->source.value.max_tile_top_units);
}
return TRUE;
case REQ_RANGE_CADJACENT:
fc_strlcat(buf, prefix, bufsz);
if (preq->present) {
cat_snprintf(buf, bufsz,
PL_("The tile or at least one cardinally adjacent tile "
"must directly have %d unit or fewer.",
"The tile or at least one cardinally adjacent tile "
"must directly have %d units or fewer.",
preq->source.value.max_tile_top_units),
preq->source.value.max_tile_top_units);
} else {
cat_snprintf(buf, bufsz,
PL_("The tile and all cardinally adjacent tiles must "
"have directly more than %d unit each.",
"The tile and all cardinally adjacent tiles must "
"have directly more than %d units each.",
preq->source.value.max_tile_top_units),
preq->source.value.max_tile_top_units);
}
return TRUE;
case REQ_RANGE_ADJACENT:
fc_strlcat(buf, prefix, bufsz);
if (preq->present) {
cat_snprintf(buf, bufsz,
PL_("The tile or at least one adjacent tile must have "
"directly %d unit or fewer.",
"The tile or at least one adjacent tile must have "
"directly %d units or fewer.",
preq->source.value.max_tile_top_units),
preq->source.value.max_tile_top_units);
} else {
cat_snprintf(buf, bufsz,
PL_("The tile and all adjacent tiles must have "
"directly more than %d unit each.",
"The tile and all adjacent tiles must have "
"directly more than %d units each.",
preq->source.value.max_tile_top_units),
preq->source.value.max_tile_top_units);
}
return TRUE;
case REQ_RANGE_CITY:
common/requirements.c
return;
}
break;
case VUT_MAXTILEUNITS:
source->value.max_tile_units = atoi(value);
if (0 <= source->value.max_tile_units) {
case VUT_MAXTILETOTALUNITS:
source->value.max_tile_total_units = atoi(value);
if (0 <= source->value.max_tile_total_units) {
return;
}
break;
case VUT_MAXTILETOPUNITS:
source->value.max_tile_top_units = atoi(value);
if (0 <= source->value.max_tile_top_units) {
return;
}
break;
......
case VUT_AI_LEVEL:
source.value.ai_level = value;
return source;
case VUT_MAXTILEUNITS:
source.value.max_tile_units = value;
case VUT_MAXTILETOTALUNITS:
source.value.max_tile_total_units = value;
return source;
case VUT_MAXTILETOPUNITS:
source.value.max_tile_top_units = value;
return source;
case VUT_TERRAINCLASS:
source.value.terrainclass = value;
......
return source->value.minforeignpct;
case VUT_AI_LEVEL:
return source->value.ai_level;
case VUT_MAXTILEUNITS:
return source->value.max_tile_units;
case VUT_MAXTILETOTALUNITS:
return source->value.max_tile_total_units;
case VUT_MAXTILETOPUNITS:
return source->value.max_tile_top_units;
case VUT_TERRAINCLASS:
return source->value.terrainclass;
case VUT_ROADFLAG:
......
case VUT_TERRAINCLASS:
case VUT_TERRAINALTER:
case VUT_CITYTILE:
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
case VUT_MAXTILETOPUNITS:
case VUT_MINLATITUDE:
case VUT_MAXLATITUDE:
case VUT_MAX_DISTANCE_SQ:
......
invalid = (req.range != REQ_RANGE_TILE);
break;
case VUT_CITYTILE:
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
case VUT_MAXTILETOPUNITS:
invalid = (req.range != REQ_RANGE_TILE
&& req.range != REQ_RANGE_CADJACENT
&& req.range != REQ_RANGE_ADJACENT);
......
case VUT_DIPLREL_TILE_O:
case VUT_DIPLREL_UNITANY:
case VUT_DIPLREL_UNITANY_O:
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
case VUT_MAXTILETOPUNITS:
case VUT_MINTECHS:
case VUT_FUTURETECHS:
case VUT_MINCITIES:
......
}
/**********************************************************************//**
Determine whether a maximum units on tile requirement is satisfied in a
given context, ignoring parts of the requirement that can be handled
Determine whether a maximum total units on tile requirement is satisfied in
a given context, ignoring parts of the requirement that can be handled
uniformly for all requirement types.
context, other_context and req must not be null,
and req must be a maxunitsontile requirement
**************************************************************************/
static enum fc_tristate
is_maxunitsontile_req_active(const struct civ_map *nmap,
const struct req_context *context,
const struct req_context *other_context,
const struct requirement *req)
is_maxtotalunitsontile_req_active(const struct civ_map *nmap,
const struct req_context *context,
const struct req_context *other_context,
const struct requirement *req)
{
int max_units;
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_MAXTILEUNITS);
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_MAXTILETOTALUNITS);
max_units = req->source.value.max_tile_units;
max_units = req->source.value.max_tile_total_units;
/* TODO: If can't see V_INVIS -> TRI_MAYBE */
switch (req->range) {
......
return TRI_MAYBE;
}
/**********************************************************************//**
Determine whether a maximum top units on tile requirement is satisfied in
a given context, ignoring parts of the requirement that can be handled
uniformly for all requirement types.
context, other_context and req must not be null,
and req must be a maxunitsontile requirement
**************************************************************************/
static enum fc_tristate
is_maxtopunitsontile_req_active(const struct civ_map *nmap,
const struct req_context *context,
const struct req_context *other_context,
const struct requirement *req)
{
int max_units;
int count;
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_MAXTILETOPUNITS);
max_units = req->source.value.max_tile_top_units;
/* TODO: If can't see V_INVIS -> TRI_MAYBE */
switch (req->range) {
case REQ_RANGE_TILE:
if (!context->tile) {
return TRI_MAYBE;
}
count = 0;
unit_list_iterate(context->tile->units, punit) {
if (!unit_transported(punit)) {
count++;
}
} unit_list_iterate_end;
return BOOL_TO_TRISTATE(count <= max_units);
case REQ_RANGE_CADJACENT:
if (!context->tile) {
return TRI_MAYBE;
}
count = 0;
unit_list_iterate(context->tile->units, punit) {
if (!unit_transported(punit)) {
count++;
}
} unit_list_iterate_end;
if (count <= max_units) {
return TRI_YES;
}
cardinal_adjc_iterate(nmap, context->tile, adjc_tile) {
count = 0;
unit_list_iterate(adjc_tile->units, punit) {
if (!unit_transported(punit)) {
count++;
}
} unit_list_iterate_end;
if (count <= max_units) {
return TRI_YES;
}
} cardinal_adjc_iterate_end;
return TRI_NO;
case REQ_RANGE_ADJACENT:
if (!context->tile) {
return TRI_MAYBE;
}
count = 0;
unit_list_iterate(context->tile->units, punit) {
if (!unit_transported(punit)) {
count++;
}
} unit_list_iterate_end;
if (count <= max_units) {
return TRI_YES;
}
adjc_iterate(nmap, context->tile, adjc_tile) {
count = 0;
unit_list_iterate(adjc_tile->units, punit) {
if (!unit_transported(punit)) {
count++;
}
} unit_list_iterate_end;
if (count <= max_units) {
return TRI_YES;
}
} 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_LOCAL:
case REQ_RANGE_COUNT:
break;
}
fc_assert_msg(FALSE, "Invalid range %d.", req->range);
return TRI_MAYBE;
}
/**********************************************************************//**
Determine whether an extra requirement is satisfied in a given context,
ignoring parts of the requirement that can be handled uniformly for all
......
[VUT_MAX_DISTANCE_SQ] = {is_max_distance_sq_req_active, REQUCH_YES},
[VUT_MAX_REGION_TILES] = {is_max_region_tiles_req_active, REQUCH_NO},
[VUT_MAXLATITUDE] = {is_latitude_req_active, REQUCH_YES},
[VUT_MAXTILEUNITS] = {is_maxunitsontile_req_active, REQUCH_NO},
[VUT_MAXTILETOTALUNITS] = {is_maxtotalunitsontile_req_active, REQUCH_NO},
[VUT_MAXTILETOPUNITS] = {is_maxtopunitsontile_req_active, REQUCH_NO},
[VUT_MINCALFRAG] = {is_mincalfrag_req_active, REQUCH_NO},
[VUT_MINCULTURE] = {is_minculture_req_active, REQUCH_NO},
[VUT_MINFOREIGNPCT] = {is_minforeignpct_req_active, REQUCH_NO},
......
case VUT_DIPLREL_TILE_O:
case VUT_DIPLREL_UNITANY:
case VUT_DIPLREL_UNITANY_O:
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
case VUT_MAXTILETOPUNITS:
case VUT_UTYPE:
case VUT_UCLASS:
case VUT_MINVETERAN:
......
return psource1->value.minforeignpct == psource2->value.minforeignpct;
case VUT_AI_LEVEL:
return psource1->value.ai_level == psource2->value.ai_level;
case VUT_MAXTILEUNITS:
return psource1->value.max_tile_units == psource2->value.max_tile_units;
case VUT_MAXTILETOTALUNITS:
return psource1->value.max_tile_total_units == psource2->value.max_tile_total_units;
case VUT_MAXTILETOPUNITS:
return psource1->value.max_tile_top_units == psource2->value.max_tile_top_units;
case VUT_TERRAINCLASS:
return psource1->value.terrainclass == psource2->value.terrainclass;
case VUT_ROADFLAG:
......
return buffer;
case VUT_AI_LEVEL:
return ai_level_name(psource->value.ai_level);
case VUT_MAXTILEUNITS:
fc_snprintf(buffer, sizeof(buffer), "%d", psource->value.max_tile_units);
case VUT_MAXTILETOTALUNITS:
fc_snprintf(buffer, sizeof(buffer), "%d", psource->value.max_tile_total_units);
return buffer;
case VUT_MAXTILETOPUNITS:
fc_snprintf(buffer, sizeof(buffer), "%d", psource->value.max_tile_top_units);
return buffer;
case VUT_TERRAINCLASS:
return terrain_class_name(psource->value.terrainclass);
......
cat_snprintf(buf, bufsz, _("%s AI"),
ai_level_translated_name(psource->value.ai_level)); /* FIXME */
return buf;
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
/* TRANS: here <= means 'less than or equal' */
cat_snprintf(buf, bufsz, PL_("<=%d total unit",
"<=%d total units",
psource->value.max_tile_total_units),
psource->value.max_tile_total_units);
return buf;
case VUT_MAXTILETOPUNITS:
/* TRANS: here <= means 'less than or equal' */
cat_snprintf(buf, bufsz, PL_("<=%d unit",
"<=%d units", psource->value.max_tile_units),
psource->value.max_tile_units);
"<=%d units", psource->value.max_tile_top_units),
psource->value.max_tile_top_units);
return buf;
case VUT_TERRAINCLASS:
/* TRANS: Terrain class: "Land terrain" */
doc/README.effects
Requirement types and supported ranges
======================================
Tech: World, Alliance, Team, Player, Local
TechFlag: World, Alliance, Team, Player, Local
MinTechs: World, Player
FutureTechs: World, Player
MinCities: Player
Achievement: World, Alliance, Team, Player
Counter: City
Gov: Player
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
Terrain: Tile, Adjacent, CAdjacent, Traderoute, City
Good: City
UnitType: Local, Tile, CAdjacent, Adjacent
UnitTypeFlag: Local, Tile, CAdjacent, Adjacent
UnitClass: Local, Tile, CAdjacent, Adjacent
UnitClassFlag: Local, Tile, CAdjacent, Adjacent
Nation: World, Alliance, Team, Player
NationGroup: World, Alliance, Team, Player
Nationality: Traderoute, City
PlayerFlag: Player
PlayerState: Player
OriginalOwner: City
DiplRel: World, Alliance, Team, Player, Local
DiplRelTile: Alliance, Team, Player, Local
DiplRelTileOther:Local
DiplRelUnitAny: Alliance, Team, Player, Local
Tech: World, Alliance, Team, Player, Local
TechFlag: World, Alliance, Team, Player, Local
MinTechs: World, Player
FutureTechs: World, Player
MinCities: Player
Achievement: World, Alliance, Team, Player
Counter: City
Gov: Player
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
Terrain: Tile, Adjacent, CAdjacent, Traderoute, City
Good: City
UnitType: Local, Tile, CAdjacent, Adjacent
UnitTypeFlag: Local, Tile, CAdjacent, Adjacent
UnitClass: Local, Tile, CAdjacent, Adjacent
UnitClassFlag: Local, Tile, CAdjacent, Adjacent
Nation: World, Alliance, Team, Player
NationGroup: World, Alliance, Team, Player
Nationality: Traderoute, City
PlayerFlag: Player
PlayerState: Player
OriginalOwner: City
DiplRel: World, Alliance, Team, Player, Local
DiplRelTile: Alliance, Team, Player, Local
DiplRelTileOther: Local
DiplRelUnitAny: Alliance, Team, Player, Local
DiplRelUnitAnyOther: Local
Action: Local
OutputType: Local
Specialist: Local
MinYear: World
MinCalFrag: World
Topology: World
Wrap: World
ServerSetting: World
Age (of unit): Local
Age (of city): City
Age (of player): Player
FormAge: Local
MinSize: Traderoute, City
MinCulture: World, Alliance, Team, Player, Traderoute, City
MinForeignPct: Traderoute, City
AI: Player
MaxUnitsOnTile: Tile, Adjacent, CAdjacent
TerrainClass: Tile, Adjacent, CAdjacent, Traderoute, City
TerrainFlag: Tile, Adjacent, CAdjacent, Traderoute, City
TerrainAlter: Tile
MinLatitude: Tile, Adjacent, CAdjacent, World
MaxLatitude: Tile, Adjacent, CAdjacent, World
CityTile: Tile, Adjacent, CAdjacent
CityStatus: Traderoute, City
Style: Player
UnitState: Local
Activity: Local
MinMoveFrags: Local
MinVeteran: Local
MinHitPoints: Local
TileRel: Tile, Adjacent, CAdjacent
MaxDistanceSq: Tile
MaxRegionTiles: Continent, Adjacent, CAdjacent
Action: Local
OutputType: Local
Specialist: Local
MinYear: World
MinCalFrag: World
Topology: World
Wrap: World
ServerSetting: World
Age (of unit): Local
Age (of city): City
Age (of player): Player
FormAge: Local
MinSize: Traderoute, City
MinCulture: World, Alliance, Team, Player, Traderoute, City
MinForeignPct: Traderoute, City
AI: Player
MaxUnitsOnTile: Tile, Adjacent, CAdjacent
MaxTopUnitsOnTile: Tile, Adjacent, CAdjacent
TerrainClass: Tile, Adjacent, CAdjacent, Traderoute, City
TerrainFlag: Tile, Adjacent, CAdjacent, Traderoute, City
TerrainAlter: Tile
MinLatitude: Tile, Adjacent, CAdjacent, World
MaxLatitude: Tile, Adjacent, CAdjacent, World
CityTile: Tile, Adjacent, CAdjacent
CityStatus: Traderoute, City
Style: Player
UnitState: Local
Activity: Local
MinMoveFrags: Local
MinVeteran: Local
MinHitPoints: Local
TileRel: Tile, Adjacent, CAdjacent
MaxDistanceSq: Tile
MaxRegionTiles: Continent, Adjacent, CAdjacent
Site is like Building, except that the requirement is fulfilled even after
gen_headers/enums/fc_types_enums.def
IMPR_FLAG "BuildingFlag"
IMPR_GENUS "BuildingGenus"
MAXLATITUDE "MaxLatitude"
MAXTILEUNITS "MaxUnitsOnTile"
MAXTILETOPUNITS "MaxTopUnitsOnTile"
MAXTILETOTALUNITS "MaxUnitsOnTile"
MAX_DISTANCE_SQ "MaxDistanceSq"
MAX_REGION_TILES "MaxRegionTiles"
MINCALFRAG "MinCalFrag"
server/cityturn.c
purge = TRUE;
}
break;
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
if (preq->present) {
notify_player(pplayer, city_tile(pcity),
E_CITY_CANTBUILD, ftc_server,
PL_("%s can't build %s from the worklist; "
"more than %d total unit on tile."
" Postponing...",
"%s can't build %s from the worklist; "
"more than %d total units on tile."
" Postponing...",
preq->source.value.max_tile_total_units),
city_link(pcity),
tgt_name,
preq->source.value.max_tile_total_units);
script_server_signal_emit(signal_name, ptarget,
pcity, "need_tileunits");
} else {
notify_player(pplayer, city_tile(pcity),
E_CITY_CANTBUILD, ftc_server,
PL_("%s can't build %s from the worklist; "
"fewer than %d total unit on tile."
" Postponing...",
"%s can't build %s from the worklist; "
"fewer than %d total units on tile."
" Postponing...",
preq->source.value.max_tile_total_units + 1),
city_link(pcity),
tgt_name,
preq->source.value.max_tile_total_units + 1);
script_server_signal_emit(signal_name, ptarget,
pcity, "need_tileunits");
}
break;
case VUT_MAXTILETOPUNITS:
if (preq->present) {
notify_player(pplayer, city_tile(pcity),
E_CITY_CANTBUILD, ftc_server,
......
"%s can't build %s from the worklist; "
"more than %d units on tile."
" Postponing...",
preq->source.value.max_tile_units),
preq->source.value.max_tile_top_units),
city_link(pcity),
tgt_name,
preq->source.value.max_tile_units);
preq->source.value.max_tile_top_units);
script_server_signal_emit(signal_name, ptarget,
pcity, "need_tileunits");
pcity, "need_tiletopunits");
} else {
notify_player(pplayer, city_tile(pcity),
E_CITY_CANTBUILD, ftc_server,
......
"%s can't build %s from the worklist; "
"fewer than %d units on tile."
" Postponing...",
preq->source.value.max_tile_units + 1),
preq->source.value.max_tile_top_units + 1),
city_link(pcity),
tgt_name,
preq->source.value.max_tile_units + 1);
preq->source.value.max_tile_top_units + 1);
script_server_signal_emit(signal_name, ptarget,
pcity, "need_tileunits");
pcity, "need_tiletopunits");
}
break;
case VUT_AI_LEVEL:
server/ruleset/rssanity.c
/* Can have multiple, since it's flag based (wrapx & wrapy) */
case VUT_EXTRA:
/* Note that there can be more than 1 extra / tile. */
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
case VUT_MAXTILETOPUNITS:
/* Can require different numbers on e.g. local/adjacent tiles. */
case VUT_NATION:
/* Can require multiple nations at Team/Alliance/World range. */
tools/ruledit/univ_value.c
case VUT_DIPLREL_UNITANY_O:
src->value.diplrel = DS_WAR;
return TRUE;
case VUT_MAXTILEUNITS:
src->value.max_tile_units = 0;
case VUT_MAXTILETOTALUNITS:
src->value.max_tile_total_units = 0;
return TRUE;
case VUT_MAXTILETOPUNITS:
src->value.max_tile_top_units = 0;
return TRUE;
case VUT_STYLE:
if (game.control.num_styles <= 0) {
......
case VUT_MINSIZE:
case VUT_MINYEAR:
case VUT_MINCALFRAG:
case VUT_MAXTILEUNITS:
case VUT_MAXTILETOTALUNITS:
case VUT_MAXTILETOPUNITS:
case VUT_MINCULTURE:
case VUT_MINFOREIGNPCT:
case VUT_MINMOVES:
(2-2/3)