From 9eb7abf4651567acdf75f486cdc1c7c26c8313b7 Mon Sep 17 00:00:00 2001 From: Alina Lenk Date: Sat, 11 May 2024 13:37:49 +0200 Subject: [PATCH 10/11] Unhardcode terrain-class-specific border claiming rules See RM #588 Signed-off-by: Alina Lenk --- ai/default/daieffects.c | 1 + common/tech.h | 23 ++--- data/alien/effects.ruleset | 50 ++++++++++ data/alien/techs.ruleset | 6 +- data/civ1/effects.ruleset | 41 ++++++++ data/civ1/techs.ruleset | 4 - data/civ2/effects.ruleset | 41 ++++++++ data/civ2/techs.ruleset | 4 - data/civ2civ3/effects.ruleset | 41 ++++++++ data/civ2civ3/techs.ruleset | 4 - data/classic/effects.ruleset | 41 ++++++++ data/classic/techs.ruleset | 4 - data/goldkeep/effects.ruleset | 41 ++++++++ data/goldkeep/techs.ruleset | 4 - data/granularity/effects.ruleset | 41 ++++++++ data/granularity/techs.ruleset | 4 - data/multiplayer/effects.ruleset | 41 ++++++++ data/multiplayer/techs.ruleset | 4 - data/ruledit/comments-3.3.txt | 4 - data/sandbox/effects.ruleset | 41 ++++++++ data/sandbox/techs.ruleset | 4 - data/stub/techs.ruleset | 4 - data/webperimental/effects.ruleset | 41 ++++++++ data/webperimental/techs.ruleset | 4 - doc/README.effects | 5 + gen_headers/enums/effects_enums.def | 1 + server/maphand.c | 93 ++++------------- server/ruleset/rscompat.c | 150 ++++++++++++++++++++++++++++ 28 files changed, 606 insertions(+), 136 deletions(-) diff --git a/ai/default/daieffects.c b/ai/default/daieffects.c index bc91e7b406..9dcfbfdff6 100644 --- a/ai/default/daieffects.c +++ b/ai/default/daieffects.c @@ -612,6 +612,7 @@ adv_want dai_effect_value(struct player *pplayer, case EFT_UNIT_SHIELD_VALUE_PCT: case EFT_NUKE_BLAST_RADIUS_1_SQ: case EFT_HEAL_UNIT_PCT: + case EFT_TILE_CLAIMABLE: break; /* This has no effect for AI */ case EFT_VISIBLE_WALLS: diff --git a/common/tech.h b/common/tech.h index ff4c70ec42..f5fbd5303b 100644 --- a/common/tech.h +++ b/common/tech.h @@ -84,20 +84,15 @@ typedef int Tech_type_id; /* 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 diff --git a/data/alien/effects.ruleset b/data/alien/effects.ruleset index 4849b32697..753b467dca 100644 --- a/data/alien/effects.ruleset +++ b/data/alien/effects.ruleset @@ -1165,3 +1165,53 @@ reqs = { "type", "name", "range", "present" "Action", "Upgrade Unit", "Local", TRUE } + +[effect_claim_land] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" + "TerrainClass", "Land", "Tile" + "TileRel", "Same Region", "Tile" + } + +[effect_claim_ocean_adj] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" + "TerrainClass", "Oceanic", "Tile" + "MaxDistanceSq", "2", "Tile" + } + +[effect_claim_ocean_lake] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" + "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "20", "Continent" + "TileRel", "Region Surrounded", "Tile" +; implicit with Region Surrounded +; "TileRel", "Same Terrain Class", "Tile", FALSE + } + +[effect_claim_ocean_from_land_bay] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range", "present" + "TerrainClass", "Oceanic", "Tile", TRUE + "TileRel", "Same Terrain Class", "Tile", FALSE + "MaxRegionTiles", "3", "Adjacent", TRUE + "TileRel", "Only Other Region", "Adjacent", TRUE + } + +[effect_claim_ocean_tech] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" + "TerrainClass", "Oceanic", "Tile" + "Tech", "Ocean Cities", "Player" + } diff --git a/data/alien/techs.ruleset b/data/alien/techs.ruleset index 690add0d4f..e160ffcf0e 100644 --- a/data/alien/techs.ruleset +++ b/data/alien/techs.ruleset @@ -111,10 +111,6 @@ format_version = 40 ; 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 @@ -530,7 +526,7 @@ Increases max tax/science/lux rate by 10%.") 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?") diff --git a/data/civ1/effects.ruleset b/data/civ1/effects.ruleset index d077d151b0..14f888aa9e 100644 --- a/data/civ1/effects.ruleset +++ b/data/civ1/effects.ruleset @@ -1597,3 +1597,44 @@ reqs = { "type", "name", "range", "present" "Action", "Disband Unit Recover", "Local", TRUE } + +; Note: There are no oceanic border sources, so we don't need to check +; the tiles' terrain class +[effect_claim_land] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Land", "Tile" + "TileRel", "Same Region", "Tile" + } + +[effect_claim_ocean_adj] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxDistanceSq", "2", "Tile" + } + +[effect_claim_ocean_lake] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "20", "Continent" + "TileRel", "Region Surrounded", "Tile" + } + +[effect_claim_ocean_bay] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "3", "Adjacent" + "TileRel", "Only Other Region", "Adjacent" + "TileRel", "Same Region", "Adjacent" + } diff --git a/data/civ1/techs.ruleset b/data/civ1/techs.ruleset index 71f7cf4480..d71bea1cc2 100644 --- a/data/civ1/techs.ruleset +++ b/data/civ1/techs.ruleset @@ -107,10 +107,6 @@ format_version = 40 ; 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 diff --git a/data/civ2/effects.ruleset b/data/civ2/effects.ruleset index 531b2f3652..b59a2fa588 100644 --- a/data/civ2/effects.ruleset +++ b/data/civ2/effects.ruleset @@ -2680,3 +2680,44 @@ reqs = { "type", "name", "range", "present" "Action", "Upgrade Unit", "Local", TRUE } + +; Note: There are no oceanic border sources, so we don't need to check +; the tiles' terrain class +[effect_claim_land] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Land", "Tile" + "TileRel", "Same Region", "Tile" + } + +[effect_claim_ocean_adj] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxDistanceSq", "2", "Tile" + } + +[effect_claim_ocean_lake] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "20", "Continent" + "TileRel", "Region Surrounded", "Tile" + } + +[effect_claim_ocean_bay] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "3", "Adjacent" + "TileRel", "Only Other Region", "Adjacent" + "TileRel", "Same Region", "Adjacent" + } diff --git a/data/civ2/techs.ruleset b/data/civ2/techs.ruleset index 8cc838f6af..299a392873 100644 --- a/data/civ2/techs.ruleset +++ b/data/civ2/techs.ruleset @@ -107,10 +107,6 @@ format_version = 40 ; 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 diff --git a/data/civ2civ3/effects.ruleset b/data/civ2civ3/effects.ruleset index c6363893d6..f8fbd74f79 100644 --- a/data/civ2civ3/effects.ruleset +++ b/data/civ2civ3/effects.ruleset @@ -4620,3 +4620,44 @@ reqs = { "type", "name", "range", "present" "Action", "Upgrade Unit", "Local", TRUE } + +; Note: There are no oceanic border sources, so we don't need to check +; the tiles' terrain class +[effect_claim_land] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Land", "Tile" + "TileRel", "Same Region", "Tile" + } + +[effect_claim_ocean_adj] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxDistanceSq", "2", "Tile" + } + +[effect_claim_ocean_lake] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "20", "Continent" + "TileRel", "Region Surrounded", "Tile" + } + +[effect_claim_ocean_bay] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "3", "Adjacent" + "TileRel", "Only Other Region", "Adjacent" + "TileRel", "Same Region", "Adjacent" + } diff --git a/data/civ2civ3/techs.ruleset b/data/civ2civ3/techs.ruleset index a96e1ec348..56cc119c48 100644 --- a/data/civ2civ3/techs.ruleset +++ b/data/civ2civ3/techs.ruleset @@ -107,10 +107,6 @@ format_version = 40 ; 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 diff --git a/data/classic/effects.ruleset b/data/classic/effects.ruleset index 63837c597a..5adfef3eca 100644 --- a/data/classic/effects.ruleset +++ b/data/classic/effects.ruleset @@ -2735,3 +2735,44 @@ reqs = { "type", "name", "range", "present" "Action", "Upgrade Unit", "Local", TRUE } + +; Note: There are no oceanic border sources, so we don't need to check +; the tiles' terrain class +[effect_claim_land] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Land", "Tile" + "TileRel", "Same Region", "Tile" + } + +[effect_claim_ocean_adj] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxDistanceSq", "2", "Tile" + } + +[effect_claim_ocean_lake] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "20", "Continent" + "TileRel", "Region Surrounded", "Tile" + } + +[effect_claim_ocean_bay] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "3", "Adjacent" + "TileRel", "Only Other Region", "Adjacent" + "TileRel", "Same Region", "Adjacent" + } diff --git a/data/classic/techs.ruleset b/data/classic/techs.ruleset index 6d0ee0470f..1d1e9a5f75 100644 --- a/data/classic/techs.ruleset +++ b/data/classic/techs.ruleset @@ -107,10 +107,6 @@ format_version = 40 ; 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 diff --git a/data/goldkeep/effects.ruleset b/data/goldkeep/effects.ruleset index aed07e90b8..7082177574 100644 --- a/data/goldkeep/effects.ruleset +++ b/data/goldkeep/effects.ruleset @@ -3076,3 +3076,44 @@ reqs = { "type", "name", "range", "present" "Action", "Upgrade Unit", "Local", TRUE } + +; Note: There are no oceanic border sources, so we don't need to check +; the tiles' terrain class +[effect_claim_land] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Land", "Tile" + "TileRel", "Same Region", "Tile" + } + +[effect_claim_ocean_adj] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxDistanceSq", "2", "Tile" + } + +[effect_claim_ocean_lake] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "20", "Continent" + "TileRel", "Region Surrounded", "Tile" + } + +[effect_claim_ocean_bay] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "3", "Adjacent" + "TileRel", "Only Other Region", "Adjacent" + "TileRel", "Same Region", "Adjacent" + } diff --git a/data/goldkeep/techs.ruleset b/data/goldkeep/techs.ruleset index 8c43367be8..5656c3a52f 100644 --- a/data/goldkeep/techs.ruleset +++ b/data/goldkeep/techs.ruleset @@ -109,10 +109,6 @@ format_version = 40 ; 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 diff --git a/data/granularity/effects.ruleset b/data/granularity/effects.ruleset index a8cfebde00..bf9d1c70cd 100644 --- a/data/granularity/effects.ruleset +++ b/data/granularity/effects.ruleset @@ -631,3 +631,44 @@ reqs = { "type", "name", "range" "Extra", "Mine", "Tile" } + +[effect_claim_land] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" + "TerrainClass", "Land", "Tile" + "TileRel", "Same Region", "Tile" + } + +[effect_claim_ocean_adj] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" + "TerrainClass", "Oceanic", "Tile" + "MaxDistanceSq", "2", "Tile" + } + +[effect_claim_ocean_lake] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" + "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "20", "Continent" + "TileRel", "Region Surrounded", "Tile" +; implicit with Region Surrounded +; "TileRel", "Same Terrain Class", "Tile", FALSE + } + +[effect_claim_ocean_from_land_bay] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range", "present" + "TerrainClass", "Oceanic", "Tile", TRUE + "TileRel", "Same Terrain Class", "Tile", FALSE + "MaxRegionTiles", "3", "Adjacent", TRUE + "TileRel", "Only Other Region", "Adjacent", TRUE + } diff --git a/data/granularity/techs.ruleset b/data/granularity/techs.ruleset index 2df9431ef3..2d0e2d057a 100644 --- a/data/granularity/techs.ruleset +++ b/data/granularity/techs.ruleset @@ -107,10 +107,6 @@ format_version = 40 ; 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 diff --git a/data/multiplayer/effects.ruleset b/data/multiplayer/effects.ruleset index ceb6819e80..60370eb803 100644 --- a/data/multiplayer/effects.ruleset +++ b/data/multiplayer/effects.ruleset @@ -2774,3 +2774,44 @@ reqs = { "type", "name", "range", "present" "Action", "Upgrade Unit", "Local", TRUE } + +; Note: There are no oceanic border sources, so we don't need to check +; the tiles' terrain class +[effect_claim_land] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Land", "Tile" + "TileRel", "Same Region", "Tile" + } + +[effect_claim_ocean_adj] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxDistanceSq", "2", "Tile" + } + +[effect_claim_ocean_lake] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "20", "Continent" + "TileRel", "Region Surrounded", "Tile" + } + +[effect_claim_ocean_bay] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "3", "Adjacent" + "TileRel", "Only Other Region", "Adjacent" + "TileRel", "Same Region", "Adjacent" + } diff --git a/data/multiplayer/techs.ruleset b/data/multiplayer/techs.ruleset index c83d4c73ed..5aa6012de4 100644 --- a/data/multiplayer/techs.ruleset +++ b/data/multiplayer/techs.ruleset @@ -107,10 +107,6 @@ format_version = 40 ; 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 diff --git a/data/ruledit/comments-3.3.txt b/data/ruledit/comments-3.3.txt index 87218b0e0e..28bfb144b5 100644 --- a/data/ruledit/comments-3.3.txt +++ b/data/ruledit/comments-3.3.txt @@ -160,10 +160,6 @@ techs = "\ ; 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\ " diff --git a/data/sandbox/effects.ruleset b/data/sandbox/effects.ruleset index 16fe45dabd..cba611fb40 100644 --- a/data/sandbox/effects.ruleset +++ b/data/sandbox/effects.ruleset @@ -5425,3 +5425,44 @@ reqs = "Counter", "Turn_Owned2", "City", TRUE "Counter", "Turn_of_Celebration", "City", TRUE } + +; Note: There are no oceanic border sources, so we don't need to check +; the tiles' terrain class +[effect_claim_land] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Land", "Tile" + "TileRel", "Same Region", "Tile" + } + +[effect_claim_ocean_adj] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxDistanceSq", "2", "Tile" + } + +[effect_claim_ocean_lake] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "20", "Continent" + "TileRel", "Region Surrounded", "Tile" + } + +[effect_claim_ocean_bay] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "3", "Adjacent" + "TileRel", "Only Other Region", "Adjacent" + "TileRel", "Same Region", "Adjacent" + } diff --git a/data/sandbox/techs.ruleset b/data/sandbox/techs.ruleset index e38a755b5b..9e759bc52d 100644 --- a/data/sandbox/techs.ruleset +++ b/data/sandbox/techs.ruleset @@ -107,10 +107,6 @@ format_version = 40 ; 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 diff --git a/data/stub/techs.ruleset b/data/stub/techs.ruleset index b63468e719..6d93023143 100644 --- a/data/stub/techs.ruleset +++ b/data/stub/techs.ruleset @@ -101,10 +101,6 @@ format_version = 40 ; 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 diff --git a/data/webperimental/effects.ruleset b/data/webperimental/effects.ruleset index e9f056e8ff..e901f7e126 100644 --- a/data/webperimental/effects.ruleset +++ b/data/webperimental/effects.ruleset @@ -3021,3 +3021,44 @@ reqs = { "type", "name", "range", "present" "Action", "Upgrade Unit", "Local", TRUE } + +; Note: There are no oceanic border sources, so we don't need to check +; the tiles' terrain class +[effect_claim_land] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Land", "Tile" + "TileRel", "Same Region", "Tile" + } + +[effect_claim_ocean_adj] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxDistanceSq", "2", "Tile" + } + +[effect_claim_ocean_lake] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "20", "Continent" + "TileRel", "Region Surrounded", "Tile" + } + +[effect_claim_ocean_bay] +type = "Tile_Claimable" +value = 1 +reqs = + { "type", "name", "range" +; "TerrainClass", "Oceanic", "Tile" + "MaxRegionTiles", "3", "Adjacent" + "TileRel", "Only Other Region", "Adjacent" + "TileRel", "Same Region", "Adjacent" + } diff --git a/data/webperimental/techs.ruleset b/data/webperimental/techs.ruleset index f6460f2468..266c9cf373 100644 --- a/data/webperimental/techs.ruleset +++ b/data/webperimental/techs.ruleset @@ -107,10 +107,6 @@ format_version = 40 ; 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 diff --git a/doc/README.effects b/doc/README.effects index 30be2bbb50..4c327081fd 100644 --- a/doc/README.effects +++ b/doc/README.effects @@ -727,6 +727,11 @@ Thiefs_Share_Pm "Steal Gold Escape" actions that is lost before it reaches the player ordering it. Evaluated against the actor unit. +Tile_Claimable + A positive value means national borders can expand to this tile from a + border source (city or base). The border source's tile is used as the + other tile for requirements that depend on two tiles. + Tile_Workable If value > 0, city can work target tile. diff --git a/gen_headers/enums/effects_enums.def b/gen_headers/enums/effects_enums.def index 73d08870de..be60940a62 100644 --- a/gen_headers/enums/effects_enums.def +++ b/gen_headers/enums/effects_enums.def @@ -163,6 +163,7 @@ values TECH_LEAKAGE "Tech_Leakage" IMPR_UPKEEP_REDUCTION "Impr_Upkeep_Reduction" CULTURE_PCT "Culture_Pct" + TILE_CLAIMABLE "Tile_Claimable" USER_EFFECT_1 "User_Effect_1" USER_EFFECT_2 "User_Effect_2" USER_EFFECT_3 "User_Effect_3" diff --git a/server/maphand.c b/server/maphand.c index 75f493d0a5..95c5a6c40e 100644 --- a/server/maphand.c +++ b/server/maphand.c @@ -59,8 +59,6 @@ #include "maphand.h" -#define MAXIMUM_CLAIMED_OCEAN_SIZE (20) - /* Suppress send_tile_info() during game_load() */ static bool send_tile_suppressed = FALSE; @@ -87,8 +85,8 @@ static inline bool map_is_also_seen(const struct tile *ptile, 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. @@ -2071,17 +2069,8 @@ void check_terrain_change(struct tile *ptile, struct terrain *oldter) 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); } } @@ -2089,60 +2078,26 @@ void check_terrain_change(struct tile *ptile, struct terrain *oldter) } /**********************************************************************//** - 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 the tile itself is the + border source or the Tile_Claimable effect is positive **************************************************************************/ -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; - bool other_continent; - - if (get_ocean_size(-cont) <= MAXIMUM_CLAIMED_OCEAN_SIZE - && get_lake_surrounder(cont) == source_cont) { - return TRUE; - } - if (ptile == source) { /* Source itself is always claimable. */ 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)) { - return TRUE; - } - - ocean_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++; - } else if (adj_cont != source_cont) { - /* This water is adjacent to a continent different from the one - * the border source is on */ - other_continent = TRUE; - } - } adjc_iterate_end; - if (!other_continent && ocean_tiles <= 2) { - return TRUE; - } else { - return FALSE; - } + return 0 < get_target_bonus_effects(nullptr, + &(const struct req_context) { + .tile = ptile, + .player = pplayer, + }, + &(const struct req_context) { + .tile = source, + }, + EFT_TILE_CLAIMABLE); } /**********************************************************************//** @@ -2357,17 +2312,9 @@ void map_claim_border(struct tile *ptile, struct player *owner, } } - 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; } diff --git a/server/ruleset/rscompat.c b/server/ruleset/rscompat.c index 72fef173e4..f58b580521 100644 --- a/server/ruleset/rscompat.c +++ b/server/ruleset/rscompat.c @@ -41,6 +41,8 @@ #include "rscompat.h" +#define MAXIMUM_CLAIMED_OCEAN_SIZE_3_2 (20) + #define enough_new_user_flags(_new_flags_, _name_, \ _LAST_USER_FLAG_, _LAST_USER_FLAG_PREV_) \ FC_STATIC_ASSERT((ARRAY_SIZE(_new_flags_) \ @@ -48,8 +50,10 @@ FC_STATIC_ASSERT((ARRAY_SIZE(_new_flags_) \ 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 @@ -386,6 +390,54 @@ bool rscompat_names(struct rscompat_info *info) } } + 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; } @@ -405,6 +457,7 @@ static bool effect_list_compat_cb(struct effect *peffect, void *data) 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) { @@ -441,6 +494,84 @@ void rscompat_postprocess(struct rscompat_info *info) * thought limited by game.info.tech_leakage setting. */ effect_new(EFT_TECH_LEAKAGE, 1, nullptr); + /* Old behavior: Land tiles can be claimed by land border sources on the + * same continent. */ + effect = effect_new(EFT_TILE_CLAIMABLE, 1, nullptr); + e_req = req_from_values(VUT_TERRAINCLASS, REQ_RANGE_TILE, + FALSE, TRUE, FALSE, TC_LAND); + effect_req_append(effect, e_req); + e_req = req_from_values(VUT_TILE_REL, REQ_RANGE_TILE, + FALSE, TRUE, FALSE, TREL_SAME_REGION); + effect_req_append(effect, e_req); + /* Tile-range TREL_SAME_REGION implies TREL_SAME_TCLASS */ + + /* Old behavior: Oceanic tiles can be claimed by adjacent border + * sources. */ + effect = effect_new(EFT_TILE_CLAIMABLE, 1, 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 part of an ocean that is no larger than + * MAXIMUM_CLAIMED_OCEAN_SIZE tiles and that is adjacent to only one + * continent (i.e. surrounded by it) can be claimed by land border + * sources on that continent. */ + effect = effect_new(EFT_TILE_CLAIMABLE, 1, 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_REGION_TILES, REQ_RANGE_CONTINENT, + FALSE, TRUE, FALSE, + MAXIMUM_CLAIMED_OCEAN_SIZE_3_2); + effect_req_append(effect, e_req); + e_req = req_from_values(VUT_TILE_REL, REQ_RANGE_TILE, + FALSE, TRUE, FALSE, TREL_REGION_SURROUNDED); + effect_req_append(effect, e_req); + /* Tile-range TREL_REGION_SURROUNDED implies negated TREL_SAME_TCLASS */ + + /* Old behavior: Oceanic tiles adjacent to no more than two other oceanic + * tiles and (individually) adjacent to only a single continent can be + * claimed by land border sources on that continent. */ + effect = effect_new(EFT_TILE_CLAIMABLE, 1, 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_TILE_REL, REQ_RANGE_TILE, + FALSE, FALSE, FALSE, TREL_SAME_TCLASS); + effect_req_append(effect, e_req); + e_req = req_from_values(VUT_MAX_REGION_TILES, REQ_RANGE_ADJACENT, + FALSE, TRUE, FALSE, 2 + 1); + effect_req_append(effect, e_req); + e_req = req_from_values(VUT_TILE_REL, REQ_RANGE_ADJACENT, + FALSE, TRUE, FALSE, TREL_ONLY_OTHER_REGION); + effect_req_append(effect, e_req); + + /* Old behavior: Oceanic tiles can be claimed by any oceanic border + * sources with the Claim_Ocean_Limited techflag. */ + effect = effect_new(EFT_TILE_CLAIMABLE, 1, 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_TILE_REL, REQ_RANGE_TILE, + FALSE, TRUE, FALSE, TREL_SAME_TCLASS); + 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 border sources + * with the Claim_Ocean techflag. */ + effect = effect_new(EFT_TILE_CLAIMABLE, 1, 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(); @@ -473,6 +604,25 @@ static int first_free_unit_type_user_flag(void) 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) == nullptr) { + 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. **************************************************************************/ -- 2.34.1