Project

General

Profile

Feature #588 » 0007-Unhardcode-terrain-class-specific-border-claiming-ru.patch

main v3 - Alina Lenk, 05/16/2024 10:03 PM

View differences:

ai/default/daieffects.c
case EFT_UNIT_SHIELD_VALUE_PCT:
case EFT_NUKE_BLAST_RADIUS_1_SQ:
case EFT_HEAL_UNIT_PCT:
case EFT_TILE_CLAIMABLE_FROM_SAME:
case EFT_TILE_CLAIMABLE_FROM_OTHER:
break;
/* This has no effect for AI */
case EFT_VISIBLE_WALLS:
common/fc_types.h
* compatibility code to server/rscompat.c. */
#define CASUS_BELLI_OUTRAGE 1000
/* A border source can claim tiles on or surrounded by the same continent
* or body of water if EFT_TILE_CLAIMABLE_* is equal to or above
* TILE_CLAIMABLE_CONTINENT. To change this value you must update the
* documentation of each Tile_Claimable_* effect in
* doc/README.effects, update existing rulesets and add ruleset
* compatibility code to server/rscompat.c. */
#define TILE_CLAIMABLE_CONTINENT 1
/* A border source can claim any tiles if EFT_TILE_CLAIMABLE_* is equal to
* or above TILE_CLAIMABLE_ALWAYS. To change this value you must update the
* documentation of each Tile_Claimable_* effect in
* doc/README.effects, update existing rulesets and add ruleset
* compatibility code to server/rscompat.c. */
#define TILE_CLAIMABLE_ALWAYS 1000
/* Really in ai.c */
const char *ai_level_name_update_cb(const char *old);
common/tech.h
/* Player can build air units */
#define SPECENUM_VALUE2 TF_BUILD_AIRBORNE
#define SPECENUM_VALUE2NAME N_("Build_Airborne")
/* Player can claim ocean tiles non-adjacent to border source */
#define SPECENUM_VALUE3 TF_CLAIM_OCEAN
#define SPECENUM_VALUE3NAME N_("Claim_Ocean")
/* Player can claim ocean tiles non-adjacent to border source as long
* as source is ocean tile */
#define SPECENUM_VALUE4 TF_CLAIM_OCEAN_LIMITED
#define SPECENUM_VALUE4NAME N_("Claim_Ocean_Limited")
#define SPECENUM_VALUE5 TECH_USER_1
#define SPECENUM_VALUE6 TECH_USER_2
#define SPECENUM_VALUE7 TECH_USER_3
#define SPECENUM_VALUE8 TECH_USER_4
#define SPECENUM_VALUE9 TECH_USER_5
#define SPECENUM_VALUE10 TECH_USER_6
#define SPECENUM_VALUE11 TECH_USER_7
#define SPECENUM_VALUE3 TECH_USER_1
#define SPECENUM_VALUE4 TECH_USER_2
#define SPECENUM_VALUE5 TECH_USER_3
#define SPECENUM_VALUE6 TECH_USER_4
#define SPECENUM_VALUE7 TECH_USER_5
#define SPECENUM_VALUE8 TECH_USER_6
#define SPECENUM_VALUE9 TECH_USER_7
#define SPECENUM_VALUE10 TECH_USER_8
#define SPECENUM_VALUE11 TECH_USER_9
#define SPECENUM_VALUE12 TECH_USER_LAST
/* Keep this last. */
#define SPECENUM_COUNT TF_COUNT
data/alien/effects.ruleset
{ "type", "name", "range", "present"
"Action", "Upgrade Unit", "Local", TRUE
}
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
reqs =
{ "type", "name", "range"
"TerrainClass", "Land", "Tile"
}
; claim ocean from adjacent ocean
[effect_claim_ocean_base_same]
type = "Tile_Claimable_From_Same"
value = 1000
reqs =
{ "type", "name", "range"
"TerrainClass", "Oceanic", "Tile"
"MaxDistanceSq", "2", "Tile"
}
; claim ocean from surrounding land
[effect_claim_ocean_base_other]
type = "Tile_Claimable_From_Other"
value = 1
reqs =
{ "type", "name", "range"
"TerrainClass", "Oceanic", "Tile"
}
; claim ocean from any ocean with Ocean Cities
[effect_claim_ocean_full_same]
type = "Tile_Claimable_From_Same"
value = 1000
reqs =
{ "type", "name", "range"
"TerrainClass", "Oceanic", "Tile"
"Tech", "Ocean Cities", "Player"
}
; claim ocean from any land with Ocean Cities
[effect_claim_ocean_full_other]
type = "Tile_Claimable_From_Other"
value = 1000
reqs =
{ "type", "name", "range"
"TerrainClass", "Oceanic", "Tile"
"Tech", "Ocean Cities", "Player"
}
data/alien/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
......
name = _("Ocean Cities")
req1 = "Deneb Radar"
req2 = "Thermal Module"
flags = "Claim_Ocean"
flags = ""
graphic = "a.ocean_cities"
graphic_alt = "-"
helptext = _("Cities on ocean. Why not?")
data/civ1/effects.ruleset
{ "type", "name", "range", "present"
"Action", "Disband Unit Recover", "Local", TRUE
}
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Land", "Tile"
; }
; claim ocean from surrounding land
[effect_claim_ocean]
type = "Tile_Claimable_From_Other"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Oceanic", "Tile"
; }
data/civ1/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
data/civ2/effects.ruleset
{ "type", "name", "range", "present"
"Action", "Upgrade Unit", "Local", TRUE
}
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Land", "Tile"
; }
; claim ocean from surrounding land
[effect_claim_ocean]
type = "Tile_Claimable_From_Other"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Oceanic", "Tile"
; }
data/civ2/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
data/civ2civ3/effects.ruleset
{ "type", "name", "range", "present"
"Action", "Upgrade Unit", "Local", TRUE
}
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Land", "Tile"
; }
; claim ocean from surrounding land
[effect_claim_ocean]
type = "Tile_Claimable_From_Other"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Oceanic", "Tile"
; }
data/civ2civ3/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
data/classic/effects.ruleset
{ "type", "name", "range", "present"
"Action", "Upgrade Unit", "Local", TRUE
}
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Land", "Tile"
; }
; claim ocean from surrounding land
[effect_claim_ocean]
type = "Tile_Claimable_From_Other"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Oceanic", "Tile"
; }
data/classic/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
data/goldkeep/effects.ruleset
{ "type", "name", "range", "present"
"Action", "Upgrade Unit", "Local", TRUE
}
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Land", "Tile"
; }
; claim ocean from surrounding land
[effect_claim_ocean]
type = "Tile_Claimable_From_Other"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Oceanic", "Tile"
; }
data/goldkeep/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
data/granularity/effects.ruleset
{ "type", "name", "range"
"Extra", "Mine", "Tile"
}
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
reqs =
{ "type", "name", "range"
"TerrainClass", "Land", "Tile"
}
; claim ocean from adjacent ocean
[effect_claim_ocean_base_same]
type = "Tile_Claimable_From_Same"
value = 1000
reqs =
{ "type", "name", "range"
"TerrainClass", "Oceanic", "Tile"
"MaxDistanceSq", "2", "Tile"
}
; claim ocean from surrounding land
[effect_claim_ocean_base_other]
type = "Tile_Claimable_From_Other"
value = 1
reqs =
{ "type", "name", "range"
"TerrainClass", "Oceanic", "Tile"
}
data/granularity/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
data/multiplayer/effects.ruleset
{ "type", "name", "range", "present"
"Action", "Upgrade Unit", "Local", TRUE
}
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Land", "Tile"
; }
; claim ocean from surrounding land
[effect_claim_ocean]
type = "Tile_Claimable_From_Other"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Oceanic", "Tile"
; }
data/multiplayer/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
data/ruledit/comments-3.3.txt
; extra. See \"bridged_over\" extra property in\n\
; terrain.ruleset.\n\
; \"Build_Airborne\" = from now on can build air units (for use by AI)\n\
; \"Claim_Ocean\" = Player claims ocean tiles even if they are not\n\
; adjacent to border source\n\
; \"Claim_Ocean_Limited\" = Oceanic border sources claim ocean tiles even if\n\
; they are not adjacent to border source\n\
;\n\
; */ <-- avoid gettext warnings\n\
"
data/sandbox/effects.ruleset
"Counter", "Turn_Owned2", "City", TRUE
"Counter", "Turn_of_Celebration", "City", TRUE
}
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Land", "Tile"
; }
; claim ocean from surrounding land
[effect_claim_ocean]
type = "Tile_Claimable_From_Other"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Oceanic", "Tile"
; }
data/sandbox/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
data/stub/effects.ruleset
[effect_city_build_slots_basic]
type = "City_Build_Slots"
value = 1
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
reqs =
{ "type", "name", "range"
"TerrainClass", "Land", "Tile"
}
; claim ocean from adjacent ocean
[effect_claim_ocean_base_same]
type = "Tile_Claimable_From_Same"
value = 1000
reqs =
{ "type", "name", "range"
"TerrainClass", "Oceanic", "Tile"
"MaxDistanceSq", "2", "Tile"
}
; claim ocean from surrounding land
[effect_claim_ocean_base_other]
type = "Tile_Claimable_From_Other"
value = 1
reqs =
{ "type", "name", "range"
"TerrainClass", "Oceanic", "Tile"
}
data/stub/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
data/webperimental/effects.ruleset
{ "type", "name", "range", "present"
"Action", "Upgrade Unit", "Local", TRUE
}
; claim land from land on the same continent
[effect_claim_land]
type = "Tile_Claimable_From_Same"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Land", "Tile"
; }
; claim ocean from surrounding land
[effect_claim_ocean]
type = "Tile_Claimable_From_Other"
value = 1
; there are no oceanic border sources
;reqs =
; { "type", "name", "range"
; "TerrainClass", "Oceanic", "Tile"
; }
data/webperimental/techs.ruleset
; extra. See "bridged_over" extra property in
; terrain.ruleset.
; "Build_Airborne" = from now on can build air units (for use by AI)
; "Claim_Ocean" = Player claims ocean tiles even if they are not
; adjacent to border source
; "Claim_Ocean_Limited" = Oceanic border sources claim ocean tiles even if
; they are not adjacent to border source
;
; */ <-- avoid gettext warnings
doc/README.effects
"Steal Gold Escape" actions that is lost before it reaches the player
ordering it. Evaluated against the actor unit.
Tile_Claimable_From_Other
Controls whether national borders can expand to a tile from a border
source (city or base) on a tile of a different terrain class.
A positive value means the tile can be claimed if it is sufficiently
surrounded by the continent (or body of water) the source is part of
(e.g. inland seas, bays, small islands).
A value of at least 1000 means the tile can always be claimed.
Tile_Claimable_From_Same
Controls whether national borders can expand to a tile from a border
source (city or base) on a tile of the same terrain class.
A positive value means the tile can be claimed if it is part of the same
continent (or same body of water) as the border source.
A value of at least 1000 means the tile can always be claimed.
Tile_Workable
If value > 0, city can work target tile.
gen_headers/enums/effects_enums.def
TECH_LEAKAGE "Tech_Leakage"
IMPR_UPKEEP_REDUCTION "Impr_Upkeep_Reduction"
CULTURE_PCT "Culture_Pct"
TILE_CLAIMABLE_FROM_SAME "Tile_Claimable_From_Same"
TILE_CLAIMABLE_FROM_OTHER "Tile_Claimable_From_Other"
USER_EFFECT_1 "User_Effect_1"
USER_EFFECT_2 "User_Effect_2"
USER_EFFECT_3 "User_Effect_3"
server/generator/mapgen_utils.c
* ocean.
*/
static Continent_id *lake_surrounders = NULL;
static Continent_id *island_surrounders = NULL;
static int *continent_sizes = NULL;
static int *ocean_sizes = NULL;
/**********************************************************************//**
Calculate lake_surrounders[] array
Calculate lake_surrounders[] and island_surrounders[] arrays
**************************************************************************/
static void recalculate_lake_surrounders(void)
static void recalculate_surrounders(void)
{
const size_t size = (wld.map.num_oceans + 1) * sizeof(*lake_surrounders);
size_t size;
size = (wld.map.num_oceans + 1) * sizeof(*lake_surrounders);
lake_surrounders = fc_realloc(lake_surrounders, size);
memset(lake_surrounders, 0, size);
size = (wld.map.num_continents + 1) * sizeof(*island_surrounders);
island_surrounders = fc_realloc(island_surrounders, size);
memset(island_surrounders, 0, size);
whole_map_iterate(&(wld.map), ptile) {
const struct terrain *pterrain = tile_terrain(ptile);
Continent_id cont = tile_continent(ptile);
......
continue;
}
if (terrain_type_terrain_class(pterrain) != TC_OCEAN) {
adjc_iterate(&(wld.map), ptile, tile2) {
Continent_id cont2 = tile_continent(tile2);
if (is_ocean_tile(tile2)) {
if (lake_surrounders[-cont2] == 0) {
lake_surrounders[-cont2] = cont;
} else if (lake_surrounders[-cont2] != cont) {
lake_surrounders[-cont2] = -1;
}
}
if (is_ocean(pterrain)) {
fc_assert_action(cont < 0, continue);
adjc_iterate(&(wld.map), ptile, adj_tile) {
Continent_id adj_cont = tile_continent(adj_tile);
if (!is_ocean_tile(adj_tile)) {
fc_assert_action(adj_cont > 0, continue);
if (island_surrounders[adj_cont] == 0) {
island_surrounders[adj_cont] = -cont;
} else if (island_surrounders[adj_cont] != -cont) {
island_surrounders[adj_cont] = -1;
}
}
} adjc_iterate_end;
} else {
fc_assert_action(cont > 0, continue);
adjc_iterate(&(wld.map), ptile, adj_tile) {
Continent_id adj_cont = tile_continent(adj_tile);
if (is_ocean_tile(adj_tile)) {
fc_assert_action(adj_cont < 0, continue);
if (lake_surrounders[-adj_cont] == 0) {
lake_surrounders[-adj_cont] = cont;
} else if (lake_surrounders[-adj_cont] != cont) {
lake_surrounders[-adj_cont] = -1;
}
}
} adjc_iterate_end;
}
} whole_map_iterate_end;
......
/**********************************************************************//**
Regenerate all oceanic tiles for small water bodies as lakes.
Assumes assign_continent_numbers() and recalculate_lake_surrounders()
have already been done!
Assumes assign_continent_numbers() has already been called!
FIXME: insufficiently generalized, use terrain property.
**************************************************************************/
void regenerate_lakes(void)
......
/**********************************************************************//**
Get continent surrounding lake, or -1 if there is multiple continents.
**************************************************************************/
int get_lake_surrounders(Continent_id cont)
int get_lake_surrounders(Continent_id id)
{
return lake_surrounders[-cont];
fc_assert_ret_val(id < 0, -1);
return lake_surrounders[-id];
}
/**********************************************************************//**
Get ocean surrounding island, or +1 if there are multiple oceans.
**************************************************************************/
int get_island_surrounders(Continent_id id)
{
fc_assert_ret_val(id > 0, -1);
return -island_surrounders[id];
}
/**********************************************************************//**
......
/**********************************************************************//**
Assigns continent and ocean numbers to all tiles, and set
map.num_continents and map.num_oceans. Recalculates continent and
ocean sizes, and lake_surrounders[] arrays.
ocean sizes, and lake_surrounders[] and island_surrounders[] arrays.
Continents have numbers 1 to map.num_continents _inclusive_.
Oceans have (negative) numbers -1 to -map.num_oceans _inclusive_.
......
}
} whole_map_iterate_end;
recalculate_lake_surrounders();
recalculate_surrounders();
log_verbose("Map has %d continents and %d oceans",
wld.map.num_continents, wld.map.num_oceans);
......
free(lake_surrounders);
lake_surrounders = NULL;
}
if (island_surrounders != NULL) {
free(island_surrounders);
island_surrounders = NULL;
}
if (continent_sizes != NULL) {
free(continent_sizes);
continent_sizes = NULL;
server/generator/mapgen_utils.h
void regenerate_lakes(void);
void smooth_water_depth(void);
void assign_continent_numbers(void);
int get_lake_surrounders(Continent_id cont);
int get_lake_surrounders(Continent_id id);
int get_island_surrounders(Continent_id id);
int get_continent_size(Continent_id id);
int get_ocean_size(Continent_id id);
server/maphand.c
#include "maphand.h"
#define MAXIMUM_CLAIMED_OCEAN_SIZE (20)
#define MAXIMUM_CLAIMED_LAKE_OR_ISLAND_SIZE (20)
/* Suppress send_tile_info() during game_load() */
static bool send_tile_suppressed = FALSE;
......
const struct player *pplayer,
enum vision_layer vlayer);
static bool is_claimable_ocean(struct tile *ptile, struct tile *source,
struct player *pplayer);
static bool is_tile_claimable(struct tile *ptile, struct tile *source,
struct player *pplayer);
/**********************************************************************//**
Used only in global_warming() and nuclear_winter() below.
......
claimer = tile_claimer(ptile);
if (claimer != NULL) {
/* Make sure map_claim_border() conditions are still satisfied */
if (is_ocean_tile(ptile)) {
/* Only certain water tiles are claimable */
if (!is_claimable_ocean(ptile, claimer, tile_owner(ptile))) {
map_clear_border(ptile);
}
} else {
/* Only land tiles on the same island as the border source
* are claimable */
if (tile_continent(ptile) != tile_continent(claimer)) {
map_clear_border(ptile);
}
if (!is_tile_claimable(ptile, claimer, tile_owner(ptile))) {
map_clear_border(ptile);
}
}
......
}
/**********************************************************************//**
Ocean tile can be claimed iff one of the following conditions stands:
a) it is an inland lake not larger than MAXIMUM_OCEAN_SIZE
b) it is adjacent to only one continent and not more than two ocean tiles
c) It is one tile away from a border source
d) Player knows tech with Claim_Ocean flag
e) Source itself is Oceanic tile and player knows tech with Claim_Ocean_Limited flag
The source which claims the ocean has to be placed on the correct continent.
in case a) The continent which surrounds the inland lake
in case b) The only continent which is adjacent to the tile
A tile can be claimed by a border source iff one of the following
conditions is fulfilled:
a) The tile is the border source
b) The relevant Tile_Claimable_* effect is TILE_CLAIMABLE_CONTINENT or
more, and the tile is on the same continent as the border source
c) The relevant Tile_Claimable_* effect is TILE_CLAIMABLE_CONTINENT or
more, the tile is part of an inland lake or an island not larger than
MAXIMUM_CLAIMED_LAKE_OR_ISLAND_SIZE, and the border source is on the
continent or ocean surrounding that lake or island
d) The relevant Tile_Claimable_* effect is TILE_CLAIMABLE_CONTINENT or
more, the tile is adjacent to no more than two tiles of the same
terrain class and only one contiguous continent/ocean of the other,
and the border source is on that continent or ocean
e) The relevant Tile_Claimable_* effect is TILE_CLAIMABLE_ALWAYS or more
**************************************************************************/
static bool is_claimable_ocean(struct tile *ptile, struct tile *source,
struct player *pplayer)
static bool is_tile_claimable(struct tile *ptile, struct tile *source,
struct player *pplayer)
{
Continent_id cont = tile_continent(ptile);
Continent_id source_cont = tile_continent(source);
int ocean_tiles;
int same_class_tiles, eft_value;
enum effect_type eft_type;
bool other_continent;
if (get_ocean_size(-cont) <= MAXIMUM_CLAIMED_OCEAN_SIZE
&& get_lake_surrounders(cont) == source_cont) {
if (ptile == source) {
/* Source itself is always claimable (a) */
return TRUE;
}
if (ptile == source) {
/* Source itself is always claimable. */
if ((cont < 0 && source_cont < 0) || (cont > 0 && source_cont > 0)) {
/* Same terrain class */
eft_type = EFT_TILE_CLAIMABLE_FROM_SAME;
} else {
/* Different terrain classes */
eft_type = EFT_TILE_CLAIMABLE_FROM_OTHER;
}
eft_value = get_target_bonus_effects(nullptr,
&(const struct req_context) {
.tile = ptile,
.player = pplayer,
},
&(const struct req_context) {
.tile = source,
},
eft_type);
if (eft_value < TILE_CLAIMABLE_CONTINENT) {
/* Not claimable (except a, checked above) */
return FALSE;
}
if (eft_value >= TILE_CLAIMABLE_ALWAYS) {
/* Claimable no matter adjacency or continents (e) */
return TRUE;
}
if (num_known_tech_with_flag(pplayer, TF_CLAIM_OCEAN) > 0
|| (source_cont < 0 && num_known_tech_with_flag(pplayer, TF_CLAIM_OCEAN_LIMITED) > 0)) {
if (cont == source_cont) {
/* Same continent/ocean (b) */
return TRUE;
}
if (cont < 0 && source_cont > 0
&& get_ocean_size(-cont) <= MAXIMUM_CLAIMED_LAKE_OR_ISLAND_SIZE
&& get_lake_surrounders(cont) == source_cont) {
/* Lake is claimable from the surrounding continent (c) */
return TRUE;
}
if (cont > 0 && source_cont < 0
&& get_continent_size(cont) <= MAXIMUM_CLAIMED_LAKE_OR_ISLAND_SIZE
&& get_island_surrounders(cont) == source_cont) {
/* Island is claimable from the surrounding ocean (c) */
return TRUE;
}
ocean_tiles = 0;
same_class_tiles = 0;
other_continent = FALSE;
adjc_iterate(&(wld.map), ptile, adj_tile) {
Continent_id adj_cont = tile_continent(adj_tile);
if (adj_tile == source) {
/* Water next to border source is always claimable */
return TRUE;
}
if (adj_cont == cont) {
ocean_tiles++;
same_class_tiles++;
} else if (adj_cont != source_cont) {
/* This water is adjacent to a continent different from the one
/* This tile is adjacent to a continent/ocean different from the one
* the border source is on */
other_continent = TRUE;
}
} adjc_iterate_end;
if (!other_continent && ocean_tiles <= 2) {
if (!other_continent && same_class_tiles <= 2) {
/* Bay/peninsula claimable from the surrounding continent/ocean (d) */
return TRUE;
} else {
return FALSE;
}
return FALSE;
}
/**********************************************************************//**
......
}
}
if (is_ocean_tile(dtile)) {
/* Only certain water tiles are claimable */
if (is_claimable_ocean(dtile, ptile, owner)) {
map_claim_ownership(dtile, owner, ptile, dr == 0);
}
} else {
/* Only land tiles on the same island as the border source
* are claimable */
if (tile_continent(dtile) == tile_continent(ptile)) {
map_claim_ownership(dtile, owner, ptile, dr == 0);
}
/* Only certain tiles are claimable */
if (is_tile_claimable(dtile, ptile, owner)) {
map_claim_ownership(dtile, owner, ptile, dr == 0);
}
} circle_dxyr_iterate_end;
}
server/ruleset/rscompat.c
not_enough_new_##_name_##_user_flags)
#define UTYF_LAST_USER_FLAG_3_2 UTYF_USER_FLAG_50
#define TECH_LAST_USER_FLAG_3_2 TECH_USER_7
static int first_free_unit_type_user_flag(void);
static int first_free_tech_user_flag(void);
/**********************************************************************//**
Initialize rscompat information structure
......
}
}
if (info->version < RSFORMAT_3_3) {
int first_free;
int i;
/* Some tech flags moved to the ruleset between 3.2 and 3.3.
* Add them back as user flags.
* XXX: ruleset might not need all of these, and may have enough
* flags of its own that these additional ones prevent conversion. */
const struct {
const char *name;
const char *helptxt;
} new_flags_33[] = {
{ N_("Claim_Ocean"),
N_("National borders expand freely into the ocean.") },
{ N_("Claim_Ocean_Limited"),
N_("National borders from oceanic sources expand freely.") },
};
enough_new_user_flags(new_flags_33, tech,
(TECH_USER_LAST - 1), TECH_LAST_USER_FLAG_3_2);
/* Tech flags. */
first_free = first_free_tech_user_flag() + TECH_USER_1;
for (i = 0; i < ARRAY_SIZE(new_flags_33); i++) {
if (TECH_USER_1 + MAX_NUM_USER_TECH_FLAGS <= first_free + i) {
/* Can't add the user unit type flags. */
ruleset_error(NULL, LOG_ERROR,
"Can't upgrade the ruleset. Not enough free tech "
"user flags to add user flags for the tech flags "
"that used to be hardcoded.");
return FALSE;
}
/* Shouldn't be possible for valid old ruleset to have flag names that
* clash with these ones */
if (tech_flag_id_by_name(new_flags_33[i].name, fc_strcasecmp)
!= tech_flag_id_invalid()) {
ruleset_error(NULL, LOG_ERROR,
"Ruleset had illegal user tech flag '%s'",
new_flags_33[i].name);
return FALSE;
}
set_user_tech_flag_name(first_free + i,
new_flags_33[i].name,
new_flags_33[i].helptxt);
}
}
/* No errors encountered. */
return TRUE;
}
......
void rscompat_postprocess(struct rscompat_info *info)
{
struct action_enabler *enabler;
struct effect *effect;
struct requirement e_req;
if (!info->compat_mode || info->version >= RSFORMAT_CURRENT) {
......
* thought limited by game.info.tech_leakage setting. */
effect_new(EFT_TECH_LEAKAGE, 1, nullptr);
/* Old behavior: Land tiles can always be claimed by land border sources
* on the same continent. */
effect = effect_new(EFT_TILE_CLAIMABLE_FROM_SAME,
TILE_CLAIMABLE_CONTINENT,
nullptr);
e_req = req_from_values(VUT_TERRAINCLASS, REQ_RANGE_TILE,
FALSE, TRUE, FALSE, TC_LAND);
effect_req_append(effect, e_req);
/* Old behavior: Oceanic tiles can always be claimed by adjacent oceanic
* border sources. */
effect = effect_new(EFT_TILE_CLAIMABLE_FROM_SAME,
TILE_CLAIMABLE_ALWAYS,
nullptr);
e_req = req_from_values(VUT_TERRAINCLASS, REQ_RANGE_TILE,
FALSE, TRUE, FALSE, TC_OCEAN);
effect_req_append(effect, e_req);
e_req = req_from_values(VUT_MAX_DISTANCE_SQ, REQ_RANGE_TILE,
FALSE, TRUE, FALSE, 2);
effect_req_append(effect, e_req);
/* Old behavior: Oceanic tiles can always be claimed by land border
* sources on a surrounding continent. */
effect = effect_new(EFT_TILE_CLAIMABLE_FROM_OTHER,
TILE_CLAIMABLE_CONTINENT,
nullptr);
e_req = req_from_values(VUT_TERRAINCLASS, REQ_RANGE_TILE,
FALSE, TRUE, FALSE, TC_OCEAN);
effect_req_append(effect, e_req);
/* Old behavior: Oceanic tiles can be claimed by any oceanic border
* sources with Claim_Ocean_Limited techflag. */
effect = effect_new(EFT_TILE_CLAIMABLE_FROM_SAME,
TILE_CLAIMABLE_ALWAYS,
nullptr);
e_req = req_from_values(VUT_TERRAINCLASS, REQ_RANGE_TILE,
FALSE, TRUE, FALSE, TC_OCEAN);
effect_req_append(effect, e_req);
e_req = req_from_str("TechFlag", "Player", FALSE, TRUE, FALSE,
"Claim_Ocean_Limited");
effect_req_append(effect, e_req);
/* Old behavior: Oceanic tiles can be claimed by any oceanic border
* sources with Claim_Ocean techflag. */
effect = effect_new(EFT_TILE_CLAIMABLE_FROM_SAME,
TILE_CLAIMABLE_ALWAYS,
nullptr);
e_req = req_from_values(VUT_TERRAINCLASS, REQ_RANGE_TILE,
FALSE, TRUE, FALSE, TC_OCEAN);
effect_req_append(effect, e_req);
e_req = req_from_str("TechFlag", "Player", FALSE, TRUE, FALSE,
"Claim_Ocean");
effect_req_append(effect, e_req);
/* Old behavior: Oceanic tiles can be claimed by any land border sources
* with Claim_Ocean techflag. */
effect = effect_new(EFT_TILE_CLAIMABLE_FROM_OTHER,
TILE_CLAIMABLE_ALWAYS,
nullptr);
e_req = req_from_values(VUT_TERRAINCLASS, REQ_RANGE_TILE,
FALSE, TRUE, FALSE, TC_OCEAN);
effect_req_append(effect, e_req);
e_req = req_from_str("TechFlag", "Player", FALSE, TRUE, FALSE,
"Claim_Ocean");
effect_req_append(effect, e_req);
/* Make sure that all action enablers added or modified by the
* compatibility post processing fulfills all hard action requirements. */
rscompat_enablers_add_obligatory_hard_reqs();
......
return MAX_NUM_USER_UNIT_FLAGS;
}
/**********************************************************************//**
Find and return the first unused tech user flag. If all tech
user flags are taken MAX_NUM_USER_TECH_FLAGS is returned.
**************************************************************************/
static int first_free_tech_user_flag(void)
{
int flag;
/* Find the first unused user defined tech flag. */
for (flag = 0; flag < MAX_NUM_USER_TECH_FLAGS; flag++) {
if (tech_flag_id_name_cb(flag + TECH_USER_1) == NULL) {
return flag;
}
}
/* All tech user flags are taken. */
return MAX_NUM_USER_TECH_FLAGS;
}
/**********************************************************************//**
Convert 3.2 unit type flag name to 3.3 one.
**************************************************************************/
(3-3/5)