mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-28 21:58:54 +07:00
Regions part 3 - resource placement, resource settings (#5690)
* placeLuxuries * map resource settings * strategic and bonus resources * terrain fixes * slight optimizations * vanilla jsons * fix luxury terrain distribution * also for vanilla * fix ruleset bug * terrainfilter
This commit is contained in:
@ -15,7 +15,8 @@
|
||||
"movementCost": 1,
|
||||
"RGB": [107,167,193],
|
||||
"uniques": ["[+2] to Fertility for Map Generation",
|
||||
"Considered [Desirable] when determining start locations <on water maps>"]
|
||||
"Considered [Desirable] when determining start locations <on water maps>",
|
||||
"Every [60] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Grassland",
|
||||
@ -39,7 +40,8 @@
|
||||
"Considered [Food] when determining start locations <in [Forest] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Hill] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Grassland] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Hybrid] Regions>"]
|
||||
"Considered [Food] when determining start locations <in [Hybrid] Regions>",
|
||||
"Every [33] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Plains",
|
||||
@ -67,7 +69,8 @@
|
||||
"Considered [Food] when determining start locations <in [Desert] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Hill] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Plains] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Hybrid] Regions>"]
|
||||
"Considered [Food] when determining start locations <in [Hybrid] Regions>",
|
||||
"Every [33] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Tundra",
|
||||
@ -83,7 +86,8 @@
|
||||
"[+2] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [30]% [Tundra] tiles and [Snow] tiles, with priority [1]",
|
||||
"Considered [Food] when determining start locations <in [Tundra] Regions>",
|
||||
"Considered [Desirable] when determining start locations <in [Tundra] Regions>"]
|
||||
"Considered [Desirable] when determining start locations <in [Tundra] Regions>",
|
||||
"Every [16] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Desert",
|
||||
@ -97,7 +101,8 @@
|
||||
"Occurs at temperature between [0.5] and [0.6] and humidity between [0.5] and [0.7]",
|
||||
"[+1] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [25]% [Desert] tiles, with priority [4]",
|
||||
"Considered [Undesirable] when determining start locations <in all except [Desert] Regions>"]
|
||||
"Considered [Undesirable] when determining start locations <in all except [Desert] Regions>",
|
||||
"Every [13] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Lakes",
|
||||
@ -133,7 +138,9 @@
|
||||
"Occurs at temperature between [-0.7] and [-0.6] and humidity between [0] and [0.4]",
|
||||
"Occurs at temperature between [-0.6] and [-0.5] and humidity between [0] and [0.2]",
|
||||
"Always Fertility [-1] for Map Generation",
|
||||
"Considered [Undesirable] when determining start locations"]
|
||||
"Considered [Undesirable] when determining start locations",
|
||||
"Every [17] tiles with this terrain will receive a major deposit of a strategic resource.",
|
||||
"Never receives any resources <in [Hill] tiles>"]
|
||||
},
|
||||
|
||||
// Terrain features
|
||||
@ -153,8 +160,10 @@
|
||||
"[+1] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [40]% [Hill] tiles, with priority [5]",
|
||||
"Base Terrain on this tile is not counted for Region determination",
|
||||
"Starts in regions of this type receive an extra [Sheep]",
|
||||
"Considered [Desirable] when determining start locations",
|
||||
"Considered [Production] when determining start locations"]
|
||||
"Considered [Production] when determining start locations",
|
||||
"Every [22] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Forest",
|
||||
@ -176,7 +185,8 @@
|
||||
"Considered [Desirable] when determining start locations",
|
||||
"Considered [Production] when determining start locations",
|
||||
"Considered [Food] when determining start locations <in [Forest] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Tundra] Regions>"],
|
||||
"Considered [Food] when determining start locations <in [Tundra] Regions>",
|
||||
"Every [39] tiles with this terrain will receive a major deposit of a strategic resource."],
|
||||
"civilopediaText": [{"text":"A Camp can be built here without cutting it down", "link":"Improvement/Camp"}]
|
||||
},
|
||||
{
|
||||
@ -196,7 +206,8 @@
|
||||
"A Region is formed with at least [35]% [Jungle] tiles and [Forest] tiles, with priority [2]",
|
||||
"A Region can not contain more [Forest] tiles than [Jungle] tiles",
|
||||
"Considered [Food] when determining start locations <in all except [Grassland] Regions>",
|
||||
"Considered [Desirable] when determining start locations <in all except [Grassland] Regions>"]
|
||||
"Considered [Desirable] when determining start locations <in all except [Grassland] Regions>",
|
||||
"Every [33] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Marsh",
|
||||
@ -207,7 +218,8 @@
|
||||
"defenceBonus": -0.15,
|
||||
"occursOn": ["Grassland"],
|
||||
"uniques": ["Rare feature",
|
||||
"[-2] to Fertility for Map Generation"],
|
||||
"[-2] to Fertility for Map Generation",
|
||||
"Every [9] tiles with this terrain will receive a major deposit of a strategic resource."],
|
||||
"civilopediaText": [{"text":"Only Polders can be built here", "link":"Improvement/Polder"}]
|
||||
},
|
||||
{
|
||||
|
@ -6,23 +6,33 @@
|
||||
"terrainsCanBeFoundOn": ["Grassland"],
|
||||
"food": 1,
|
||||
"improvement": "Pasture",
|
||||
"improvementStats": {"production": 1}
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Generated on every [18] tiles <in [Featureless] [Grassland] tiles>",
|
||||
"Generated on every [22] tiles <in [Featureless] [Grassland] tiles> <in [Hill] Regions>"]
|
||||
},
|
||||
{
|
||||
"name": "Sheep",
|
||||
"resourceType": "Bonus",
|
||||
"terrainsCanBeFoundOn": ["Plains","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Hill"],
|
||||
"food": 1,
|
||||
"improvement": "Pasture",
|
||||
"improvementStats": {"food": 1}
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Generated on every [13] tiles <in [Hill] tiles> <in tiles without [Forest]> <in tiles without [Jungle]>",
|
||||
"Generated on every [10] tiles <in [Hill] tiles> <in tiles without [Forest]> <in tiles without [Jungle]> <in tiles without [Fresh Water]> <in [Hill] Regions>"]
|
||||
},
|
||||
{
|
||||
"name": "Deer",
|
||||
"resourceType": "Bonus",
|
||||
"terrainsCanBeFoundOn": ["Forest","Tundra"],
|
||||
"terrainsCanBeFoundOn": ["Forest","Tundra"], // Tundra only if lowland
|
||||
"food": 1,
|
||||
"improvement": "Camp",
|
||||
"improvementStats": {"production": 1}
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Generated on every [8] tiles <in [Tundra] [Forest] tiles>",
|
||||
"Generated on every [12] tiles <in [Featureless] [Tundra] tiles>",
|
||||
"Generated on every [25] tiles <in [Plains] [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Generated on every [25] tiles <in [Grassland] [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Generated on every [16] tiles <in [Featureless] [Tundra] tiles> <in [Hill] Regions>",
|
||||
"Generated on every [28] tiles <in [Forest] tiles> <in [Hill] Regions>"]
|
||||
},
|
||||
{
|
||||
"name": "Bananas",
|
||||
@ -30,23 +40,32 @@
|
||||
"terrainsCanBeFoundOn": ["Jungle"],
|
||||
"food": 1,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"food": 2,"production": -1}
|
||||
"improvementStats": {"food": 2,"production": -1},
|
||||
"uniques": ["Generated on every [14] tiles <in [Jungle] tiles>",
|
||||
"Generated on every [16] tiles <in [Jungle] tiles> <in [Hill] Regions>"]
|
||||
},
|
||||
{
|
||||
"name": "Wheat",
|
||||
"resourceType": "Bonus",
|
||||
"terrainsCanBeFoundOn": ["Plains","Flood plains","Desert"],
|
||||
"terrainsCanBeFoundOn": ["Plains","Flood plains","Desert"], // Desert only if fresh water
|
||||
"food": 1,
|
||||
"improvement": "Farm",
|
||||
"improvementStats": {"food": 1}
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Generated on every [27] tiles <in [Featureless] [Plains] tiles>",
|
||||
"Generated on every [10] tiles <in [Desert] [Fresh Water] tiles> <in tiles without [Hill]>",
|
||||
"Generated on every [20] tiles <in [Featureless] [Plains] tiles> <in [Hill] Regions>",
|
||||
"Generated on every [20] tiles <in [Fresh Water] [Desert] tiles> <in tiles without [Hill]> <in [Hill] Regions>"]
|
||||
},
|
||||
{
|
||||
"name": "Stone",
|
||||
"resourceType": "Bonus",
|
||||
"terrainsCanBeFoundOn": ["Plains","Desert","Snow"],
|
||||
"terrainsCanBeFoundOn": ["Grassland","Desert","Tundra"],
|
||||
"production": 1,
|
||||
"improvement": "Quarry",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Generated on every [20] tiles <in [Featureless] [Grassland] tiles> <in tiles without [Fresh Water]>",
|
||||
"Generated on every [15] tiles <in [Featureless] [Tundra] tiles>",
|
||||
"Generated on every [19] tiles <in [Featureless] [Desert] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Fish",
|
||||
@ -54,7 +73,8 @@
|
||||
"terrainsCanBeFoundOn": ["Coast"],
|
||||
"food": 1,
|
||||
"improvement": "Fishing Boats",
|
||||
"improvementStats": {"food": 1}
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Generated on every [10] tiles <in [Featureless] [Coast] tiles>"]
|
||||
},
|
||||
/*
|
||||
{
|
||||
@ -72,10 +92,18 @@
|
||||
"name": "Horses",
|
||||
"resourceType": "Strategic",
|
||||
"revealedBy": "Animal Husbandry",
|
||||
"terrainsCanBeFoundOn": ["Plains","Grassland","Hill","Desert"],
|
||||
"terrainsCanBeFoundOn": ["Plains","Grassland","Hill"], // Hill only if plains or grassland
|
||||
"production": 1,
|
||||
"improvement": "Pasture",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Guaranteed with Strategic Balance resource option",
|
||||
"Generated with weight [100] <in [Featureless] [Grassland] tiles>",
|
||||
"Generated with weight [100] <in [Featureless] [Plains] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Grassland] [Hill] tiles> <in tiles without [Forest]> <in tiles without [Jungle]>",
|
||||
"Minor deposits generated with weight [10] <in [Plains] [Hill] tiles> <in tiles without [Forest]> <in tiles without [Jungle]>",
|
||||
"Minor deposits generated with weight [100] <in [Featureless] [Grassland] tiles> <in [Fresh Water] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Featureless] [Grassland] tiles> <in tiles without [Fresh Water]>",
|
||||
"Minor deposits generated with weight [30] <in [Featureless] [Plains] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 4, "default": 4, "abundant": 6},
|
||||
"minorDepositAmount": {"sparse": 1, "default": 2, "abundant": 3}
|
||||
},
|
||||
@ -83,21 +111,46 @@
|
||||
"name": "Iron",
|
||||
"resourceType": "Strategic",
|
||||
"revealedBy": "Iron Working",
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Desert","Tundra","Snow","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Desert","Tundra","Snow","Hill","Marsh"],
|
||||
"production": 1,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Guaranteed with Strategic Balance resource option",
|
||||
"Generated with weight [45] <in [Featureless] [Tundra] tiles>",
|
||||
"Generated with weight [25] <in [Featureless] [Snow] tiles>",
|
||||
"Generated with weight [35] <in [Featureless] [Desert] tiles>",
|
||||
"Generated with weight [26] <in [Hill] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Marsh] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Jungle] [Hill] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Forest] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Hill] tiles> <in tiles without [Forest]> <in tiles without [Jungle]>",
|
||||
"Minor deposits generated with weight [30] <in [Featureless] [Grassland] tiles> <in tiles without [Fresh Water]>",
|
||||
"Minor deposits generated with weight [20] <in [Featureless] [Plains] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Desert] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Tundra] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Snow] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 4, "default": 6, "abundant": 9},
|
||||
"minorDepositAmount": {"sparse": 1, "default": 2, "abundant": 3}
|
||||
},
|
||||
{
|
||||
"name": "Coal",
|
||||
"resourceType": "Strategic",
|
||||
"revealedBy": "Industrialization",
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Hill"],
|
||||
"revealedBy": "Scientific Theory",
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Hill","Jungle","Forest","Marsh"],
|
||||
"production": 1,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 2},
|
||||
"uniques": ["Generated with weight [35] <in [Hill] tiles>",
|
||||
"Generated with weight [30] <in [Jungle] tiles> <in tiles without [Hill]>",
|
||||
"Generated with weight [30] <in [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Marsh] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Jungle] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Forest] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Grassland] [Hill] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Plains] [Hill] tiles>",
|
||||
"Minor deposits generated with weight [30] <in [Desert] [Hill] tiles>",
|
||||
"Minor deposits generated with weight [30] <in [Tundra] [Hill] tiles>",
|
||||
"Minor deposits generated with weight [30] <in [Snow] [Hill] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 5, "default": 7, "abundant": 10},
|
||||
"minorDepositAmount": {"sparse": 2, "default": 3, "abundant": 3}
|
||||
},
|
||||
@ -109,7 +162,18 @@
|
||||
"production": 1,
|
||||
"improvement": "Oil well",
|
||||
"improvementStats": {"production": 3},
|
||||
"uniques": ["Deposits in [Water] tiles always provide [4] resources"],
|
||||
"uniques": ["Deposits in [Coast] tiles always provide [4] resources",
|
||||
"Guaranteed with Strategic Balance resource option",
|
||||
"Generated with weight [65] <in [Marsh] tiles> <in tiles without [Hill]>",
|
||||
"Generated with weight [40] <in [Featureless] [Tundra] tiles>",
|
||||
"Generated with weight [60] <in [Featureless] [Snow] tiles>",
|
||||
"Generated with weight [65] <in [Featureless] [Desert] tiles>",
|
||||
"Generated with weight [100] <in [Featureless] [Coast] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Marsh] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Jungle] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Desert] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Featureless] [Tundra] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Featureless] [Snow] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 5, "default": 7, "abundant": 9},
|
||||
"minorDepositAmount": {"sparse": 2, "default": 3, "abundant": 3}
|
||||
},
|
||||
@ -117,10 +181,15 @@
|
||||
"name": "Aluminum",
|
||||
"resourceType": "Strategic",
|
||||
"revealedBy": "Electricity",
|
||||
"terrainsCanBeFoundOn": ["Plains","Desert","Tundra","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Desert","Tundra","Hill","Snow","Jungle"],
|
||||
"production": 1,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 2},
|
||||
"uniques": ["Generated with weight [15] <in [Featureless] [Tundra] tiles>",
|
||||
"Generated with weight [15] <in [Featureless] [Snow] tiles>",
|
||||
"Generated with weight [39] <in [Hill] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Jungle] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Desert] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 5, "default": 8, "abundant": 10},
|
||||
"minorDepositAmount": {"sparse": 2, "default": 3, "abundant": 3}
|
||||
},
|
||||
@ -128,10 +197,16 @@
|
||||
"name": "Uranium",
|
||||
"resourceType": "Strategic",
|
||||
"revealedBy": "Atomic Theory",
|
||||
"terrainsCanBeFoundOn": ["Plains","Desert","Tundra","Hill","Snow","Forest","Desert","Marsh","Grassland"],
|
||||
"terrainsCanBeFoundOn": ["Marsh","Jungle","Forest","Tundra","Snow"],
|
||||
"production": 1,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 2},
|
||||
"uniques": ["Generated with weight [35] <in [Marsh] tiles> <in tiles without [Hill]>",
|
||||
"Generated with weight [70] <in [Jungle] tiles> <in tiles without [Hill]>",
|
||||
"Generated with weight [70] <in [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Forest] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Tundra] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Snow] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 2, "default": 4, "abundant": 4},
|
||||
"minorDepositAmount": {"sparse": 1, "default": 2, "abundant": 3}
|
||||
},
|
||||
@ -144,122 +219,137 @@
|
||||
"gold": 2,
|
||||
"improvement": "Camp",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [40]",
|
||||
"Appears in [Forest] regions with weight [10]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [40] <in [Tundra] Regions>",
|
||||
"Generated with weight [10] <in [Forest] Regions>",
|
||||
"Generated near City States with weight [15]"]
|
||||
},
|
||||
{
|
||||
"name": "Cotton",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Desert"],
|
||||
"terrainsCanBeFoundOn": ["Grassland","Flood plains"],
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Desert] regions with weight [15]",
|
||||
"Appears in [Grassland] regions with weight [30]",
|
||||
"Appears in [Hybrid] regions with weight [15]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [15] <in [Desert] Regions>",
|
||||
"Generated with weight [30] <in [Grassland] Regions>",
|
||||
"Generated with weight [15] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Hill] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Dyes",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest"],
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest","Marsh"],
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [5]",
|
||||
"Appears in [Jungle] regions with weight [5]",
|
||||
"Appears in [Forest] regions with weight [30]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [5] <in [Tundra] Regions>",
|
||||
"Generated with weight [5] <in [Jungle] Regions>",
|
||||
"Generated with weight [30] <in [Forest] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Hill] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Gems",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Jungle","Grassland","Plains","Desert","Tundra","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest","Hill"],
|
||||
"gold": 3,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [5]",
|
||||
"Appears in [Jungle] regions with weight [20]",
|
||||
"Appears in [Hill] regions with weight [15]",
|
||||
"Appears in [Grassland] regions with weight [5]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [5] <in [Tundra] Regions>",
|
||||
"Generated with weight [20] <in [Jungle] Regions>",
|
||||
"Generated with weight [15] <in [Hill] Regions>",
|
||||
"Generated with weight [5] <in [Grassland] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Forest] tiles> <in tiles without [Hill]>"]
|
||||
},
|
||||
{
|
||||
"name": "Gold Ore", // Not called "Gold" in order to not conflict with siege type units for translations
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Desert","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Desert","Hill","Forest","Jungle"],
|
||||
"gold": 2,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Appears in [Desert] regions with weight [25]",
|
||||
"Appears in [Hill] regions with weight [30]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [25] <in [Desert] Regions>",
|
||||
"Generated with weight [30] <in [Hill] Regions>",
|
||||
"Generated with weight [5] <in [Plains] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Doesn't generate naturally <in [Jungle] tiles> <in tiles without [Hill]>"]
|
||||
},
|
||||
{
|
||||
"name": "Silver",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Desert","Tundra","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Hill","Forest","Jungle","Tundra","Grassland"],
|
||||
"gold": 2,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [25]",
|
||||
"Appears in [Hill] regions with weight [30]",
|
||||
"Appears in [Grassland] regions with weight [20]",
|
||||
"Appears in [Hybrid] regions with weight [10]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [25] <in [Tundra] Regions>",
|
||||
"Generated with weight [30] <in [Hill] Regions>",
|
||||
"Generated with weight [20] <in [Grassland] Regions>",
|
||||
"Generated with weight [10] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Doesn't generate naturally <in [Jungle] tiles> <in tiles without [Hill]>",
|
||||
"Doesn't generate naturally <in [Tundra] [Hill] tiles>",
|
||||
"Doesn't generate naturally <in [Grassland] [Fresh Water] tiles>",
|
||||
"Doesn't generate naturally <in [Grassland] [Hill] tiles>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Incense",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Plains","Desert"],
|
||||
"terrainsCanBeFoundOn": ["Plains","Desert","Flood plains"],
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Desert] regions with weight [35]",
|
||||
"Appears in [Plains] regions with weight [10]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [35] <in [Desert] Regions>",
|
||||
"Generated with weight [10] <in [Plains] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]"]
|
||||
},
|
||||
{
|
||||
"name": "Ivory",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Plains"],
|
||||
"terrainsCanBeFoundOn": ["Plains","Grassland"],
|
||||
"gold": 2,
|
||||
"improvement": "Camp",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Plains] regions with weight [35]",
|
||||
"Appears in [Hybrid] regions with weight [15]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [35] <in [Plains] Regions>",
|
||||
"Generated with weight [15] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Grassland] [Fresh Water] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Silk",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Forest"],
|
||||
"terrainsCanBeFoundOn": ["Forest","Jungle"],
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [5]",
|
||||
"Appears in [Forest] regions with weight [30]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [5] <in [Jungle] Regions>",
|
||||
"Generated with weight [30] <in [Forest] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]",
|
||||
"Doesn't generate naturally <in [Hill] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Spices",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest"],
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest","Marsh"],
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [30]",
|
||||
"Appears in [Forest] regions with weight [10]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Grassland] regions with weight [5]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [30] <in [Jungle] Regions>",
|
||||
"Generated with weight [10] <in [Forest] Regions>",
|
||||
"Generated with weight [5] <in [Plains] Regions>",
|
||||
"Generated with weight [5] <in [Grassland] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]",
|
||||
"Doesn't generate naturally <in [Hill] tiles>",
|
||||
"Doesn't generate naturally <in [Tundra] [Forest] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Wine",
|
||||
@ -268,32 +358,35 @@
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Plains] regions with weight [35]",
|
||||
"Appears in [Hybrid] regions with weight [15]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [35] <in [Plains] Regions>",
|
||||
"Generated with weight [15] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]"]
|
||||
},
|
||||
{
|
||||
"name": "Sugar",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Plains","Flood plains","Grassland","Marsh"],
|
||||
"terrainsCanBeFoundOn": ["Flood plains","Grassland","Marsh"],
|
||||
// Technically sugar can also be placed on lowland jungles which then *turn* into marsh.
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [20]",
|
||||
"Appears in [Desert] regions with weight [15]",
|
||||
"Appears in [Grassland] regions with weight [20]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [20] <in [Jungle] Regions>",
|
||||
"Generated with weight [15] <in [Desert] Regions>",
|
||||
"Generated with weight [20] <in [Grassland] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Grassland] tiles> <in tiles without [Fresh Water]>"]
|
||||
},
|
||||
{
|
||||
"name": "Marble",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Desert","Plains","Tundra","Hill","Grassland"],
|
||||
"terrainsCanBeFoundOn": ["Desert","Plains","Hill","Grassland"],
|
||||
"gold": 2,
|
||||
"improvement": "Quarry",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["[+15]% Production when constructing [All] wonders [in all cities]",
|
||||
"Special placement during map generation"]
|
||||
"Special placement during map generation",
|
||||
"Doesn't generate naturally <in [Grassland] [Fresh Water] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Whales",
|
||||
@ -303,13 +396,13 @@
|
||||
"gold": 1,
|
||||
"improvement": "Fishing Boats",
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [35]",
|
||||
"Appears in [Forest] regions with weight [10]",
|
||||
"Appears in [Hill] regions with weight [10]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Grassland] regions with weight [10]",
|
||||
"Appears in [Hybrid] regions with weight [20]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [35] <in [Tundra] Regions>",
|
||||
"Generated with weight [10] <in [Forest] Regions>",
|
||||
"Generated with weight [10] <in [Hill] Regions>",
|
||||
"Generated with weight [5] <in [Plains] Regions>",
|
||||
"Generated with weight [10] <in [Grassland] Regions>",
|
||||
"Generated with weight [20] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]"]
|
||||
},
|
||||
{
|
||||
"name": "Pearls",
|
||||
@ -318,14 +411,14 @@
|
||||
"gold": 2,
|
||||
"improvement": "Fishing Boats",
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [20]",
|
||||
"Appears in [Forest] regions with weight [10]",
|
||||
"Appears in [Desert] regions with weight [5]",
|
||||
"Appears in [Hill] regions with weight [15]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Grassland] regions with weight [10]",
|
||||
"Appears in [Hybrid] regions with weight [20]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [20] <in [Jungle] Regions>",
|
||||
"Generated with weight [10] <in [Forest] Regions>",
|
||||
"Generated with weight [5] <in [Desert] Regions>",
|
||||
"Generated with weight [15] <in [Hill] Regions>",
|
||||
"Generated with weight [5] <in [Plains] Regions>",
|
||||
"Generated with weight [10] <in [Grassland] Regions>",
|
||||
"Generated with weight [20] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]"]
|
||||
},
|
||||
{
|
||||
"name": "Jewelry",
|
||||
@ -338,42 +431,46 @@
|
||||
"resourceType": "Luxury",
|
||||
"gold": 2,
|
||||
"uniques": ["Can only be created by Mercantile City-States"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Citrus",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest"],
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest","Flood plains"],
|
||||
"food": 1,
|
||||
"gold": 1,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [35]",
|
||||
"Appears in [Forest] regions with weight [5]",
|
||||
"Appears in [Desert] regions with weight [5]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [35] <in [Jungle] Regions>",
|
||||
"Generated with weight [5] <in [Forest] Regions>",
|
||||
"Generated with weight [5] <in [Desert] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]",
|
||||
"Doesn't generate naturally <in [Tundra] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Copper",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Plains","Grassland","Desert","Tundra","Snow"],
|
||||
"terrainsCanBeFoundOn": ["Hill","Forest","Jungle","Grassland","Tundra"],
|
||||
"gold": 2,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 2},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [15]",
|
||||
"Appears in [Jungle] regions with weight [5]",
|
||||
"Appears in [Forest] regions with weight [5]",
|
||||
"Appears in [Desert] regions with weight [10]",
|
||||
"Appears in [Hill] regions with weight [30]",
|
||||
"Appears in [Grassland] regions with weight [20]",
|
||||
"Appears in [Hybrid] regions with weight [20]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [15] <in [Tundra] Regions>",
|
||||
"Generated with weight [5] <in [Jungle] Regions>",
|
||||
"Generated with weight [5] <in [Forest] Regions>",
|
||||
"Generated with weight [10] <in [Desert] Regions>",
|
||||
"Generated with weight [30] <in [Hill] Regions>",
|
||||
"Generated with weight [20] <in [Grassland] Regions>",
|
||||
"Generated with weight [20] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Grassland] [Fresh Water] tiles>",
|
||||
"Doesn't generate naturally <in [Jungle] tiles> <in tiles without [Hill]>",
|
||||
"Doesn't generate naturally <in [Forest] tiles> <in tiles without [Hill]> <in tiles without [Tundra]>"]
|
||||
},
|
||||
/*
|
||||
{
|
||||
"name": "Cocoa",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Jungle"],
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest"], // Forest only if flat, non-tundra
|
||||
"food": 1,
|
||||
"gold": 1,
|
||||
"improvement": "Plantation",
|
||||
@ -388,30 +485,31 @@
|
||||
"gold": 1,
|
||||
"improvement": "Fishing Boats",
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [30]",
|
||||
"Appears in [Jungle] regions with weight [5]",
|
||||
"Appears in [Forest] regions with weight [10]",
|
||||
"Appears in [Hill] regions with weight [10]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Grassland] regions with weight [20]",
|
||||
"Appears in [Hybrid] regions with weight [20]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [30] <in [Tundra] Regions>",
|
||||
"Generated with weight [5] <in [Jungle] Regions>",
|
||||
"Generated with weight [10] <in [Forest] Regions>",
|
||||
"Generated with weight [10] <in [Hill] Regions>",
|
||||
"Generated with weight [5] <in [Plains] Regions>",
|
||||
"Generated with weight [20] <in [Grassland] Regions>",
|
||||
"Generated with weight [20] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]"]
|
||||
},
|
||||
{
|
||||
"name": "Salt",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Desert","Tundra","Plains"],
|
||||
"terrainsCanBeFoundOn": ["Desert","Tundra","Plains","Forest"],
|
||||
"gold": 1,
|
||||
"food": 1,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"food": 1,"production":1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [15]",
|
||||
"Appears in [Forest] regions with weight [5]",
|
||||
"Appears in [Desert] regions with weight [15]",
|
||||
"Appears in [Hill] regions with weight [10]",
|
||||
"Appears in [Plains] regions with weight [25]",
|
||||
"Appears in [Hybrid] regions with weight [15]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [15] <in [Tundra] Regions>",
|
||||
"Generated with weight [5] <in [Forest] Regions>",
|
||||
"Generated with weight [15] <in [Desert] Regions>",
|
||||
"Generated with weight [10] <in [Hill] Regions>",
|
||||
"Generated with weight [25] <in [Plains] Regions>",
|
||||
"Generated with weight [15] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Forest] [Hill] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Truffles",
|
||||
@ -420,11 +518,13 @@
|
||||
"gold": 2,
|
||||
"improvement": "Camp",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [5]",
|
||||
"Appears in [Forest] regions with weight [30]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Grassland] regions with weight [5]",
|
||||
"Appears in [Hybrid] regions with weight [10]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [5] <in [Jungle] Regions>",
|
||||
"Generated with weight [30] <in [Forest] Regions>",
|
||||
"Generated with weight [5] <in [Plains] Regions>",
|
||||
"Generated with weight [5] <in [Grassland] Regions>",
|
||||
"Generated with weight [10] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]",
|
||||
"Doesn't generate naturally <in [Forest] [Hill] tiles>",
|
||||
"Doesn't generate naturally <in [Tundra] [Forest] tiles>"]
|
||||
}
|
||||
]
|
||||
|
@ -15,7 +15,8 @@
|
||||
"movementCost": 1,
|
||||
"RGB": [107,167,193],
|
||||
"uniques": ["[+2] to Fertility for Map Generation",
|
||||
"Considered [Desirable] when determining start locations <on water maps>"]
|
||||
"Considered [Desirable] when determining start locations <on water maps>",
|
||||
"Every [60] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Grassland",
|
||||
@ -24,13 +25,13 @@
|
||||
"movementCost": 1,
|
||||
"RGB": [97,171,58],
|
||||
"uniques": ["Occurs at temperature between [-0.4] and [0.1] and humidity between [0.2] and [0.4]",
|
||||
"Occurs at temperature between [0.1] and [0.2] and humidity between [0.3] and [0.4]",
|
||||
"Occurs at temperature between [-0.5] and [0.5] and humidity between [0.6] and [0.8]",
|
||||
"Occurs at temperature between [-0.5] and [1] and humidity between [0.9] and [1]",
|
||||
"Occurs at temperature between [0.9] and [1] and humidity between [0.2] and [0.9]",
|
||||
"Occurs at temperature between [0.8] and [0.9] and humidity between [0.6] and [0.9]",
|
||||
"Occurs at temperature between [0.7] and [0.8] and humidity between [0.7] and [0.9]",
|
||||
"Occurs at temperature between [0.6] and [0.8] and humidity between [0.4] and [0.6]",
|
||||
"Occurs at temperature between [0.1] and [0.2] and humidity between [0.3] and [0.4]",
|
||||
"Occurs at temperature between [-0.5] and [0.5] and humidity between [0.6] and [0.8]",
|
||||
"Occurs at temperature between [-0.5] and [1] and humidity between [0.9] and [1]",
|
||||
"Occurs at temperature between [0.9] and [1] and humidity between [0.2] and [0.9]",
|
||||
"Occurs at temperature between [0.8] and [0.9] and humidity between [0.6] and [0.9]",
|
||||
"Occurs at temperature between [0.7] and [0.8] and humidity between [0.7] and [0.9]",
|
||||
"Occurs at temperature between [0.6] and [0.8] and humidity between [0.4] and [0.6]",
|
||||
"[+3] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [30]% [Grassland] tiles, with priority [7]",
|
||||
"A Region can not contain more [Plains] tiles than [Grassland] tiles",
|
||||
@ -39,7 +40,8 @@
|
||||
"Considered [Food] when determining start locations <in [Forest] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Hill] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Grassland] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Hybrid] Regions>"]
|
||||
"Considered [Food] when determining start locations <in [Hybrid] Regions>",
|
||||
"Every [33] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Plains",
|
||||
@ -49,16 +51,16 @@
|
||||
"movementCost": 1,
|
||||
"RGB": [168,185,102],
|
||||
"uniques": ["Occurs at temperature between [-0.4] and [-0.1] and humidity between [0] and [0.2]",
|
||||
"Occurs at temperature between [-0.4] and [0.4] and humidity between [0.4] and [0.6]",
|
||||
"Occurs at temperature between [0.4] and [0.5] and humidity between [0.5] and [0.6]",
|
||||
"Occurs at temperature between [-0.6] and [0.7] and humidity between [0.8] and [0.9]",
|
||||
"Occurs at temperature between [-0.6] and [-0.5] and humidity between [0.9] and [1]",
|
||||
"Occurs at temperature between [0.5] and [0.7] and humidity between [0.7] and [0.8]",
|
||||
"Occurs at temperature between [0.9] and [1] and humidity between [0] and [0.2]",
|
||||
"Occurs at temperature between [0.8] and [0.9] and humidity between [0.2] and [0.6]",
|
||||
"Occurs at temperature between [0.7] and [0.8] and humidity between [0.3] and [0.4]",
|
||||
"Occurs at temperature between [0.6] and [0.8] and humidity between [0.6] and [0.7]",
|
||||
"Occurs at temperature between [0.5] and [0.7] and humidity between [0.7] and [0.8]",
|
||||
"Occurs at temperature between [-0.4] and [0.4] and humidity between [0.4] and [0.6]",
|
||||
"Occurs at temperature between [0.4] and [0.5] and humidity between [0.5] and [0.6]",
|
||||
"Occurs at temperature between [-0.6] and [0.7] and humidity between [0.8] and [0.9]",
|
||||
"Occurs at temperature between [-0.6] and [-0.5] and humidity between [0.9] and [1]",
|
||||
"Occurs at temperature between [0.5] and [0.7] and humidity between [0.7] and [0.8]",
|
||||
"Occurs at temperature between [0.9] and [1] and humidity between [0] and [0.2]",
|
||||
"Occurs at temperature between [0.8] and [0.9] and humidity between [0.2] and [0.6]",
|
||||
"Occurs at temperature between [0.7] and [0.8] and humidity between [0.3] and [0.4]",
|
||||
"Occurs at temperature between [0.6] and [0.8] and humidity between [0.6] and [0.7]",
|
||||
"Occurs at temperature between [0.5] and [0.7] and humidity between [0.7] and [0.8]",
|
||||
"[+4] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [30]% [Plains] tiles, with priority [6]",
|
||||
"A Region can not contain more [Grassland] tiles than [Plains] tiles",
|
||||
@ -67,7 +69,8 @@
|
||||
"Considered [Food] when determining start locations <in [Desert] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Hill] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Plains] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Hybrid] Regions>"]
|
||||
"Considered [Food] when determining start locations <in [Hybrid] Regions>",
|
||||
"Every [33] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Tundra",
|
||||
@ -76,14 +79,15 @@
|
||||
"movementCost": 1,
|
||||
"RGB": [189,204,191],
|
||||
"uniques": ["Occurs at temperature between [-0.9] and [-0.6] and humidity between [0.8] and [1]",
|
||||
"Occurs at temperature between [-0.8] and [-0.5] and humidity between [0.6] and [0.8]",
|
||||
"Occurs at temperature between [-0.7] and [-0.4] and humidity between [0.4] and [0.6]",
|
||||
"Occurs at temperature between [-0.6] and [-0.4] and humidity between [0.2] and [0.4]",
|
||||
"Occurs at temperature between [-0.5] and [-0.4] and humidity between [0] and [0.2]",
|
||||
"Occurs at temperature between [-0.8] and [-0.5] and humidity between [0.6] and [0.8]",
|
||||
"Occurs at temperature between [-0.7] and [-0.4] and humidity between [0.4] and [0.6]",
|
||||
"Occurs at temperature between [-0.6] and [-0.4] and humidity between [0.2] and [0.4]",
|
||||
"Occurs at temperature between [-0.5] and [-0.4] and humidity between [0] and [0.2]",
|
||||
"[+2] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [30]% [Tundra] tiles and [Snow] tiles, with priority [1]",
|
||||
"Considered [Food] when determining start locations <in [Tundra] Regions>",
|
||||
"Considered [Desirable] when determining start locations <in [Tundra] Regions>"]
|
||||
"Considered [Desirable] when determining start locations <in [Tundra] Regions>",
|
||||
"Every [16] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Desert",
|
||||
@ -91,13 +95,14 @@
|
||||
"movementCost": 1,
|
||||
"RGB": [ 230, 230, 113],
|
||||
"uniques": ["Occurs at temperature between [-0.1] and [0.9] and humidity between [0] and [0.2]",
|
||||
"Occurs at temperature between [0.1] and [0.8] and humidity between [0.2] and [0.3]",
|
||||
"Occurs at temperature between [0.2] and [0.7] and humidity between [0.3] and [0.4]",
|
||||
"Occurs at temperature between [0.4] and [0.6] and humidity between [0.4] and [0.5]",
|
||||
"Occurs at temperature between [0.5] and [0.6] and humidity between [0.5] and [0.7]",
|
||||
"Occurs at temperature between [0.1] and [0.8] and humidity between [0.2] and [0.3]",
|
||||
"Occurs at temperature between [0.2] and [0.7] and humidity between [0.3] and [0.4]",
|
||||
"Occurs at temperature between [0.4] and [0.6] and humidity between [0.4] and [0.5]",
|
||||
"Occurs at temperature between [0.5] and [0.6] and humidity between [0.5] and [0.7]",
|
||||
"[+1] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [25]% [Desert] tiles, with priority [4]",
|
||||
"Considered [Undesirable] when determining start locations <in all except [Desert] Regions>"]
|
||||
"Considered [Undesirable] when determining start locations <in all except [Desert] Regions>",
|
||||
"Every [13] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Lakes",
|
||||
@ -106,8 +111,8 @@
|
||||
"gold": 1,
|
||||
"RGB": [ 123, 202, 226],
|
||||
"uniques": ["Fresh water",
|
||||
"Considered [Food] when determining start locations",
|
||||
"Considered [Desirable] when determining start locations"]
|
||||
"Considered [Food] when determining start locations",
|
||||
"Considered [Desirable] when determining start locations"]
|
||||
},
|
||||
{
|
||||
"name": "Mountain",
|
||||
@ -116,11 +121,11 @@
|
||||
"defenceBonus": 0.25,
|
||||
"RGB": [120, 120, 120],
|
||||
"uniques": ["Rough terrain",
|
||||
"Has an elevation of [4] for visibility calculations",
|
||||
"Occurs in chains at high elevations",
|
||||
"Units ending their turn on this terrain take [50] damage",
|
||||
"Always Fertility [-2] for Map Generation",
|
||||
"Considered [Undesirable] when determining start locations"]
|
||||
"Has an elevation of [4] for visibility calculations",
|
||||
"Occurs in chains at high elevations",
|
||||
"Units ending their turn on this terrain take [50] damage",
|
||||
"Always Fertility [-2] for Map Generation",
|
||||
"Considered [Undesirable] when determining start locations"]
|
||||
},
|
||||
{
|
||||
"name": "Snow",
|
||||
@ -128,12 +133,14 @@
|
||||
"movementCost": 1,
|
||||
"RGB": [231, 242, 249],
|
||||
"uniques": ["Occurs at temperature between [-1] and [-0.9] and humidity between [0] and [1]",
|
||||
"Occurs at temperature between [-0.9] and [-0.8] and humidity between [0] and [0.8]",
|
||||
"Occurs at temperature between [-0.8] and [-0.7] and humidity between [0] and [0.6]",
|
||||
"Occurs at temperature between [-0.7] and [-0.6] and humidity between [0] and [0.4]",
|
||||
"Occurs at temperature between [-0.6] and [-0.5] and humidity between [0] and [0.2]",
|
||||
"Occurs at temperature between [-0.9] and [-0.8] and humidity between [0] and [0.8]",
|
||||
"Occurs at temperature between [-0.8] and [-0.7] and humidity between [0] and [0.6]",
|
||||
"Occurs at temperature between [-0.7] and [-0.6] and humidity between [0] and [0.4]",
|
||||
"Occurs at temperature between [-0.6] and [-0.5] and humidity between [0] and [0.2]",
|
||||
"Always Fertility [-1] for Map Generation",
|
||||
"Considered [Undesirable] when determining start locations"]
|
||||
"Considered [Undesirable] when determining start locations",
|
||||
"Every [17] tiles with this terrain will receive a major deposit of a strategic resource.",
|
||||
"Never receives any resources <in [Hill] tiles>"]
|
||||
},
|
||||
|
||||
// Terrain features
|
||||
@ -147,14 +154,16 @@
|
||||
"RGB": [105,125,72],
|
||||
"occursOn": ["Tundra","Plains","Grassland","Desert","Snow"],
|
||||
"uniques": ["Rough terrain",
|
||||
"[+5] Strength for cities built on this terrain",
|
||||
"Has an elevation of [2] for visibility calculations",
|
||||
"Occurs in groups around high elevations",
|
||||
"[+1] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [40]% [Hill] tiles, with priority [5]",
|
||||
"Base Terrain on this tile is not counted for Region determination",
|
||||
"Considered [Desirable] when determining start locations",
|
||||
"Considered [Production] when determining start locations"]
|
||||
"[+5] Strength for cities built on this terrain",
|
||||
"Has an elevation of [2] for visibility calculations",
|
||||
"Occurs in groups around high elevations",
|
||||
"[+1] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [40]% [Hill] tiles, with priority [5]",
|
||||
"Base Terrain on this tile is not counted for Region determination",
|
||||
"Starts in regions of this type receive an extra [Sheep]",
|
||||
"Considered [Desirable] when determining start locations",
|
||||
"Considered [Production] when determining start locations",
|
||||
"Every [22] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Forest",
|
||||
@ -167,16 +176,17 @@
|
||||
"defenceBonus": 0.25,
|
||||
"occursOn": ["Tundra","Plains","Grassland","Hill"],
|
||||
"uniques": ["Rough terrain",
|
||||
"Provides a one-time Production bonus to the closest city when cut down",
|
||||
"Blocks line-of-sight from tiles at same elevation",
|
||||
"Resistant to nukes", "Can be destroyed by nukes",
|
||||
"A Region is formed with at least [30]% [Forest] tiles, with priority [3]",
|
||||
"A Region is formed with at least [35]% [Forest] tiles and [Jungle] tiles, with priority [3]",
|
||||
"A Region can not contain more [Jungle] tiles than [Forest] tiles",
|
||||
"Considered [Desirable] when determining start locations",
|
||||
"Considered [Production] when determining start locations",
|
||||
"Considered [Food] when determining start locations <in [Forest] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Tundra] Regions>"],
|
||||
"Provides a one-time Production bonus to the closest city when cut down",
|
||||
"Blocks line-of-sight from tiles at same elevation",
|
||||
"Resistant to nukes", "Can be destroyed by nukes",
|
||||
"A Region is formed with at least [30]% [Forest] tiles, with priority [3]",
|
||||
"A Region is formed with at least [35]% [Forest] tiles and [Jungle] tiles, with priority [3]",
|
||||
"A Region can not contain more [Jungle] tiles than [Forest] tiles",
|
||||
"Considered [Desirable] when determining start locations",
|
||||
"Considered [Production] when determining start locations",
|
||||
"Considered [Food] when determining start locations <in [Forest] Regions>",
|
||||
"Considered [Food] when determining start locations <in [Tundra] Regions>",
|
||||
"Every [39] tiles with this terrain will receive a major deposit of a strategic resource."],
|
||||
"civilopediaText": [{"text":"A Camp can be built here without cutting it down", "link":"Improvement/Camp"}]
|
||||
},
|
||||
{
|
||||
@ -189,14 +199,15 @@
|
||||
"defenceBonus": 0.25,
|
||||
"occursOn": ["Plains","Grassland"],
|
||||
"uniques": ["Rough terrain",
|
||||
"Blocks line-of-sight from tiles at same elevation",
|
||||
"Resistant to nukes", "Can be destroyed by nukes",
|
||||
"[-1] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [30]% [Jungle] tiles, with priority [2]",
|
||||
"A Region is formed with at least [35]% [Jungle] tiles and [Forest] tiles, with priority [2]",
|
||||
"A Region can not contain more [Forest] tiles than [Jungle] tiles",
|
||||
"Considered [Food] when determining start locations <in all except [Grassland] Regions>",
|
||||
"Considered [Desirable] when determining start locations <in all except [Grassland] Regions>"]
|
||||
"Blocks line-of-sight from tiles at same elevation",
|
||||
"Resistant to nukes", "Can be destroyed by nukes",
|
||||
"[-1] to Fertility for Map Generation",
|
||||
"A Region is formed with at least [30]% [Jungle] tiles, with priority [2]",
|
||||
"A Region is formed with at least [35]% [Jungle] tiles and [Forest] tiles, with priority [2]",
|
||||
"A Region can not contain more [Forest] tiles than [Jungle] tiles",
|
||||
"Considered [Food] when determining start locations <in all except [Grassland] Regions>",
|
||||
"Considered [Desirable] when determining start locations <in all except [Grassland] Regions>",
|
||||
"Every [33] tiles with this terrain will receive a major deposit of a strategic resource."]
|
||||
},
|
||||
{
|
||||
"name": "Marsh",
|
||||
@ -207,7 +218,8 @@
|
||||
"defenceBonus": -0.15,
|
||||
"occursOn": ["Grassland"],
|
||||
"uniques": ["Rare feature",
|
||||
"[-2] to Fertility for Map Generation"],
|
||||
"[-2] to Fertility for Map Generation",
|
||||
"Every [9] tiles with this terrain will receive a major deposit of a strategic resource."],
|
||||
"civilopediaText": [{"text":"Only Polders can be built here", "link":"Improvement/Polder"}]
|
||||
},
|
||||
{
|
||||
@ -231,10 +243,10 @@
|
||||
"defenceBonus": -0.1,
|
||||
"occursOn": ["Desert"],
|
||||
"uniques": ["Fresh water", "Rare feature",
|
||||
"Only [All Road] improvements may be built on this tile",
|
||||
"Always Fertility [4] for Map Generation",
|
||||
"Considered [Food] when determining start locations",
|
||||
"Considered [Desirable] when determining start locations"]
|
||||
"Only [All Road] improvements may be built on this tile",
|
||||
"Always Fertility [4] for Map Generation",
|
||||
"Considered [Food] when determining start locations",
|
||||
"Considered [Desirable] when determining start locations"]
|
||||
},
|
||||
{
|
||||
"name": "Flood plains",
|
||||
@ -244,8 +256,8 @@
|
||||
"defenceBonus": -0.1,
|
||||
"occursOn": ["Desert"],
|
||||
"uniques": ["Always Fertility [5] for Map Generation",
|
||||
"Considered [Food] when determining start locations",
|
||||
"Considered [Desirable] when determining start locations"]
|
||||
"Considered [Food] when determining start locations",
|
||||
"Considered [Desirable] when determining start locations"]
|
||||
},
|
||||
{
|
||||
"name": "Ice",
|
||||
@ -254,7 +266,7 @@
|
||||
"overrideStats": true,
|
||||
"occursOn": ["Ocean", "Coast"],
|
||||
"uniques": ["[-1] to Fertility for Map Generation",
|
||||
"Considered [Undesirable] when determining start locations"]
|
||||
"Considered [Undesirable] when determining start locations"]
|
||||
},
|
||||
{
|
||||
"name": "Atoll",
|
||||
@ -479,46 +491,46 @@
|
||||
"unbuildable": true,
|
||||
"weight": 10
|
||||
},
|
||||
/*
|
||||
// BNW wonders
|
||||
{
|
||||
"name": "King Solomon's Mines",
|
||||
"type": "NaturalWonder",
|
||||
"production": 6,
|
||||
"overrideStats": true,
|
||||
"occursOn": ["Plains","Desert"],
|
||||
"uniques": ["Must be adjacent to [0] [Coast] tiles",
|
||||
"Must be adjacent to [0] to [2] [Mountain] tiles"],
|
||||
"turnsInto": "Plains",
|
||||
"impassable": true,
|
||||
"unbuildable": true,
|
||||
"weight": 4
|
||||
},
|
||||
{// Will be introduced in Brave New World. Despite being a lake, it cannot be sailed on and it blocks line of sight like a mountain.
|
||||
"name": "Lake Victoria",
|
||||
"type": "NaturalWonder",
|
||||
"food": 6,
|
||||
"occursOn": ["Plains"],
|
||||
"turnsInto": "Mountain",
|
||||
"impassable": true,
|
||||
"unbuildable": true,
|
||||
"uniques": ["Fresh water","Must be adjacent to [0] [Coast] tiles"],
|
||||
"weight": 10
|
||||
},
|
||||
{
|
||||
"name": "Mount Kilimanjaro",
|
||||
"type": "NaturalWonder",
|
||||
"food": 3,
|
||||
"culture": 2,
|
||||
"occursOn": ["Plains","Grassland"],
|
||||
"turnsInto": "Mountain",
|
||||
"impassable": true,
|
||||
"unbuildable": true,
|
||||
"uniques": ["Must be adjacent to [0] [Coast] tiles",
|
||||
"Must be adjacent to [2] to [6] [Hill] tiles",
|
||||
"Must be adjacent to [0] to [2] [Mountain] tiles",
|
||||
"Grants [Altitude Training] ([double movement and +10% Strength in hills]) to adjacent [Land] units for the rest of the game"],
|
||||
"weight": 10
|
||||
}
|
||||
*/
|
||||
/*
|
||||
// BNW wonders
|
||||
{
|
||||
"name": "King Solomon's Mines",
|
||||
"type": "NaturalWonder",
|
||||
"production": 6,
|
||||
"overrideStats": true,
|
||||
"occursOn": ["Plains","Desert"],
|
||||
"uniques": ["Must be adjacent to [0] [Coast] tiles",
|
||||
"Must be adjacent to [0] to [2] [Mountain] tiles"],
|
||||
"turnsInto": "Plains",
|
||||
"impassable": true,
|
||||
"unbuildable": true,
|
||||
"weight": 4
|
||||
},
|
||||
{// Will be introduced in Brave New World. Despite being a lake, it cannot be sailed on and it blocks line of sight like a mountain.
|
||||
"name": "Lake Victoria",
|
||||
"type": "NaturalWonder",
|
||||
"food": 6,
|
||||
"occursOn": ["Plains"],
|
||||
"turnsInto": "Mountain",
|
||||
"impassable": true,
|
||||
"unbuildable": true,
|
||||
"uniques": ["Fresh water","Must be adjacent to [0] [Coast] tiles"],
|
||||
"weight": 10
|
||||
},
|
||||
{
|
||||
"name": "Mount Kilimanjaro",
|
||||
"type": "NaturalWonder",
|
||||
"food": 3,
|
||||
"culture": 2,
|
||||
"occursOn": ["Plains","Grassland"],
|
||||
"turnsInto": "Mountain",
|
||||
"impassable": true,
|
||||
"unbuildable": true,
|
||||
"uniques": ["Must be adjacent to [0] [Coast] tiles",
|
||||
"Must be adjacent to [2] to [6] [Hill] tiles",
|
||||
"Must be adjacent to [0] to [2] [Mountain] tiles",
|
||||
"Grants [Altitude Training] ([double movement and +10% Strength in hills]) to adjacent [Land] units for the rest of the game"],
|
||||
"weight": 10
|
||||
}
|
||||
*/
|
||||
]
|
||||
|
@ -6,15 +6,19 @@
|
||||
"terrainsCanBeFoundOn": ["Grassland"],
|
||||
"food": 1,
|
||||
"improvement": "Pasture",
|
||||
"improvementStats": {"production": 1}
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Generated on every [18] tiles <in [Featureless] [Grassland] tiles>",
|
||||
"Generated on every [22] tiles <in [Featureless] [Grassland] tiles> <in [Hill] Regions>"]
|
||||
},
|
||||
{
|
||||
"name": "Sheep",
|
||||
"resourceType": "Bonus",
|
||||
"terrainsCanBeFoundOn": ["Plains","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Hill"],
|
||||
"food": 1,
|
||||
"improvement": "Pasture",
|
||||
"improvementStats": {"food": 1}
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Generated on every [13] tiles <in [Hill] tiles> <in tiles without [Forest]> <in tiles without [Jungle]>",
|
||||
"Generated on every [10] tiles <in [Hill] tiles> <in tiles without [Forest]> <in tiles without [Jungle]> <in tiles without [Fresh Water]> <in [Hill] Regions>"]
|
||||
},
|
||||
{
|
||||
"name": "Deer",
|
||||
@ -22,7 +26,13 @@
|
||||
"terrainsCanBeFoundOn": ["Forest","Tundra"],
|
||||
"food": 1,
|
||||
"improvement": "Camp",
|
||||
"improvementStats": {"production": 1}
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Generated on every [8] tiles <in [Tundra] [Forest] tiles>",
|
||||
"Generated on every [12] tiles <in [Featureless] [Tundra] tiles>",
|
||||
"Generated on every [25] tiles <in [Plains] [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Generated on every [25] tiles <in [Grassland] [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Generated on every [16] tiles <in [Featureless] [Tundra] tiles> <in [Hill] Regions>",
|
||||
"Generated on every [28] tiles <in [Forest] tiles> <in [Hill] Regions>"]
|
||||
},
|
||||
{
|
||||
"name": "Bananas",
|
||||
@ -30,7 +40,9 @@
|
||||
"terrainsCanBeFoundOn": ["Jungle"],
|
||||
"food": 1,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"food": 2,"production": -1}
|
||||
"improvementStats": {"food": 2,"production": -1},
|
||||
"uniques": ["Generated on every [14] tiles <in [Jungle] tiles>",
|
||||
"Generated on every [16] tiles <in [Jungle] tiles> <in [Hill] Regions>"]
|
||||
},
|
||||
{
|
||||
"name": "Wheat",
|
||||
@ -38,15 +50,22 @@
|
||||
"terrainsCanBeFoundOn": ["Plains","Flood plains","Desert"],
|
||||
"food": 1,
|
||||
"improvement": "Farm",
|
||||
"improvementStats": {"food": 1}
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Generated on every [27] tiles <in [Featureless] [Plains] tiles>",
|
||||
"Generated on every [10] tiles <in [Desert] [Fresh Water] tiles> <in tiles without [Hill]>",
|
||||
"Generated on every [20] tiles <in [Featureless] [Plains] tiles> <in [Hill] Regions>",
|
||||
"Generated on every [20] tiles <in [Fresh Water] [Desert] tiles> <in tiles without [Hill]> <in [Hill] Regions>"]
|
||||
},
|
||||
{
|
||||
"name": "Stone",
|
||||
"resourceType": "Bonus",
|
||||
"terrainsCanBeFoundOn": ["Plains","Desert","Snow"],
|
||||
"terrainsCanBeFoundOn": ["Grassland","Desert","Tundra"],
|
||||
"production": 1,
|
||||
"improvement": "Quarry",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Generated on every [20] tiles <in [Featureless] [Grassland] tiles> <in tiles without [Fresh Water]>",
|
||||
"Generated on every [15] tiles <in [Featureless] [Tundra] tiles>",
|
||||
"Generated on every [19] tiles <in [Featureless] [Desert] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Fish",
|
||||
@ -54,7 +73,8 @@
|
||||
"terrainsCanBeFoundOn": ["Coast"],
|
||||
"food": 1,
|
||||
"improvement": "Fishing Boats",
|
||||
"improvementStats": {"food": 1}
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Generated on every [10] tiles <in [Featureless] [Coast] tiles>"]
|
||||
},
|
||||
/*
|
||||
{
|
||||
@ -72,10 +92,18 @@
|
||||
"name": "Horses",
|
||||
"resourceType": "Strategic",
|
||||
"revealedBy": "Animal Husbandry",
|
||||
"terrainsCanBeFoundOn": ["Plains","Grassland","Hill","Desert"],
|
||||
"terrainsCanBeFoundOn": ["Plains","Grassland","Hill"],
|
||||
"production": 1,
|
||||
"improvement": "Pasture",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Guaranteed with Strategic Balance resource option",
|
||||
"Generated with weight [100] <in [Featureless] [Grassland] tiles>",
|
||||
"Generated with weight [100] <in [Featureless] [Plains] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Grassland] [Hill] tiles> <in tiles without [Forest]> <in tiles without [Jungle]>",
|
||||
"Minor deposits generated with weight [10] <in [Plains] [Hill] tiles> <in tiles without [Forest]> <in tiles without [Jungle]>",
|
||||
"Minor deposits generated with weight [100] <in [Featureless] [Grassland] tiles> <in [Fresh Water] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Featureless] [Grassland] tiles> <in tiles without [Fresh Water]>",
|
||||
"Minor deposits generated with weight [30] <in [Featureless] [Plains] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 4, "default": 4, "abundant": 6},
|
||||
"minorDepositAmount": {"sparse": 1, "default": 2, "abundant": 3}
|
||||
},
|
||||
@ -83,10 +111,24 @@
|
||||
"name": "Iron",
|
||||
"resourceType": "Strategic",
|
||||
"revealedBy": "Iron Working",
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Desert","Tundra","Snow","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Desert","Tundra","Snow","Hill","Marsh"],
|
||||
"production": 1,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Guaranteed with Strategic Balance resource option",
|
||||
"Generated with weight [45] <in [Featureless] [Tundra] tiles>",
|
||||
"Generated with weight [25] <in [Featureless] [Snow] tiles>",
|
||||
"Generated with weight [35] <in [Featureless] [Desert] tiles>",
|
||||
"Generated with weight [26] <in [Hill] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Marsh] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Jungle] [Hill] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Forest] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Hill] tiles> <in tiles without [Forest]> <in tiles without [Jungle]>",
|
||||
"Minor deposits generated with weight [30] <in [Featureless] [Grassland] tiles> <in tiles without [Fresh Water]>",
|
||||
"Minor deposits generated with weight [20] <in [Featureless] [Plains] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Desert] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Tundra] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Snow] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 4, "default": 6, "abundant": 9},
|
||||
"minorDepositAmount": {"sparse": 1, "default": 2, "abundant": 3}
|
||||
},
|
||||
@ -94,10 +136,21 @@
|
||||
"name": "Coal",
|
||||
"resourceType": "Strategic",
|
||||
"revealedBy": "Scientific Theory",
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Hill","Jungle","Forest","Marsh"],
|
||||
"production": 1,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 2},
|
||||
"uniques": ["Generated with weight [35] <in [Hill] tiles>",
|
||||
"Generated with weight [30] <in [Jungle] tiles> <in tiles without [Hill]>",
|
||||
"Generated with weight [30] <in [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Marsh] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Jungle] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Forest] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Grassland] [Hill] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Plains] [Hill] tiles>",
|
||||
"Minor deposits generated with weight [30] <in [Desert] [Hill] tiles>",
|
||||
"Minor deposits generated with weight [30] <in [Tundra] [Hill] tiles>",
|
||||
"Minor deposits generated with weight [30] <in [Snow] [Hill] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 5, "default": 7, "abundant": 10},
|
||||
"minorDepositAmount": {"sparse": 2, "default": 3, "abundant": 3}
|
||||
},
|
||||
@ -109,7 +162,18 @@
|
||||
"production": 1,
|
||||
"improvement": "Oil well",
|
||||
"improvementStats": {"production": 3},
|
||||
"uniques": ["Deposits in [Water] tiles always provide [4] resources"],
|
||||
"uniques": ["Deposits in [Coast] tiles always provide [4] resources",
|
||||
"Guaranteed with Strategic Balance resource option",
|
||||
"Generated with weight [65] <in [Marsh] tiles> <in tiles without [Hill]>",
|
||||
"Generated with weight [40] <in [Featureless] [Tundra] tiles>",
|
||||
"Generated with weight [60] <in [Featureless] [Snow] tiles>",
|
||||
"Generated with weight [65] <in [Featureless] [Desert] tiles>",
|
||||
"Generated with weight [100] <in [Featureless] [Coast] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Marsh] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Jungle] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Desert] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Featureless] [Tundra] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Featureless] [Snow] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 5, "default": 7, "abundant": 9},
|
||||
"minorDepositAmount": {"sparse": 2, "default": 3, "abundant": 3}
|
||||
},
|
||||
@ -117,10 +181,15 @@
|
||||
"name": "Aluminum",
|
||||
"resourceType": "Strategic",
|
||||
"revealedBy": "Electricity",
|
||||
"terrainsCanBeFoundOn": ["Plains","Desert","Tundra","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Desert","Tundra","Hill","Snow","Jungle"],
|
||||
"production": 1,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 2},
|
||||
"uniques": ["Generated with weight [15] <in [Featureless] [Tundra] tiles>",
|
||||
"Generated with weight [15] <in [Featureless] [Snow] tiles>",
|
||||
"Generated with weight [39] <in [Hill] tiles>",
|
||||
"Minor deposits generated with weight [20] <in [Jungle] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Desert] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 5, "default": 8, "abundant": 10},
|
||||
"minorDepositAmount": {"sparse": 2, "default": 3, "abundant": 3}
|
||||
},
|
||||
@ -128,14 +197,20 @@
|
||||
"name": "Uranium",
|
||||
"resourceType": "Strategic",
|
||||
"revealedBy": "Atomic Theory",
|
||||
"terrainsCanBeFoundOn": ["Plains","Desert","Tundra","Hill","Snow","Forest","Desert","Marsh","Grassland"],
|
||||
"terrainsCanBeFoundOn": ["Marsh","Jungle","Forest","Tundra","Snow"],
|
||||
"production": 1,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 2},
|
||||
"uniques": ["Generated with weight [35] <in [Marsh] tiles> <in tiles without [Hill]>",
|
||||
"Generated with weight [70] <in [Jungle] tiles> <in tiles without [Hill]>",
|
||||
"Generated with weight [70] <in [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Minor deposits generated with weight [10] <in [Forest] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Tundra] tiles>",
|
||||
"Minor deposits generated with weight [10] <in [Featureless] [Snow] tiles>"],
|
||||
"majorDepositAmount": {"sparse": 2, "default": 4, "abundant": 4},
|
||||
"minorDepositAmount": {"sparse": 1, "default": 2, "abundant": 3}
|
||||
},
|
||||
|
||||
|
||||
// Luxury resources
|
||||
{
|
||||
"name": "Furs",
|
||||
@ -144,122 +219,137 @@
|
||||
"gold": 2,
|
||||
"improvement": "Camp",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [40]",
|
||||
"Appears in [Forest] regions with weight [10]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [40] <in [Tundra] Regions>",
|
||||
"Generated with weight [10] <in [Forest] Regions>",
|
||||
"Generated near City States with weight [15]"]
|
||||
},
|
||||
{
|
||||
"name": "Cotton",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Desert"],
|
||||
"terrainsCanBeFoundOn": ["Grassland","Flood plains"],
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Desert] regions with weight [15]",
|
||||
"Appears in [Grassland] regions with weight [30]",
|
||||
"Appears in [Hybrid] regions with weight [15]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [15] <in [Desert] Regions>",
|
||||
"Generated with weight [30] <in [Grassland] Regions>",
|
||||
"Generated with weight [15] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Hill] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Dyes",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest"],
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest","Marsh"],
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [5]",
|
||||
"Appears in [Jungle] regions with weight [5]",
|
||||
"Appears in [Forest] regions with weight [30]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [5] <in [Tundra] Regions>",
|
||||
"Generated with weight [5] <in [Jungle] Regions>",
|
||||
"Generated with weight [30] <in [Forest] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Hill] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Gems",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Jungle","Grassland","Plains","Desert","Tundra","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest","Hill"],
|
||||
"gold": 3,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [5]",
|
||||
"Appears in [Jungle] regions with weight [20]",
|
||||
"Appears in [Hill] regions with weight [15]",
|
||||
"Appears in [Grassland] regions with weight [5]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [5] <in [Tundra] Regions>",
|
||||
"Generated with weight [20] <in [Jungle] Regions>",
|
||||
"Generated with weight [15] <in [Hill] Regions>",
|
||||
"Generated with weight [5] <in [Grassland] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Forest] tiles> <in tiles without [Hill]>"]
|
||||
},
|
||||
{
|
||||
"name": "Gold Ore", // Not called "Gold" in order to not conflict with siege type units for translations
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Grassland","Plains","Desert","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Desert","Hill","Forest","Jungle"],
|
||||
"gold": 2,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Appears in [Desert] regions with weight [25]",
|
||||
"Appears in [Hill] regions with weight [30]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [25] <in [Desert] Regions>",
|
||||
"Generated with weight [30] <in [Hill] Regions>",
|
||||
"Generated with weight [5] <in [Plains] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Doesn't generate naturally <in [Jungle] tiles> <in tiles without [Hill]>"]
|
||||
},
|
||||
{
|
||||
"name": "Silver",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Desert","Tundra","Hill"],
|
||||
"terrainsCanBeFoundOn": ["Hill","Forest","Jungle","Tundra","Grassland"],
|
||||
"gold": 2,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [25]",
|
||||
"Appears in [Hill] regions with weight [30]",
|
||||
"Appears in [Grassland] regions with weight [20]",
|
||||
"Appears in [Hybrid] regions with weight [10]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [25] <in [Tundra] Regions>",
|
||||
"Generated with weight [30] <in [Hill] Regions>",
|
||||
"Generated with weight [20] <in [Grassland] Regions>",
|
||||
"Generated with weight [10] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Forest] tiles> <in tiles without [Hill]>",
|
||||
"Doesn't generate naturally <in [Jungle] tiles> <in tiles without [Hill]>",
|
||||
"Doesn't generate naturally <in [Tundra] [Hill] tiles>",
|
||||
"Doesn't generate naturally <in [Grassland] [Fresh Water] tiles>",
|
||||
"Doesn't generate naturally <in [Grassland] [Hill] tiles>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Incense",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Plains","Desert"],
|
||||
"terrainsCanBeFoundOn": ["Plains","Desert","Flood plains"],
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Desert] regions with weight [35]",
|
||||
"Appears in [Plains] regions with weight [10]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [35] <in [Desert] Regions>",
|
||||
"Generated with weight [10] <in [Plains] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]"]
|
||||
},
|
||||
{
|
||||
"name": "Ivory",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Plains"],
|
||||
"terrainsCanBeFoundOn": ["Plains","Grassland"],
|
||||
"gold": 2,
|
||||
"improvement": "Camp",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Plains] regions with weight [35]",
|
||||
"Appears in [Hybrid] regions with weight [15]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [35] <in [Plains] Regions>",
|
||||
"Generated with weight [15] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Grassland] [Fresh Water] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Silk",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Forest"],
|
||||
"terrainsCanBeFoundOn": ["Forest","Jungle"],
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [5]",
|
||||
"Appears in [Forest] regions with weight [30]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [5] <in [Jungle] Regions>",
|
||||
"Generated with weight [30] <in [Forest] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]",
|
||||
"Doesn't generate naturally <in [Hill] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Spices",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest"],
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest","Marsh"],
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [30]",
|
||||
"Appears in [Forest] regions with weight [10]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Grassland] regions with weight [5]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [30] <in [Jungle] Regions>",
|
||||
"Generated with weight [10] <in [Forest] Regions>",
|
||||
"Generated with weight [5] <in [Plains] Regions>",
|
||||
"Generated with weight [5] <in [Grassland] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]",
|
||||
"Doesn't generate naturally <in [Hill] tiles>",
|
||||
"Doesn't generate naturally <in [Tundra] [Forest] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Wine",
|
||||
@ -268,32 +358,35 @@
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Plains] regions with weight [35]",
|
||||
"Appears in [Hybrid] regions with weight [15]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [35] <in [Plains] Regions>",
|
||||
"Generated with weight [15] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]"]
|
||||
},
|
||||
{
|
||||
"name": "Sugar",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Plains","Flood plains","Grassland","Marsh"],
|
||||
"terrainsCanBeFoundOn": ["Flood plains","Grassland","Marsh"],
|
||||
// Technically sugar can also be placed on lowland jungles which then *turn* into marsh.
|
||||
"gold": 2,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [20]",
|
||||
"Appears in [Desert] regions with weight [15]",
|
||||
"Appears in [Grassland] regions with weight [20]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [20] <in [Jungle] Regions>",
|
||||
"Generated with weight [15] <in [Desert] Regions>",
|
||||
"Generated with weight [20] <in [Grassland] Regions>",
|
||||
"Generated with weight [5] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]",
|
||||
"Doesn't generate naturally <in [Grassland] tiles> <in tiles without [Fresh Water]>"]
|
||||
},
|
||||
{
|
||||
"name": "Marble",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Desert","Plains","Tundra","Hill","Grassland"],
|
||||
"terrainsCanBeFoundOn": ["Desert","Plains","Hill","Grassland"],
|
||||
"gold": 2,
|
||||
"improvement": "Quarry",
|
||||
"improvementStats": {"production": 1},
|
||||
"uniques": ["[+15]% Production when constructing [All] wonders [in all cities]",
|
||||
"Special placement during map generation"]
|
||||
"Special placement during map generation",
|
||||
"Doesn't generate naturally <in [Grassland] [Fresh Water] tiles>"]
|
||||
},
|
||||
{
|
||||
"name": "Whales",
|
||||
@ -303,13 +396,13 @@
|
||||
"gold": 1,
|
||||
"improvement": "Fishing Boats",
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [35]",
|
||||
"Appears in [Forest] regions with weight [10]",
|
||||
"Appears in [Hill] regions with weight [10]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Grassland] regions with weight [10]",
|
||||
"Appears in [Hybrid] regions with weight [20]",
|
||||
"Appears near City States with weight [10]"]
|
||||
"uniques": ["Generated with weight [35] <in [Tundra] Regions>",
|
||||
"Generated with weight [10] <in [Forest] Regions>",
|
||||
"Generated with weight [10] <in [Hill] Regions>",
|
||||
"Generated with weight [5] <in [Plains] Regions>",
|
||||
"Generated with weight [10] <in [Grassland] Regions>",
|
||||
"Generated with weight [20] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [10]"]
|
||||
},
|
||||
{
|
||||
"name": "Pearls",
|
||||
@ -318,14 +411,14 @@
|
||||
"gold": 2,
|
||||
"improvement": "Fishing Boats",
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [20]",
|
||||
"Appears in [Forest] regions with weight [10]",
|
||||
"Appears in [Desert] regions with weight [5]",
|
||||
"Appears in [Hill] regions with weight [15]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Grassland] regions with weight [10]",
|
||||
"Appears in [Hybrid] regions with weight [20]",
|
||||
"Appears near City States with weight [15]"]
|
||||
"uniques": ["Generated with weight [20] <in [Jungle] Regions>",
|
||||
"Generated with weight [10] <in [Forest] Regions>",
|
||||
"Generated with weight [5] <in [Desert] Regions>",
|
||||
"Generated with weight [15] <in [Hill] Regions>",
|
||||
"Generated with weight [5] <in [Plains] Regions>",
|
||||
"Generated with weight [10] <in [Grassland] Regions>",
|
||||
"Generated with weight [20] <in [Hybrid] Regions>",
|
||||
"Generated near City States with weight [15]"]
|
||||
},
|
||||
{
|
||||
"name": "Jewelry",
|
||||
@ -339,92 +432,4 @@
|
||||
"gold": 2,
|
||||
"uniques": ["Can only be created by Mercantile City-States"]
|
||||
}
|
||||
{
|
||||
"name": "Citrus",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Jungle","Forest"],
|
||||
"food": 1,
|
||||
"gold": 1,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [35]",
|
||||
"Appears in [Forest] regions with weight [5]",
|
||||
"Appears in [Desert] regions with weight [5]",
|
||||
"Appears in [Hybrid] regions with weight [5]",
|
||||
"Appears near City States with weight [15]"]
|
||||
},
|
||||
{
|
||||
"name": "Copper",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Plains","Grassland","Desert","Tundra","Snow"],
|
||||
"gold": 2,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"production": 2},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [15]",
|
||||
"Appears in [Jungle] regions with weight [5]",
|
||||
"Appears in [Forest] regions with weight [5]",
|
||||
"Appears in [Desert] regions with weight [10]",
|
||||
"Appears in [Hill] regions with weight [30]",
|
||||
"Appears in [Grassland] regions with weight [20]",
|
||||
"Appears in [Hybrid] regions with weight [20]",
|
||||
"Appears near City States with weight [10]"]
|
||||
},
|
||||
/*
|
||||
{
|
||||
"name": "Cocoa",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Jungle"],
|
||||
"food": 1,
|
||||
"gold": 1,
|
||||
"improvement": "Plantation",
|
||||
"improvementStats": {"food": 1,"gold": 1}
|
||||
},
|
||||
*/
|
||||
{
|
||||
"name": "Crab",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Coast"],
|
||||
"food": 1,
|
||||
"gold": 1,
|
||||
"improvement": "Fishing Boats",
|
||||
"improvementStats": {"food": 1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [30]",
|
||||
"Appears in [Jungle] regions with weight [5]",
|
||||
"Appears in [Forest] regions with weight [10]",
|
||||
"Appears in [Hill] regions with weight [10]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Grassland] regions with weight [20]",
|
||||
"Appears in [Hybrid] regions with weight [20]",
|
||||
"Appears near City States with weight [15]"]
|
||||
},
|
||||
{
|
||||
"name": "Salt",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Desert","Tundra","Plains"],
|
||||
"gold": 1,
|
||||
"food": 1,
|
||||
"improvement": "Mine",
|
||||
"improvementStats": {"food": 1,"production":1},
|
||||
"uniques": ["Appears in [Tundra] regions with weight [15]",
|
||||
"Appears in [Forest] regions with weight [5]",
|
||||
"Appears in [Desert] regions with weight [15]",
|
||||
"Appears in [Hill] regions with weight [10]",
|
||||
"Appears in [Plains] regions with weight [25]",
|
||||
"Appears in [Hybrid] regions with weight [15]",
|
||||
"Appears near City States with weight [10]"]
|
||||
},
|
||||
{
|
||||
"name": "Truffles",
|
||||
"resourceType": "Luxury",
|
||||
"terrainsCanBeFoundOn": ["Forest","Marsh","Jungle"],
|
||||
"gold": 2,
|
||||
"improvement": "Camp",
|
||||
"improvementStats": {"gold": 1},
|
||||
"uniques": ["Appears in [Jungle] regions with weight [5]",
|
||||
"Appears in [Forest] regions with weight [30]",
|
||||
"Appears in [Plains] regions with weight [5]",
|
||||
"Appears in [Grassland] regions with weight [5]",
|
||||
"Appears in [Hybrid] regions with weight [10]",
|
||||
"Appears near City States with weight [15]"]
|
||||
}
|
||||
]
|
||||
|
@ -278,9 +278,6 @@ object GameStarter {
|
||||
for (civ in gameInfo.civilizations.filter { !it.isBarbarian() && !it.isSpectator() }) {
|
||||
val startingLocation = startingLocations[civ]!!
|
||||
|
||||
if(civ.isCityState())
|
||||
addCityStateLuxury(gameInfo, startingLocation)
|
||||
|
||||
for (tile in startingLocation.getTilesInDistance(3)) {
|
||||
if (tile.improvement != null
|
||||
&& tile.getTileImprovement()!!.isAncientRuinsEquivalent()
|
||||
@ -451,28 +448,4 @@ object GameStarter {
|
||||
}
|
||||
return preferredTiles.lastOrNull() ?: freeTiles.last()
|
||||
}
|
||||
|
||||
private fun addCityStateLuxury(gameInfo: GameInfo, spawn: TileInfo) {
|
||||
// Every city state should have at least one luxury to trade
|
||||
val relevantTiles = spawn.getTilesInDistance(2).shuffled()
|
||||
|
||||
for (tile in relevantTiles) {
|
||||
if(tile.resource != null && tile.tileResource.resourceType == ResourceType.Luxury)
|
||||
return // At least one luxury; all set
|
||||
}
|
||||
|
||||
for (tile in relevantTiles) {
|
||||
// Add a luxury to the first eligible tile
|
||||
if (tile.resource != null)
|
||||
continue
|
||||
|
||||
val luxuryToAdd = gameInfo.ruleSet.tileResources.values
|
||||
.filter { it.terrainsCanBeFoundOn.contains(tile.getLastTerrain().name) && it.resourceType == ResourceType.Luxury }
|
||||
.randomOrNull()
|
||||
if (luxuryToAdd != null) {
|
||||
tile.resource = luxuryToAdd.name
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,11 +131,20 @@ object MapType {
|
||||
const val empty = "Empty"
|
||||
}
|
||||
|
||||
object MapResources {
|
||||
const val sparse = "Sparse"
|
||||
const val default = "Default"
|
||||
const val abundant = "Abundant"
|
||||
const val strategicBalance = "Strategic Balance"
|
||||
const val legendaryStart = "Legendary Start"
|
||||
}
|
||||
|
||||
class MapParameters {
|
||||
var name = ""
|
||||
var type = MapType.pangaea
|
||||
var shape = MapShape.hexagonal
|
||||
var mapSize = MapSizeNew(MapSize.Medium)
|
||||
var mapResources = MapResources.default
|
||||
var noRuins = false
|
||||
var noNaturalWonders = false
|
||||
var worldWrap = false
|
||||
@ -162,6 +171,7 @@ class MapParameters {
|
||||
it.type = type
|
||||
it.shape = shape
|
||||
it.mapSize = mapSize.clone()
|
||||
it.mapResources = mapResources
|
||||
it.noRuins = noRuins
|
||||
it.noNaturalWonders = noNaturalWonders
|
||||
it.worldWrap = worldWrap
|
||||
@ -213,6 +223,7 @@ class MapParameters {
|
||||
if (worldWrap) yield("wrapped ")
|
||||
yield(shape)
|
||||
yield(" " + displayMapDimensions())
|
||||
yield(mapResources)
|
||||
if (name.isEmpty()) return@sequence
|
||||
yield(", $type, Seed $seed, ")
|
||||
yield("$elevationExponent/$temperatureExtremeness/$resourceRichness/$vegetationRichness/")
|
||||
|
@ -530,6 +530,8 @@ open class TileInfo {
|
||||
resource -> observingCiv != null && hasViewableResource(observingCiv)
|
||||
"Water resource" -> isWater && observingCiv != null && hasViewableResource(observingCiv)
|
||||
"Natural Wonder" -> naturalWonder != null
|
||||
"Featureless" -> terrainFeatures.isEmpty()
|
||||
"Fresh Water" -> isAdjacentToFreshwater
|
||||
else -> {
|
||||
if (terrainFeatures.contains(filter)) return true
|
||||
if (hasUnique(filter)) return true
|
||||
@ -795,21 +797,30 @@ open class TileInfo {
|
||||
|
||||
fun setTileResource(newResource: TileResource, majorDeposit: Boolean = false) {
|
||||
resource = newResource.name
|
||||
|
||||
|
||||
if (newResource.resourceType != ResourceType.Strategic) return
|
||||
|
||||
|
||||
for (unique in newResource.getMatchingUniques(UniqueType.ResourceAmountOnTiles)) {
|
||||
if (matchesTerrainFilter(unique.params[0])) {
|
||||
resourceAmount = unique.params[1].toInt()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Stick to default for now
|
||||
resourceAmount = if (majorDeposit)
|
||||
newResource.majorDepositAmount.default
|
||||
else
|
||||
newResource.minorDepositAmount.default
|
||||
|
||||
resourceAmount = when (tileMap.mapParameters.mapResources) {
|
||||
MapResources.sparse -> {
|
||||
if (majorDeposit) newResource.majorDepositAmount.sparse
|
||||
else newResource.minorDepositAmount.sparse
|
||||
}
|
||||
MapResources.abundant -> {
|
||||
if (majorDeposit) newResource.majorDepositAmount.abundant
|
||||
else newResource.minorDepositAmount.abundant
|
||||
}
|
||||
else -> {
|
||||
if (majorDeposit) newResource.majorDepositAmount.default
|
||||
else newResource.minorDepositAmount.default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,7 +78,7 @@ class MapGenerator(val ruleset: Ruleset) {
|
||||
runAndMeasure("RiverGenerator") {
|
||||
RiverGenerator(map, randomness).spawnRivers()
|
||||
}
|
||||
// Region based map generation - not used when generating maps in worldbuilder
|
||||
// Region based map generation - not used when generating maps in map editor
|
||||
if (civilizations.isNotEmpty()) {
|
||||
val regions = MapRegions(ruleset)
|
||||
runAndMeasure("generateRegions") {
|
||||
@ -90,13 +90,15 @@ class MapGenerator(val ruleset: Ruleset) {
|
||||
runAndMeasure("placeResourcesAndMinorCivs") {
|
||||
regions.placeResourcesAndMinorCivs(map, civilizations.filter { ruleset.nations[it.civName]!!.isCityState() })
|
||||
}
|
||||
} else {
|
||||
// Fallback spread resources function - used when generating maps in map editor
|
||||
runAndMeasure("spreadResources") {
|
||||
spreadResources(map)
|
||||
}
|
||||
}
|
||||
runAndMeasure("NaturalWonderGenerator") {
|
||||
NaturalWonderGenerator(ruleset, randomness).spawnNaturalWonders(map)
|
||||
}
|
||||
runAndMeasure("spreadResources") {
|
||||
spreadResources(map)
|
||||
}
|
||||
runAndMeasure("spreadAncientRuins") {
|
||||
spreadAncientRuins(map)
|
||||
}
|
||||
@ -175,10 +177,8 @@ class MapGenerator(val ruleset: Ruleset) {
|
||||
|
||||
private fun spreadResources(tileMap: TileMap) {
|
||||
val mapRadius = tileMap.mapParameters.mapSize.radius
|
||||
// Commenting this out for now not to interfere with start normalization - will be restored when
|
||||
// region-based resource placement is implemented, then this function will be map editor only.
|
||||
/*for (tile in tileMap.values)
|
||||
tile.resource = null*/
|
||||
for (tile in tileMap.values)
|
||||
tile.resource = null
|
||||
|
||||
spreadStrategicResources(tileMap, mapRadius)
|
||||
spreadResources(tileMap, mapRadius, ResourceType.Luxury)
|
||||
|
@ -2,24 +2,23 @@ package com.unciv.logic.map.mapgenerator
|
||||
|
||||
import com.badlogic.gdx.math.Rectangle
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.HexMath
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.map.MapShape
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.logic.map.*
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.tile.Terrain
|
||||
import com.unciv.models.ruleset.tile.TerrainType
|
||||
import com.unciv.models.ruleset.tile.TileResource
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.translations.equalsPlaceholderText
|
||||
import com.unciv.models.translations.getPlaceholderParameters
|
||||
import com.unciv.ui.utils.randomWeighted
|
||||
import kotlin.math.*
|
||||
import kotlin.random.Random
|
||||
|
||||
class MapRegions (val ruleset: Ruleset){
|
||||
companion object {
|
||||
@ -33,10 +32,26 @@ class MapRegions (val ruleset: Ruleset){
|
||||
val secondRingFoodScores = listOf(0, 2, 5, 10, 20, 25, 28, 30, 32, 34, 35)
|
||||
val secondRingProdScores = listOf(0, 10, 20, 25, 30, 35)
|
||||
|
||||
val closeStartPenaltyForRing =
|
||||
mapOf( 0 to 99, 1 to 97, 2 to 95,
|
||||
3 to 92, 4 to 89, 5 to 69,
|
||||
6 to 57, 7 to 24, 8 to 15 )
|
||||
val closeStartPenaltyForRing = mapOf(
|
||||
0 to 99, 1 to 97, 2 to 95,
|
||||
3 to 92, 4 to 89, 5 to 69,
|
||||
6 to 57, 7 to 24, 8 to 15 )
|
||||
|
||||
val randomLuxuryRatios = mapOf(
|
||||
1 to listOf(1f),
|
||||
2 to listOf(0.55f, 0.44f),
|
||||
3 to listOf(0.40f, 0.33f, 0.27f),
|
||||
4 to listOf(0.35f, 0.25f, 0.25f, 0.15f),
|
||||
5 to listOf(0.25f, 0.25f, 0.20f, 0.15f, 0.15f),
|
||||
6 to listOf(0.20f, 0.20f, 0.20f, 0.15f, 0.15f, 0.10f),
|
||||
7 to listOf(0.20f, 0.20f, 0.15f, 0.15f, 0.10f, 0.10f, 0.10f),
|
||||
8 to listOf(0.20f, 0.15f, 0.15f, 0.10f, 0.10f, 0.10f, 0.10f, 0.10f)
|
||||
)
|
||||
|
||||
// This number is 23 in G&K, but there's a bug where hills are exempt so this number brings
|
||||
// the result closer to the density and distribution that was probably intended.
|
||||
const val baseMinorDepositFrequency = 30
|
||||
|
||||
}
|
||||
|
||||
private val regions = ArrayList<Region>()
|
||||
@ -224,7 +239,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
}
|
||||
// Normalize starts
|
||||
for (region in regions) {
|
||||
normalizeStart(tileMap[region.startPosition!!], minorCiv = false)
|
||||
normalizeStart(tileMap[region.startPosition!!], tileMap, minorCiv = false)
|
||||
}
|
||||
|
||||
val coastBiasCivs = civilizations.filter { ruleset.nations[it.civName]!!.startBias.contains("Coast") }
|
||||
@ -340,13 +355,9 @@ class MapRegions (val ruleset: Ruleset){
|
||||
|
||||
// Place impacts to keep city states etc at appropriate distance
|
||||
placeImpact(ImpactType.MinorCiv,tile, 6)
|
||||
/* lets leave these commented until resource placement is actually implemented
|
||||
placeImpact(ImpactType.Luxury, tile, 3)
|
||||
placeImpact(ImpactType.Strategic,tile, 0)
|
||||
placeImpact(ImpactType.Bonus, tile, 3)
|
||||
placeImpact(ImpactType.Fish, tile, 3)
|
||||
placeImpact(ImpactType.NaturalWonder, tile, 4)
|
||||
*/
|
||||
}
|
||||
|
||||
/** Attempts to find a good start close to the center of [region]. Calls setRegionStart with the position*/
|
||||
@ -466,7 +477,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
* Relies on startPosition having been set previously.
|
||||
* Assumes unchanged baseline values ie citizens eat 2 food each, similar production costs
|
||||
* If [minorCiv] is true, different weightings will be used. */
|
||||
private fun normalizeStart(startTile: TileInfo, minorCiv: Boolean) {
|
||||
private fun normalizeStart(startTile: TileInfo, tileMap: TileMap, minorCiv: Boolean) {
|
||||
// Remove ice-like features adjacent to start
|
||||
for (tile in startTile.neighbors) {
|
||||
val lastTerrain = tile.getTerrainFeatures().lastOrNull { it.impassable }
|
||||
@ -495,7 +506,20 @@ class MapRegions (val ruleset: Ruleset){
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Strategic Balance Resources
|
||||
// Place Strategic Balance Resources
|
||||
if (tileMap.mapParameters.mapResources == MapResources.strategicBalance) {
|
||||
val candidateTiles = startTile.getTilesInDistanceRange(1..2).shuffled() + startTile.getTilesAtDistance(3).shuffled()
|
||||
for (resource in ruleset.tileResources.values.filter { it.hasUnique(UniqueType.StrategicBalanceResource) }) {
|
||||
if (tryAddingResourceToTiles(resource, 1, candidateTiles, majorDeposit = true) == 0) {
|
||||
// Fallback mode - force placement, even on an otherwise inappropriate terrain. Do still respect water and impassible tiles!
|
||||
if (isWaterOnlyResource(resource))
|
||||
placeResourcesInTiles(999, candidateTiles.filter { it.isWater && !it.isImpassible() }.toList(), listOf(resource), majorDeposit = true, forcePlacement = true)
|
||||
else
|
||||
placeResourcesInTiles(999, candidateTiles.filter { it.isLand && !it.isImpassible() }.toList(), listOf(resource), majorDeposit = true, forcePlacement = true)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If bad early production, add a small strategic resource to SECOND ring (not for minors)
|
||||
if (!minorCiv && innerProduction < 3 && earlyProduction < 6) {
|
||||
@ -505,16 +529,11 @@ class MapRegions (val ruleset: Ruleset){
|
||||
it.resourceType == ResourceType.Strategic &&
|
||||
(it.revealedBy == null ||
|
||||
ruleset.technologies[it.revealedBy]!!.era() in earlyEras)
|
||||
}
|
||||
|
||||
if (validResources.isNotEmpty()) {
|
||||
for (tile in startTile.getTilesAtDistance(2).shuffled()) {
|
||||
val resourceToPlace = validResources.filter { tile.getLastTerrain().name in it.terrainsCanBeFoundOn }.randomOrNull()
|
||||
if (resourceToPlace != null) {
|
||||
tile.setTileResource(resourceToPlace, majorDeposit = false)
|
||||
break
|
||||
}
|
||||
}
|
||||
}.shuffled()
|
||||
val candidateTiles = startTile.getTilesAtDistance(2).shuffled()
|
||||
for (resource in validResources) {
|
||||
if (tryAddingResourceToTiles(resource, 1, candidateTiles, majorDeposit = false) > 0)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@ -551,8 +570,8 @@ class MapRegions (val ruleset: Ruleset){
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Legendary start? +2
|
||||
if (tileMap.mapParameters.mapResources == MapResources.legendaryStart)
|
||||
bonusesNeeded += 2
|
||||
|
||||
// Attempt to place one grassland at a plains-only spot (nor for minors)
|
||||
if (!minorCiv && bonusesNeeded < 3 && totalNativeTwoFood == 0) {
|
||||
@ -589,6 +608,8 @@ class MapRegions (val ruleset: Ruleset){
|
||||
while (bonusesNeeded > 0 && candidatePlots.isNotEmpty()) {
|
||||
val plot = candidatePlots.first()
|
||||
candidatePlots.remove(plot) // remove the plot as it has now been tried, whether successfully or not
|
||||
if (plot.getBaseTerrain().hasUnique(UniqueType.BlocksResources, StateForConditionals(attackedTile = plot)))
|
||||
continue // Don't put bonuses on snow hills
|
||||
|
||||
val validBonuses = ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Bonus &&
|
||||
@ -776,8 +797,8 @@ class MapRegions (val ruleset: Ruleset){
|
||||
fun placeResourcesAndMinorCivs(tileMap: TileMap, minorCivs: List<CivilizationInfo>) {
|
||||
assignLuxuries()
|
||||
placeMinorCivs(tileMap, minorCivs)
|
||||
// TODO: place luxuries
|
||||
// TODO: place strategic and bonus resources
|
||||
placeLuxuries(tileMap)
|
||||
placeStrategicAndBonuses(tileMap)
|
||||
}
|
||||
|
||||
/** Assigns a luxury to each region. No luxury can be assigned to too many regions.
|
||||
@ -787,26 +808,33 @@ class MapRegions (val ruleset: Ruleset){
|
||||
// If there are any weightings defined in json, assume they are complete. If there are none, use flat weightings instead
|
||||
val fallbackWeightings = ruleset.tileResources.values.none {
|
||||
it.resourceType == ResourceType.Luxury &&
|
||||
(it.hasUnique(UniqueType.LuxuryWeighting) || it.hasUnique(UniqueType.LuxuryWeightingForCityStates)) }
|
||||
(it.uniqueObjects.any { unique -> unique.isOfType(UniqueType.ResourceWeighting) } || it.hasUnique(UniqueType.LuxuryWeightingForCityStates)) }
|
||||
|
||||
val maxRegionsWithLuxury = if (regions.count() > 12) 3 else 2
|
||||
val maxRegionsWithLuxury = when {
|
||||
regions.count() > 12 -> 3
|
||||
regions.count() > 8 -> 2
|
||||
else -> 1
|
||||
}
|
||||
val targetCityStateLuxuries = 3 // was probably intended to be "if (tileData.size > 5000) 4 else 3"
|
||||
val disabledPercent = 100 - min(tileData.size.toFloat().pow(0.2f) * 16, 100f).toInt() // Approximately
|
||||
val targetDisabledLuxuries = (ruleset.tileResources.values
|
||||
.count { it.resourceType == ResourceType.Luxury } * disabledPercent) / 100
|
||||
|
||||
val assignableLuxuries = ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Luxury &&
|
||||
!it.hasUnique(UniqueType.LuxurySpecialPlacement) &&
|
||||
!it.hasUnique(UniqueType.CityStateOnlyResource) }
|
||||
val amountRegionsWithLuxury = HashMap<String, Int>()
|
||||
// Init map
|
||||
ruleset.tileResources.values
|
||||
.forEach { amountRegionsWithLuxury[it.name] = 0 }
|
||||
|
||||
for (region in regions.sortedBy { getRegionPriority(ruleset.terrains[it.type]) } ) {
|
||||
var candidateLuxuries = ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Luxury &&
|
||||
val regionConditional = StateForConditionals(region = region)
|
||||
var candidateLuxuries = assignableLuxuries.filter {
|
||||
amountRegionsWithLuxury[it.name]!! < maxRegionsWithLuxury &&
|
||||
// Check that it has a weight for this region type
|
||||
(fallbackWeightings ||
|
||||
it.getMatchingUniques(UniqueType.LuxuryWeighting).any { unique -> unique.params[0] == region.type } ) &&
|
||||
it.hasUnique(UniqueType.ResourceWeighting, regionConditional)) &&
|
||||
// Check that there is enough coast if it is a water based resource
|
||||
((region.terrainCounts["Coastal"] ?: 0) >= 12 ||
|
||||
it.terrainsCanBeFoundOn.any { terrain -> ruleset.terrains[terrain]!!.type != TerrainType.Water } )
|
||||
@ -814,8 +842,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
|
||||
// If we couldn't find any options, pick from all luxuries. First try to not pick water luxuries on land regions
|
||||
if (candidateLuxuries.isEmpty()) {
|
||||
candidateLuxuries = ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Luxury &&
|
||||
candidateLuxuries = assignableLuxuries.filter {
|
||||
amountRegionsWithLuxury[it.name]!! < maxRegionsWithLuxury &&
|
||||
// Ignore weightings for this pass
|
||||
// Check that there is enough coast if it is a water based resource
|
||||
@ -825,8 +852,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
}
|
||||
// If there are still no candidates, ignore water restrictions
|
||||
if (candidateLuxuries.isEmpty()) {
|
||||
candidateLuxuries = ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Luxury &&
|
||||
candidateLuxuries = assignableLuxuries.filter {
|
||||
amountRegionsWithLuxury[it.name]!! < maxRegionsWithLuxury
|
||||
// Ignore weightings and water for this pass
|
||||
}
|
||||
@ -836,12 +862,11 @@ class MapRegions (val ruleset: Ruleset){
|
||||
|
||||
// Pick a luxury at random. Weight is reduced if the luxury has been picked before
|
||||
val modifiedWeights = candidateLuxuries.map {
|
||||
val weightingUnique = it.getMatchingUniques(UniqueType.LuxuryWeighting)
|
||||
.filter { unique -> unique.params[0] == region.type }.firstOrNull()
|
||||
val weightingUnique = it.getMatchingUniques(UniqueType.ResourceWeighting, regionConditional).firstOrNull()
|
||||
if (weightingUnique == null)
|
||||
1f / (1f + amountRegionsWithLuxury[it.name]!!)
|
||||
else
|
||||
weightingUnique.params[1].toFloat() / (1f + amountRegionsWithLuxury[it.name]!!)
|
||||
weightingUnique.params[0].toFloat() / (1f + amountRegionsWithLuxury[it.name]!!)
|
||||
}
|
||||
region.luxury = candidateLuxuries.randomWeighted(modifiedWeights).name
|
||||
amountRegionsWithLuxury[region.luxury!!] = amountRegionsWithLuxury[region.luxury]!! + 1
|
||||
@ -849,8 +874,7 @@ class MapRegions (val ruleset: Ruleset){
|
||||
|
||||
// Assign luxuries to City States
|
||||
for (i in 1..targetCityStateLuxuries) {
|
||||
val candidateLuxuries = ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Luxury &&
|
||||
val candidateLuxuries = assignableLuxuries.filter {
|
||||
amountRegionsWithLuxury[it.name] == 0 &&
|
||||
(fallbackWeightings || it.hasUnique(UniqueType.LuxuryWeightingForCityStates))
|
||||
}
|
||||
@ -868,11 +892,9 @@ class MapRegions (val ruleset: Ruleset){
|
||||
amountRegionsWithLuxury[luxury] = 1
|
||||
}
|
||||
|
||||
// Assign some resources as random placement. Marble is never random.
|
||||
val remainingLuxuries = ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Luxury &&
|
||||
amountRegionsWithLuxury[it.name] == 0 &&
|
||||
!it.hasUnique(UniqueType.LuxurySpecialPlacement)
|
||||
// Assign some resources as random placement.
|
||||
val remainingLuxuries = assignableLuxuries.filter {
|
||||
amountRegionsWithLuxury[it.name] == 0
|
||||
}.map { it.name }.shuffled()
|
||||
randomLuxuries.addAll(remainingLuxuries.drop(targetDisabledLuxuries))
|
||||
}
|
||||
@ -1096,57 +1118,508 @@ class MapRegions (val ruleset: Ruleset){
|
||||
private fun placeMinorCiv(civ: CivilizationInfo, tileMap: TileMap, tile: TileInfo) {
|
||||
tileMap.addStartingLocation(civ.civName, tile)
|
||||
placeImpact(ImpactType.MinorCiv,tile, 4)
|
||||
/* lets leave these commented until resource placement is actually implemented
|
||||
placeImpact(ImpactType.Luxury, tile, 3)
|
||||
placeImpact(ImpactType.Strategic,tile, 0)
|
||||
placeImpact(ImpactType.Bonus, tile, 3)
|
||||
placeImpact(ImpactType.Fish, tile, 3)
|
||||
placeImpact(ImpactType.Marble, tile, 4) */
|
||||
|
||||
normalizeStart(tile, minorCiv = true)
|
||||
normalizeStart(tile, tileMap, minorCiv = true)
|
||||
}
|
||||
|
||||
/** Places all Luxuries onto [tileMap]. Assumes that assignLuxuries and placeMinorCivs have been called. */
|
||||
private fun placeLuxuries(tileMap: TileMap) {
|
||||
// First place luxuries at major civ start locations
|
||||
val averageFertilityDensity = regions.sumOf { it.totalFertility } / regions.sumOf { it.tiles.count() }.toFloat()
|
||||
for (region in regions) {
|
||||
var targetLuxuries = 1
|
||||
if (tileMap.mapParameters.mapResources == MapResources.legendaryStart)
|
||||
targetLuxuries++
|
||||
if (region.totalFertility / region.tiles.count().toFloat() < averageFertilityDensity) {
|
||||
targetLuxuries++
|
||||
}
|
||||
|
||||
val luxuryToPlace = ruleset.tileResources[region.luxury]!!
|
||||
// First check 2 inner rings
|
||||
val firstPass = tileMap[region.startPosition!!].getTilesInDistanceRange(1..2)
|
||||
.shuffled().sortedBy { it.getTileFertility(false) } // Check bad tiles first
|
||||
targetLuxuries -= tryAddingResourceToTiles(luxuryToPlace, targetLuxuries, firstPass, 0.5f) // Skip every 2nd tile on first pass
|
||||
|
||||
if (targetLuxuries > 0) {
|
||||
val secondPass = firstPass + tileMap[region.startPosition!!].getTilesAtDistance(3)
|
||||
.shuffled().sortedBy { it.getTileFertility(false) } // Check bad tiles first
|
||||
targetLuxuries -= tryAddingResourceToTiles(luxuryToPlace, targetLuxuries, secondPass)
|
||||
}
|
||||
if (targetLuxuries > 0) {
|
||||
// Try adding in 1 luxury from the random rotation as compensation
|
||||
for (luxury in randomLuxuries) {
|
||||
if (tryAddingResourceToTiles(ruleset.tileResources[luxury]!!, 1, firstPass) > 0) break
|
||||
}
|
||||
}
|
||||
}
|
||||
// Second place one (1) luxury at minor civ start locations
|
||||
// Check only ones that got a start location
|
||||
for (startLocation in tileMap.startingLocationsByNation
|
||||
.filterKeys { ruleset.nations[it]!!.isCityState() }.map { it.value.first() }) {
|
||||
val region = regions.firstOrNull { startLocation in it.tiles }
|
||||
val tilesToCheck = startLocation.getTilesInDistanceRange(1..2)
|
||||
// 75% probability that we first attempt to place a "city state" luxury, then a random or regional one
|
||||
// 25% probability of going the other way around
|
||||
val globalLuxuries = if (region?.luxury != null) randomLuxuries + listOf(region.luxury) else randomLuxuries
|
||||
val candidateLuxuries = if (Random.nextInt(100) >= 25)
|
||||
cityStateLuxuries.shuffled() + globalLuxuries.shuffled()
|
||||
else
|
||||
globalLuxuries.shuffled() + cityStateLuxuries.shuffled()
|
||||
// Now try adding one until we are successful
|
||||
for (luxury in candidateLuxuries) {
|
||||
if (tryAddingResourceToTiles(ruleset.tileResources[luxury]!!, 1, tilesToCheck) > 0) break
|
||||
}
|
||||
}
|
||||
// Third add regional luxuries
|
||||
// The target number depends on map size and how close we are to an "ideal number" of civs for the map
|
||||
val idealCivs = max(2, tileData.size / 500)
|
||||
var regionTargetNumber = (tileData.size / 600) - (0.3f * abs(regions.count() - idealCivs)).toInt()
|
||||
regionTargetNumber += when (tileMap.mapParameters.mapResources) {
|
||||
MapResources.abundant -> 1
|
||||
MapResources.sparse -> -1
|
||||
else -> 0
|
||||
}
|
||||
regionTargetNumber = max(1, regionTargetNumber)
|
||||
for (region in regions) {
|
||||
val resource = ruleset.tileResources[region.luxury]!!
|
||||
if (isWaterOnlyResource(resource))
|
||||
tryAddingResourceToTiles(resource, regionTargetNumber,
|
||||
tileMap.getTilesInRectangle(region.rect).filter { it.isWater && it.neighbors.any { neighbor -> neighbor.getContinent() == region.continentID } }.shuffled(),
|
||||
0.4f, true, 4, 2)
|
||||
else
|
||||
tryAddingResourceToTiles(resource, regionTargetNumber, region.tiles.asSequence().shuffled(), 0.4f,
|
||||
true, 4, 2)
|
||||
}
|
||||
// Fourth add random luxuries
|
||||
if (randomLuxuries.isNotEmpty()) {
|
||||
var targetRandomLuxuries = tileData.size.toFloat().pow(0.45f).toInt() // Approximately
|
||||
targetRandomLuxuries *= when (tileMap.mapParameters.mapResources) {
|
||||
MapResources.sparse -> 80
|
||||
MapResources.abundant -> 133
|
||||
else -> 100
|
||||
}
|
||||
targetRandomLuxuries /= 100
|
||||
targetRandomLuxuries += Random.nextInt(regions.count()) // Add random number based on number of civs
|
||||
val minimumRandomLuxuries = tileData.size.toFloat().pow(0.2f).toInt() // Approximately
|
||||
val worldTiles = tileMap.values.asSequence().shuffled()
|
||||
for ((index, luxury) in randomLuxuries.shuffled().withIndex()) {
|
||||
val targetForThisLuxury = if (randomLuxuries.count() > 8) targetRandomLuxuries / 10
|
||||
else {
|
||||
val minimum = max(3, minimumRandomLuxuries - index)
|
||||
max(minimum, (targetRandomLuxuries * randomLuxuryRatios[randomLuxuries.count()]!![index] + 0.5f).toInt())
|
||||
}
|
||||
tryAddingResourceToTiles(ruleset.tileResources[luxury]!!, targetForThisLuxury, worldTiles, 0.25f,
|
||||
true, 4, 2)
|
||||
}
|
||||
}
|
||||
val specialLuxuries = ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Luxury &&
|
||||
it.hasUnique(UniqueType.LuxurySpecialPlacement)
|
||||
}
|
||||
val placedSpecials = HashMap<String, Int>()
|
||||
specialLuxuries.forEach { placedSpecials[it.name] = 0 } // init map
|
||||
|
||||
// Fifth, on resource settings other than sparse, add an extra luxury to starts
|
||||
if (tileMap.mapParameters.mapResources != MapResources.sparse) {
|
||||
for (region in regions) {
|
||||
val tilesToCheck = tileMap[region.startPosition!!].getTilesInDistanceRange(1..2)
|
||||
val candidateLuxuries = randomLuxuries.shuffled().toMutableList()
|
||||
if (tileMap.mapParameters.mapResources != MapResources.strategicBalance)
|
||||
candidateLuxuries += specialLuxuries.shuffled().map { it.name } // Include marble!
|
||||
candidateLuxuries += cityStateLuxuries.shuffled()
|
||||
candidateLuxuries += regions.mapNotNull { it.luxury }.shuffled()
|
||||
for (luxury in candidateLuxuries) {
|
||||
if (tryAddingResourceToTiles(ruleset.tileResources[luxury]!!, 1, tilesToCheck) > 0) {
|
||||
if (placedSpecials.containsKey(luxury)) // Keep track of marble-type specials as they may be placed now.
|
||||
placedSpecials[luxury] = placedSpecials[luxury]!! + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sixth, top up marble-type specials if needed
|
||||
for (special in specialLuxuries) {
|
||||
val targetNumber = when (tileMap.mapParameters.mapResources) {
|
||||
MapResources.sparse -> (regions.count() * 0.5f).toInt()
|
||||
MapResources.abundant -> (regions.count() * 0.9f).toInt()
|
||||
else -> (regions.count() * 0.75f).toInt()
|
||||
}
|
||||
val numberToPlace = max(2, targetNumber - placedSpecials[special.name]!!)
|
||||
tryAddingResourceToTiles(special, numberToPlace, tileMap.values.asSequence().shuffled(), 1f,
|
||||
true, 6, 0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun placeStrategicAndBonuses(tileMap: TileMap) {
|
||||
val strategicResources = ruleset.tileResources.values.filter { it.resourceType == ResourceType.Strategic }
|
||||
// As usual, if there are any relevant json definitions, assume they are complete
|
||||
val fallbackStrategic = ruleset.tileResources.values.none {
|
||||
it.resourceType == ResourceType.Strategic &&
|
||||
it.uniqueObjects.any { unique -> unique.isOfType(UniqueType.ResourceWeighting) } ||
|
||||
it.uniqueObjects.any { unique -> unique.isOfType(UniqueType.MinorDepositWeighting) }
|
||||
}
|
||||
/* There are a couple competing/complementary distribution systems at work here. First, major
|
||||
deposits are placed according to a frequency defined in the terrains themselves, for each
|
||||
tile that is eligible to get a major deposit, there is a weighted random choice between
|
||||
resource types.
|
||||
Minor deposits are placed by randomly picking a number of land tiles from anywhere on the
|
||||
map (so not stratified by terrain type) and assigning a weighted randomly picked resource.
|
||||
Bonuses are placed according to a frequency for a rule like "every 8 jungle hills", here
|
||||
implemented as a conditional.
|
||||
|
||||
We need to build lists of all tiles following a given rule to place these, which is BY FAR
|
||||
the most expensive calculation in this entire class. To save some time we anonymize the
|
||||
uniques so we only have to make one list for each set of conditionals, so eg Wheat and
|
||||
Horses can share a list since they are both interested in Featureless Plains.
|
||||
We also save a list of all land tiles for minor deposit generation. */
|
||||
|
||||
// Determines number tiles per resource
|
||||
val bonusMultiplier = when (tileMap.mapParameters.mapResources) {
|
||||
MapResources.sparse -> 1.5f
|
||||
MapResources.abundant -> 0.6667f
|
||||
else -> 1f
|
||||
}
|
||||
val landList = ArrayList<TileInfo>() // For minor deposits
|
||||
val ruleLists = HashMap<Unique, MutableList<TileInfo>>() // For rule-based generation
|
||||
|
||||
// Figure out which rules (sets of conditionals) need lists built
|
||||
for (resource in ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Strategic ||
|
||||
it.resourceType == ResourceType.Bonus }) {
|
||||
for (rule in resource.uniqueObjects.filter { unique ->
|
||||
unique.isOfType(UniqueType.ResourceFrequency) ||
|
||||
unique.isOfType(UniqueType.ResourceWeighting) ||
|
||||
unique.isOfType(UniqueType.MinorDepositWeighting) }) {
|
||||
// Weed out some clearly impossible rules straight away to save time later
|
||||
if (rule.conditionals.any { conditional ->
|
||||
(conditional.isOfType(UniqueType.ConditionalOnWaterMaps) && !usingArchipelagoRegions) ||
|
||||
(conditional.isOfType(UniqueType.ConditionalInRegionOfType) && regions.none { region -> region.type == conditional.params[0] }) ||
|
||||
(conditional.isOfType(UniqueType.ConditionalInRegionExceptOfType) && regions.all { region -> region.type == conditional.params[0] })
|
||||
} )
|
||||
continue
|
||||
val simpleRule = anonymizeUnique(rule)
|
||||
if (ruleLists.keys.none { it.text == simpleRule.text }) // Need to do text comparison since the uniques will not be equal otherwise
|
||||
ruleLists[simpleRule] = ArrayList()
|
||||
}
|
||||
}
|
||||
// Make up some rules for placing strategics in a fallback situation
|
||||
if (fallbackStrategic) {
|
||||
val interestingTerrains = strategicResources.flatMap { it.terrainsCanBeFoundOn }.map { ruleset.terrains[it]!! }.toSet()
|
||||
for (terrain in interestingTerrains) {
|
||||
val fallbackRule = if (terrain.type == TerrainType.TerrainFeature)
|
||||
Unique("RULE <in [${terrain.name}] tiles>")
|
||||
else
|
||||
Unique("RULE <in [Featureless] [${terrain.name}] tiles>")
|
||||
if (ruleLists.keys.none { it.text == fallbackRule.text }) // Need to do text comparison since the uniques will not be equal otherwise
|
||||
ruleLists[fallbackRule] = ArrayList()
|
||||
}
|
||||
}
|
||||
// Now go through the entire map to build lists
|
||||
for (tile in tileMap.values.asSequence().shuffled()) {
|
||||
val terrainCondition = StateForConditionals(attackedTile = tile, region = regions.firstOrNull { tile in it.tiles })
|
||||
if (tile.getBaseTerrain().hasUnique(UniqueType.BlocksResources, terrainCondition))
|
||||
continue // Don't count snow hills
|
||||
if (tile.isLand)
|
||||
landList.add(tile)
|
||||
for ((rule, list) in ruleLists) {
|
||||
if (rule.conditionalsApply(terrainCondition)) {
|
||||
list.add(tile)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Keep track of total placed strategic resources in case we need to top them up later
|
||||
val totalPlaced = HashMap<TileResource, Int>()
|
||||
strategicResources.forEach { totalPlaced[it] = 0 }
|
||||
|
||||
// First place major deposits on land
|
||||
for (terrain in ruleset.terrains.values.filter { it.type != TerrainType.Water }) {
|
||||
// Figure out if we generated a list for this terrain
|
||||
val list = ruleLists.filterKeys { it.text == getTerrainRule(terrain).text }.values.firstOrNull()
|
||||
if (list == null) {
|
||||
// If not the terrain can be safely skipped
|
||||
continue
|
||||
}
|
||||
totalPlaced += placeMajorDeposits(list, terrain, fallbackStrategic, 2, 2)
|
||||
}
|
||||
|
||||
// Second add some small deposits of modern strategic resources to city states
|
||||
val lastEra = ruleset.eras.values.maxOf { it.eraNumber }
|
||||
val modernOptions = strategicResources.filter {
|
||||
it.revealedBy != null &&
|
||||
ruleset.eras[ruleset.technologies[it.revealedBy]!!.era()]!!.eraNumber >= lastEra / 2
|
||||
}
|
||||
for (cityStateLocation in tileMap.startingLocationsByNation.filterKeys { ruleset.nations[it]!!.isCityState() }.values.map { it.first() }) {
|
||||
val resourceToPlace = modernOptions.random()
|
||||
totalPlaced[resourceToPlace] =
|
||||
totalPlaced[resourceToPlace]!! + tryAddingResourceToTiles(resourceToPlace, 1, cityStateLocation.getTilesInDistanceRange(1..3))
|
||||
}
|
||||
|
||||
// Third add some minor deposits to land tiles
|
||||
// Note: In G&K there is a bug where minor deposits are never placed on hills. We're not replicating that.
|
||||
val frequency = (baseMinorDepositFrequency * bonusMultiplier).toInt()
|
||||
val minorDepositsToAdd = (landList.count() / frequency) + 1
|
||||
var minorDepositsAdded = 0
|
||||
for (tile in landList) {
|
||||
if (tile.resource != null || tileData[tile.position]!!.impacts.containsKey(ImpactType.Strategic))
|
||||
continue
|
||||
val conditionalTerrain = StateForConditionals(attackedTile = tile)
|
||||
if (tile.getBaseTerrain().hasUnique(UniqueType.BlocksResources, conditionalTerrain))
|
||||
continue
|
||||
val weightings = strategicResources.map {
|
||||
if (fallbackStrategic) {
|
||||
if (tile.getLastTerrain().name in it.terrainsCanBeFoundOn) 1f else 0f
|
||||
} else {
|
||||
val uniques = it.getMatchingUniques(UniqueType.MinorDepositWeighting, conditionalTerrain).toList()
|
||||
uniques.sumOf { unique -> unique.params[0].toInt() }.toFloat()
|
||||
}
|
||||
}
|
||||
if (weightings.sum() <= 0) {
|
||||
continue
|
||||
}
|
||||
val resourceToPlace = strategicResources.randomWeighted(weightings)
|
||||
tile.setTileResource(resourceToPlace, majorDeposit = false)
|
||||
placeImpact(ImpactType.Strategic, tile, Random.nextInt(2) + Random.nextInt(2))
|
||||
totalPlaced[resourceToPlace] = totalPlaced[resourceToPlace]!! + 1
|
||||
minorDepositsAdded++
|
||||
if (minorDepositsAdded >= minorDepositsToAdd)
|
||||
break
|
||||
}
|
||||
|
||||
// Fourth add water-based major deposits. Extra impact because we don't want them too clustered and there is usually lots to go around
|
||||
for (terrain in ruleset.terrains.values.filter { it.type == TerrainType.Water }) {
|
||||
// Figure out if we generated a list for this terrain
|
||||
val list = ruleLists.filterKeys { it.text == getTerrainRule(terrain).text }.values.firstOrNull()
|
||||
if (list == null) {
|
||||
// If not the terrain can be safely skipped
|
||||
continue
|
||||
}
|
||||
totalPlaced += placeMajorDeposits(list, terrain, fallbackStrategic, 4, 3)
|
||||
}
|
||||
|
||||
// Fifth place up to 2 extra deposits of each resource type if there is < 1 per civ
|
||||
for (resource in strategicResources) {
|
||||
val extraNeeded = min(2, regions.count() - totalPlaced[resource]!!)
|
||||
if (extraNeeded > 0) {
|
||||
if (isWaterOnlyResource(resource))
|
||||
tryAddingResourceToTiles(resource, extraNeeded, tileMap.values.asSequence().filter { it.isWater }.shuffled(), respectImpacts = true)
|
||||
else
|
||||
tryAddingResourceToTiles(resource, extraNeeded, landList.asSequence(), respectImpacts = true)
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out if bonus generation rates are defined in json. Assume that if there are any, the definitions are complete.
|
||||
val fallbackBonuses = ruleset.tileResources.values.none { it.uniqueObjects.any { unique -> unique.type == UniqueType.ResourceFrequency } }
|
||||
|
||||
// Sixth place bonus resources (and other resources that might have been assigned frequency-based generation).
|
||||
// Water-based bonuses go last and have extra impact, because coasts are very common and we don't want too much clustering
|
||||
val sortedResourceList = ruleset.tileResources.values.sortedBy { isWaterOnlyResource(it) }
|
||||
for (resource in sortedResourceList) {
|
||||
val extraImpact = if (isWaterOnlyResource(resource)) 1 else 0
|
||||
for (rule in resource.uniqueObjects.filter { it.type == UniqueType.ResourceFrequency }) {
|
||||
// Figure out which list applies, if any
|
||||
val simpleRule = anonymizeUnique(rule)
|
||||
val list = ruleLists.filterKeys { it.text == simpleRule.text }.values.firstOrNull()
|
||||
// If there is no matching list, it is because the rule was determined to be impossible and so can be safely skipped
|
||||
if (list == null) continue
|
||||
// Place the resources
|
||||
placeResourcesInTiles((rule.params[0].toFloat() * bonusMultiplier).toInt(), list, listOf(resource), 0 + extraImpact, 2 + extraImpact, false)
|
||||
}
|
||||
if(fallbackBonuses && resource.resourceType == ResourceType.Bonus) {
|
||||
// Since we haven't been able to generate any rule-based lists, just generate new ones on the fly
|
||||
// Increase impact to avoid clustering since there is no terrain type stratification.
|
||||
val fallbackList = tileMap.values.filter { it.getLastTerrain().name in resource.terrainsCanBeFoundOn }.shuffled()
|
||||
placeResourcesInTiles((20 * bonusMultiplier).toInt(), fallbackList, listOf(resource), 2 + extraImpact, 2 + extraImpact, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Seventh (and finally!) place an extra bonus in the THIRD ring of each start to make it slightly more attractive
|
||||
for (region in regions) {
|
||||
val terrain = if (region.type == "Hybrid") region.terrainCounts.filterNot { it.key == "Coastal" }.maxByOrNull { it.value }!!.key
|
||||
else region.type
|
||||
val resourceUnique = ruleset.terrains[terrain]!!.getMatchingUniques(UniqueType.RegionExtraResource).firstOrNull()
|
||||
// If this region has an explicit "this is the bonus" unique go with that, else random appropriate
|
||||
val resource = if (resourceUnique != null) ruleset.tileResources[resourceUnique.params[0]]!!
|
||||
else ruleset.tileResources.values.filter { it.resourceType == ResourceType.Bonus && terrain in it.terrainsCanBeFoundOn }.random()
|
||||
val candidateTiles = tileMap[region.startPosition!!].getTilesAtDistance(3).shuffled()
|
||||
val amount = if (resourceUnique != null) 2 else 1 // Place an extra if the region type requests it
|
||||
if (tryAddingResourceToTiles(resource, amount, candidateTiles) == 0) {
|
||||
// We couldn't place any, try adding a fish instead
|
||||
val fishyBonus = ruleset.tileResources.values.filter { it.resourceType == ResourceType.Bonus &&
|
||||
it.terrainsCanBeFoundOn.any { terrainName -> ruleset.terrains[terrainName]!!.type == TerrainType.Water } }
|
||||
.randomOrNull()
|
||||
if (fishyBonus != null)
|
||||
tryAddingResourceToTiles(fishyBonus, 1, candidateTiles)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Attempts to place [amount] [resource] on [tiles], checking tiles in order. A [ratio] below 1 means skipping
|
||||
* some tiles, ie ratio = 0.25 will put a resource on every 4th eligible tile. Can optionally respect impact flags,
|
||||
* and places impact if [baseImpact] >= 0. Returns number of placed resources. */
|
||||
private fun tryAddingResourceToTiles(resource: TileResource, amount: Int, tiles: Sequence<TileInfo>, ratio: Float = 1f,
|
||||
respectImpacts: Boolean = false, baseImpact: Int = -1, randomImpact: Int = 0,
|
||||
majorDeposit: Boolean = false): Int {
|
||||
if (amount <= 0) return 0
|
||||
var amountAdded = 0
|
||||
var ratioProgress = 1f
|
||||
val impactType = when (resource.resourceType) {
|
||||
ResourceType.Luxury -> ImpactType.Luxury
|
||||
ResourceType.Strategic -> ImpactType.Strategic
|
||||
ResourceType.Bonus -> ImpactType.Bonus
|
||||
}
|
||||
|
||||
for (tile in tiles) {
|
||||
val conditionalTerrain = StateForConditionals(attackedTile = tile)
|
||||
if (tile.resource == null &&
|
||||
tile.getLastTerrain().name in resource.terrainsCanBeFoundOn &&
|
||||
!tile.getBaseTerrain().hasUnique(UniqueType.BlocksResources, conditionalTerrain) &&
|
||||
!resource.hasUnique(UniqueType.NoNaturalGeneration, conditionalTerrain)) {
|
||||
if (ratioProgress >= 1f &&
|
||||
!(respectImpacts && tileData[tile.position]!!.impacts.containsKey(impactType))) {
|
||||
tile.setTileResource(resource, majorDeposit)
|
||||
ratioProgress -= 1f
|
||||
amountAdded++
|
||||
if (baseImpact + randomImpact >= 0)
|
||||
placeImpact(impactType, tile, baseImpact + Random.nextInt(randomImpact + 1))
|
||||
if (amountAdded >= amount) break
|
||||
}
|
||||
ratioProgress += ratio
|
||||
}
|
||||
}
|
||||
return amountAdded
|
||||
}
|
||||
|
||||
/** Attempts to place major deposits in a [tileList] consisting exclusively of [terrain] tiles.
|
||||
* Lifted out of the main function to allow postponing water resources.
|
||||
* @return a map of resource types to placed deposits. */
|
||||
private fun placeMajorDeposits(tileList: List<TileInfo>, terrain: Terrain, fallbackWeightings: Boolean, baseImpact: Int, randomImpact: Int): Map<TileResource, Int> {
|
||||
if (tileList.isEmpty())
|
||||
return mapOf()
|
||||
val frequency = if (terrain.hasUnique(UniqueType.MajorStrategicFrequency))
|
||||
terrain.getMatchingUniques(UniqueType.MajorStrategicFrequency).first().params[0].toInt()
|
||||
else 25
|
||||
val resourceOptions = ruleset.tileResources.values.filter {
|
||||
it.resourceType == ResourceType.Strategic &&
|
||||
((fallbackWeightings && terrain.name in it.terrainsCanBeFoundOn) ||
|
||||
it.uniqueObjects.any { unique -> anonymizeUnique(unique).text == getTerrainRule(terrain).text })
|
||||
}
|
||||
return if (resourceOptions.isNotEmpty())
|
||||
placeResourcesInTiles(frequency, tileList, resourceOptions, baseImpact, randomImpact, true)
|
||||
else
|
||||
mapOf()
|
||||
}
|
||||
|
||||
/** Given a [tileList] and possible [resourceOptions], will place a resource on every [frequency] tiles.
|
||||
* Tries to avoid impacts, but falls back to lowest impact otherwise.
|
||||
* Goes through the list in order, so pre-shuffle it!
|
||||
* Assumes all tiles in the list are of the same terrain type when generating weightings, irrelevant if only one option.
|
||||
* Respects terrainsCanBeFoundOn when there is only one option, unless [forcePlacement] is true.
|
||||
* @return a map of the resources in the options list to number placed. */
|
||||
private fun placeResourcesInTiles(frequency: Int, tileList: List<TileInfo>, resourceOptions: List<TileResource>,
|
||||
baseImpact: Int = 0, randomImpact: Int = 0, majorDeposit: Boolean = false, forcePlacement: Boolean = false): Map<TileResource, Int> {
|
||||
if (tileList.isEmpty() || resourceOptions.isEmpty()) return mapOf()
|
||||
val impactType = when (resourceOptions.first().resourceType) {
|
||||
ResourceType.Strategic -> ImpactType.Strategic
|
||||
ResourceType.Bonus -> ImpactType.Bonus
|
||||
ResourceType.Luxury -> ImpactType.Luxury
|
||||
}
|
||||
val conditionalTerrain = StateForConditionals(attackedTile = tileList.firstOrNull())
|
||||
val weightings = resourceOptions.map {
|
||||
val unique = it.getMatchingUniques(UniqueType.ResourceWeighting, conditionalTerrain).firstOrNull()
|
||||
if (unique != null)
|
||||
unique.params[0].toFloat()
|
||||
else
|
||||
1f
|
||||
}
|
||||
val testTerrains = (resourceOptions.count() == 1) && !forcePlacement
|
||||
val amountToPlace = (tileList.count() / frequency) + 1
|
||||
var amountPlaced = 0
|
||||
val detailedPlaced = HashMap<TileResource, Int>()
|
||||
resourceOptions.forEach { detailedPlaced[it] = 0 }
|
||||
val fallbackTiles = ArrayList<TileInfo>()
|
||||
// First pass - avoid impacts entirely
|
||||
for (tile in tileList) {
|
||||
if (tile.resource != null ||
|
||||
(testTerrains &&
|
||||
(tile.getLastTerrain().name !in resourceOptions.first().terrainsCanBeFoundOn ||
|
||||
resourceOptions.first().hasUnique(UniqueType.NoNaturalGeneration, conditionalTerrain)) ) ||
|
||||
tile.getBaseTerrain().hasUnique(UniqueType.BlocksResources, conditionalTerrain))
|
||||
continue // Can't place here, can't be a fallback tile
|
||||
if (tileData[tile.position]!!.impacts.containsKey(impactType)) {
|
||||
fallbackTiles.add(tile) // Taken but might be a viable fallback tile
|
||||
} else {
|
||||
// Add a resource to the tile
|
||||
val resourceToPlace = resourceOptions.randomWeighted(weightings)
|
||||
tile.setTileResource(resourceToPlace, majorDeposit)
|
||||
placeImpact(impactType, tile, baseImpact + Random.nextInt(randomImpact + 1))
|
||||
amountPlaced++
|
||||
detailedPlaced[resourceToPlace] = detailedPlaced[resourceToPlace]!! + 1
|
||||
if (amountPlaced >= amountToPlace) {
|
||||
return detailedPlaced
|
||||
}
|
||||
}
|
||||
}
|
||||
// Second pass - place on least impacted tiles
|
||||
while (amountPlaced < amountToPlace && fallbackTiles.isNotEmpty()) {
|
||||
// Sorry, we do need to re-sort the list for every pass since new impacts are made with every placement
|
||||
val bestTile = fallbackTiles.minByOrNull { tileData[it.position]!!.impacts[impactType]!! }!!
|
||||
fallbackTiles.remove(bestTile)
|
||||
val resourceToPlace = resourceOptions.randomWeighted(weightings)
|
||||
bestTile.setTileResource(resourceToPlace, majorDeposit)
|
||||
placeImpact(impactType, bestTile, baseImpact + Random.nextInt(randomImpact + 1))
|
||||
amountPlaced++
|
||||
detailedPlaced[resourceToPlace] = detailedPlaced[resourceToPlace]!! + 1
|
||||
}
|
||||
return detailedPlaced
|
||||
}
|
||||
|
||||
/** Adds numbers to tileData in a similar way to closeStartPenalty, but for different types */
|
||||
private fun placeImpact(type: ImpactType, tile: TileInfo, radius: Int) {
|
||||
// Epicenter
|
||||
if (type == ImpactType.Fish || type == ImpactType.Marble)
|
||||
tileData[tile.position]!!.impacts[type] = 1 // These use different values
|
||||
else
|
||||
tileData[tile.position]!!.impacts[type] = 99
|
||||
tileData[tile.position]!!.impacts[type] = 99
|
||||
if (radius <= 0) return
|
||||
|
||||
for (ring in 1..radius) {
|
||||
val ringValue = radius - ring + 1
|
||||
for (outerTile in tile.getTilesAtDistance(ring)) {
|
||||
val data = tileData[outerTile.position]!!
|
||||
when (type) {
|
||||
ImpactType.Marble,
|
||||
ImpactType.MinorCiv -> data.impacts[type] = 1
|
||||
ImpactType.Fish -> {
|
||||
if (data.impacts.containsKey(type))
|
||||
data.impacts[type] = min(10, max(ringValue, data.impacts[type]!!) + 1)
|
||||
else
|
||||
data.impacts[type] = ringValue
|
||||
}
|
||||
else -> {
|
||||
if (data.impacts.containsKey(type))
|
||||
data.impacts[type] = min(50, max(ringValue, data.impacts[type]!!) + 2)
|
||||
else
|
||||
data.impacts[type] = ringValue
|
||||
}
|
||||
}
|
||||
if (data.impacts.containsKey(type))
|
||||
data.impacts[type] = min(50, max(ringValue, data.impacts[type]!!) + 2)
|
||||
else
|
||||
data.impacts[type] = ringValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @return a fake unique with the same conditionals, but sorted alphabetically.
|
||||
* Used to save some memory and time when building resource lists. */
|
||||
private fun anonymizeUnique(unique: Unique) = Unique(
|
||||
"RULE" + unique.conditionals.sortedBy { it.text }.joinToString(prefix = " ", separator = " ") { "<" + it.text + ">" })
|
||||
|
||||
/** @return a fake unique with conditionals that will satisfy the same conditions as terrainsCanBeFoundOn */
|
||||
private fun getTerrainRule(terrain: Terrain): Unique {
|
||||
return if (terrain.type == TerrainType.TerrainFeature) {
|
||||
if (terrain.hasUnique(UniqueType.VisibilityElevation))
|
||||
Unique("RULE <in [${terrain.name}] tiles>")
|
||||
else
|
||||
Unique("RULE <in [${terrain.name}] tiles> " + ruleset.terrains.values
|
||||
.filter { it.type == TerrainType.TerrainFeature && it.hasUnique(UniqueType.VisibilityElevation) }
|
||||
.joinToString(separator = " ") { "<in tiles without [${it.name}]>" })
|
||||
} else
|
||||
Unique("RULE <in [Featureless] [${terrain.name}] tiles>")
|
||||
}
|
||||
|
||||
private fun isWaterOnlyResource(resource: TileResource) = resource.terrainsCanBeFoundOn
|
||||
.all { terrainName -> ruleset.terrains[terrainName]!!.type == TerrainType.Water }
|
||||
|
||||
enum class ImpactType {
|
||||
Strategic,
|
||||
Luxury,
|
||||
Bonus,
|
||||
Fish,
|
||||
MinorCiv,
|
||||
NaturalWonder,
|
||||
Marble,
|
||||
}
|
||||
|
||||
// Holds a bunch of tile info that is only interesting during map gen
|
||||
|
@ -87,8 +87,13 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
|
||||
state.ourCombatant != null && state.ourCombatant.getHealth() > condition.params[0].toInt()
|
||||
UniqueType.ConditionalBelowHP ->
|
||||
state.ourCombatant != null && state.ourCombatant.getHealth() < condition.params[0].toInt()
|
||||
UniqueType.ConditionalInTiles ->
|
||||
UniqueType.ConditionalInTiles,
|
||||
UniqueType.ConditionalFightingInTiles ->
|
||||
state.attackedTile != null && state.attackedTile.matchesFilter(condition.params[0])
|
||||
UniqueType.ConditionalInTilesAnd ->
|
||||
state.attackedTile != null && state.attackedTile.matchesFilter(condition.params[0]) && state.attackedTile.matchesFilter(condition.params[1])
|
||||
UniqueType.ConditionalInTilesNot ->
|
||||
state.attackedTile != null && !state.attackedTile.matchesFilter(condition.params[0])
|
||||
UniqueType.ConditionalVsLargerCiv -> {
|
||||
val yourCities = state.civInfo?.cities?.size ?: 1
|
||||
val theirCities = state.theirCombatant?.getCivInfo()?.cities?.size ?: 0
|
||||
|
@ -118,7 +118,8 @@ enum class UniqueParameterType(val parameterName:String) {
|
||||
TerrainFilter("terrainFilter") {
|
||||
private val knownValues = setOf("All",
|
||||
"Coastal", "River", "Open terrain", "Rough terrain", "Water resource",
|
||||
"Foreign Land", "Foreign", "Friendly Land", "Friendly", "Enemy Land", "Enemy")
|
||||
"Foreign Land", "Foreign", "Friendly Land", "Friendly", "Enemy Land", "Enemy",
|
||||
"Featureless", "Fresh Water")
|
||||
override fun getErrorSeverity(parameterText: String, ruleset: Ruleset):
|
||||
UniqueType.UniqueComplianceErrorSeverity? {
|
||||
if (parameterText in knownValues) return null
|
||||
|
@ -299,19 +299,24 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
|
||||
UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
RegionRequireFirstLessThanSecond("A Region can not contain more [simpleTerrain] tiles than [simpleTerrain] tiles", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
IgnoreBaseTerrainForRegion("Base Terrain on this tile is not counted for Region determination", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
RegionExtraResource("Starts in regions of this type receive an extra [resource]", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
BlocksResources("Never receives any resources", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
|
||||
HasQuality("Considered [terrainQuality] when determining start locations", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
|
||||
LuxuryWeighting("Appears in [regionType] regions with weight [amount]", UniqueTarget.Resource, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
LuxuryWeightingForCityStates("Appears near City States with weight [amount]", UniqueTarget.Resource, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
ResourceWeighting("Generated with weight [amount]", UniqueTarget.Resource, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
MinorDepositWeighting("Minor deposits generated with weight [amount]", UniqueTarget.Resource, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
LuxuryWeightingForCityStates("Generated near City States with weight [amount]", UniqueTarget.Resource, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
LuxurySpecialPlacement("Special placement during map generation", UniqueTarget.Resource, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
ResourceFrequency("Generated on every [amount] tiles", UniqueTarget.Resource, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
|
||||
OverrideDepositAmountOnTileFilter("Deposits in [tileFilter] tiles always provide [amount] resources", UniqueTarget.Resource),
|
||||
StrategicBalanceResource("Guaranteed with Strategic Balance resource option", UniqueTarget.Resource),
|
||||
|
||||
NoNaturalGeneration("Doesn't generate naturally", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
NoNaturalGeneration("Doesn't generate naturally", UniqueTarget.Terrain, UniqueTarget.Resource, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
TileGenerationConditions("Occurs at temperature between [amount] and [amount] and humidity between [amount] and [amount]", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
OccursInChains("Occurs in chains at high elevations", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
OccursInGroups("Occurs in groups around high elevations", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
MajorStrategicFrequency("Every [amount] tiles with this terrain will receive a major deposit of a strategic resource.", UniqueTarget.Terrain, flags = listOf(UniqueFlag.HideInCivilopedia)),
|
||||
|
||||
RareFeature("Rare feature", UniqueTarget.Terrain),
|
||||
|
||||
@ -384,7 +389,7 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
|
||||
ConditionalVsLargerCiv("when fighting units from a Civilization with more Cities than you", UniqueTarget.Conditional),
|
||||
ConditionalAttacking("when attacking", UniqueTarget.Conditional),
|
||||
ConditionalDefending("when defending", UniqueTarget.Conditional),
|
||||
ConditionalInTiles("when fighting in [tileFilter] tiles", UniqueTarget.Conditional),
|
||||
ConditionalFightingInTiles("when fighting in [tileFilter] tiles", UniqueTarget.Conditional),
|
||||
ConditionalForeignContinent("on foreign continents", UniqueTarget.Conditional),
|
||||
ConditionalAboveHP("when above [amount] HP", UniqueTarget.Conditional),
|
||||
ConditionalBelowHP("when below [amount] HP", UniqueTarget.Conditional),
|
||||
@ -392,6 +397,9 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
|
||||
/////// tile conditionals
|
||||
ConditionalNeighborTiles("with [amount] to [amount] neighboring [tileFilter] tiles", UniqueTarget.Conditional),
|
||||
ConditionalNeighborTilesAnd("with [amount] to [amount] neighboring [tileFilter] [tileFilter] tiles", UniqueTarget.Conditional),
|
||||
ConditionalInTiles("in [tileFilter] tiles", UniqueTarget.Conditional),
|
||||
ConditionalInTilesAnd("in [tileFilter] [tileFilter] tiles", UniqueTarget.Conditional),
|
||||
ConditionalInTilesNot("in tiles without [tileFilter]", UniqueTarget.Conditional),
|
||||
|
||||
/////// area conditionals
|
||||
ConditionalOnWaterMaps("on water maps", UniqueTarget.Conditional),
|
||||
|
@ -657,7 +657,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
it.isOfType(UniqueType.ConditionalVsCity) // City Attack - half the bonus
|
||||
|| it.isOfType(UniqueType.ConditionalAttacking) // Attack - half the bonus
|
||||
|| it.isOfType(UniqueType.ConditionalDefending) // Defense - half the bonus
|
||||
|| it.isOfType(UniqueType.ConditionalInTiles) } // Bonus in terrain or feature - half the bonus
|
||||
|| it.isOfType(UniqueType.ConditionalFightingInTiles) } // Bonus in terrain or feature - half the bonus
|
||||
) {
|
||||
power *= (unique.params[0].toInt() / 2f).toPercent()
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ class MapParametersTable(
|
||||
private var customWorldSizeTable = Table ()
|
||||
private var hexagonalSizeTable = Table()
|
||||
private var rectangularSizeTable = Table()
|
||||
lateinit var resourceSelectBox: TranslatedSelectBox
|
||||
private lateinit var noRuinsCheckbox: CheckBox
|
||||
private lateinit var noNaturalWondersCheckbox: CheckBox
|
||||
private lateinit var worldWrapCheckbox: CheckBox
|
||||
@ -47,6 +48,7 @@ class MapParametersTable(
|
||||
addMapShapeSelectBox()
|
||||
addMapTypeSelectBox()
|
||||
addWorldSizeTable()
|
||||
addResourceSelectBox()
|
||||
addWrappedCheckBoxes()
|
||||
addAdvancedSettings()
|
||||
}
|
||||
@ -161,6 +163,25 @@ class MapParametersTable(
|
||||
mapParameters.mapSize = MapSizeNew(worldSizeSelectBox.selected.value)
|
||||
}
|
||||
|
||||
private fun addResourceSelectBox() {
|
||||
val mapTypes = listOfNotNull(
|
||||
MapResources.sparse,
|
||||
MapResources.default,
|
||||
MapResources.abundant,
|
||||
MapResources.strategicBalance,
|
||||
MapResources.legendaryStart
|
||||
)
|
||||
|
||||
resourceSelectBox = TranslatedSelectBox(mapTypes, mapParameters.mapResources, skin)
|
||||
|
||||
resourceSelectBox.onChange {
|
||||
mapParameters.mapResources = resourceSelectBox.selected.value
|
||||
}
|
||||
|
||||
add("{Resource Setting}:".toLabel()).left()
|
||||
add(resourceSelectBox).fillX().row()
|
||||
}
|
||||
|
||||
private fun Table.addNoRuinsCheckbox() {
|
||||
noRuinsCheckbox = "No Ancient Ruins".toCheckBox(mapParameters.noRuins) {
|
||||
mapParameters.noRuins = it
|
||||
|
Reference in New Issue
Block a user