update
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 834 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 937 B |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 831 B After Width: | Height: | Size: 509 B |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 852 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 590 B After Width: | Height: | Size: 473 B |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 716 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 936 B After Width: | Height: | Size: 731 B |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1,010 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 675 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 878 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 853 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 542 B After Width: | Height: | Size: 414 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 3 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 722 B |
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 922 B |
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 961 B |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 937 B |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 891 B |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1,007 KiB After Width: | Height: | Size: 1,015 KiB |
|
@ -28,12 +28,12 @@
|
||||||
{
|
{
|
||||||
name:"Stone Works",
|
name:"Stone Works",
|
||||||
happiness:1,
|
happiness:1,
|
||||||
production:1
|
production:1,
|
||||||
requiredNearbyImprovedResources:["Marble","Stone"]
|
requiredNearbyImprovedResources:["Marble","Stone"],
|
||||||
resourceBonusStats:{production:1},
|
resourceBonusStats:{production:1},
|
||||||
maintenance:1,
|
maintenance:1,
|
||||||
hurryCostModifier:25,
|
hurryCostModifier:25,
|
||||||
uniques:["Must not be on plains"]
|
uniques:["Must not be on plains"],
|
||||||
requiredTech:"Calendar"
|
requiredTech:"Calendar"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
culture:6,
|
culture:6,
|
||||||
isWonder:true,
|
isWonder:true,
|
||||||
greatPersonPoints:{production:1},
|
greatPersonPoints:{production:1},
|
||||||
requiredTech:"Calendar"
|
requiredTech:"Calendar",
|
||||||
quote:"'Time crumbles things; everything grows old and is forgotten under the power of time' - Aristotle"
|
quote:"'Time crumbles things; everything grows old and is forgotten under the power of time' - Aristotle"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -73,11 +73,24 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Circus",
|
name:"Circus",
|
||||||
requiredNearbyImprovedResources:["Ivory","Horses"]
|
requiredNearbyImprovedResources:["Ivory","Horses"],
|
||||||
happiness:2,
|
happiness:2,
|
||||||
hurryCostModifier:25,
|
hurryCostModifier:25,
|
||||||
requiredTech:"Trapping"
|
requiredTech:"Trapping"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
name:"Temple of Artemis",
|
||||||
|
culture:1,
|
||||||
|
isWonder:true,
|
||||||
|
greatPersonPoints:{production:1},
|
||||||
|
uniques:["+10% Growth in all Cities.","+15% Production towards Ranged Units."],
|
||||||
|
requiredTech:"Archery"
|
||||||
|
quote:"'It is not so much for its beauty that the forest makes a claim upon men's hearts, as for that subtle something, that quality of air, that emanation from old trees, that so wonderfully changes and renews a weary spirit.' - Robert Louis Stevenson"
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
{
|
{
|
||||||
name:"Walls",
|
name:"Walls",
|
||||||
cityStrength:5,
|
cityStrength:5,
|
||||||
|
@ -124,13 +137,32 @@
|
||||||
{
|
{
|
||||||
name:"Krepost",
|
name:"Krepost",
|
||||||
replaces:"Barracks",
|
replaces:"Barracks",
|
||||||
uniqueTo:"Russia"
|
uniqueTo:"Russia",
|
||||||
xpForNewUnits:15,
|
xpForNewUnits:15,
|
||||||
hurryCostModifier:25,
|
hurryCostModifier:25,
|
||||||
maintenance:1,
|
maintenance:1,
|
||||||
uniques:["Culture and Gold costs of acquiring new tiles reduced by 25% in this city"]
|
uniques:["Culture and Gold costs of acquiring new tiles reduced by 25% in this city"],
|
||||||
requiredTech:"Bronze Working"
|
requiredTech:"Bronze Working"
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
name:"Statue of Zeus",
|
||||||
|
culture:1,
|
||||||
|
isWonder:true,
|
||||||
|
uniques:["+15% Combat Strenght when attacking Cities."],
|
||||||
|
requiredTech:"Bronze Working"
|
||||||
|
quote:"'He spoke, the son of Kronos, and nodded his head with the dark brows, and the immortally anointed hair of the great god swept from his divine head, and all Olympos was shaken' - The Iliad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:"Mausoleum of Halicarnassus",
|
||||||
|
culture:1,
|
||||||
|
greatPersonPoints:{gold:1},
|
||||||
|
isWonder:true,
|
||||||
|
uniques:["Gain 100 Gold when you use a Great Person.","+2 Gold from every source of Marble and Stone"],
|
||||||
|
requiredTech:"Masonry"
|
||||||
|
quote:"'The whole earth is the tomb of heroic men and their story is not given only on stone over their clay but abides everywhere without visible symbol woven into the stuff of other men's lives.' - Pericles"
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
// Classical Era
|
// Classical Era
|
||||||
|
|
||||||
|
@ -139,7 +171,7 @@
|
||||||
hurryCostModifier:25,
|
hurryCostModifier:25,
|
||||||
maintenance:1,
|
maintenance:1,
|
||||||
resourceBonusStats:{food:1},
|
resourceBonusStats:{food:1},
|
||||||
uniques:["Can only be built in coastal cities","+1 food from Ocean and Coast tiles"]
|
uniques:["Can only be built in coastal cities","+1 food from Ocean and Coast tiles"],
|
||||||
requiredTech:"Optics"
|
requiredTech:"Optics"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -148,14 +180,14 @@
|
||||||
greatPersonPoints:{gold:1},
|
greatPersonPoints:{gold:1},
|
||||||
isWonder:true,
|
isWonder:true,
|
||||||
providesFreeBuilding: "Lighthouse",
|
providesFreeBuilding: "Lighthouse",
|
||||||
uniques:["Can only be built in coastal cities", "All military naval units receive +1 movement and +1 sight"]
|
uniques:["Can only be built in coastal cities", "All military naval units receive +1 movement and +1 sight"],
|
||||||
requiredTech:"Optics",
|
requiredTech:"Optics",
|
||||||
quote:"'They that go down to the sea in ships, that do business in great waters; these see the works of the Lord, and his wonders in the deep.' - The Bible, Psalms 107:23-24"
|
quote:"'They that go down to the sea in ships, that do business in great waters; these see the works of the Lord, and his wonders in the deep.' - The Bible, Psalms 107:23-24"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Stable",
|
name:"Stable",
|
||||||
maintenance:1,
|
maintenance:1,
|
||||||
requiredNearbyImprovedResources:["Horses","Sheep","Cattle"]
|
requiredNearbyImprovedResources:["Horses","Sheep","Cattle"],
|
||||||
resourceBonusStats:{production:1},
|
resourceBonusStats:{production:1},
|
||||||
hurryCostModifier:25,
|
hurryCostModifier:25,
|
||||||
uniques:["+15% Production when building Mounted Units in this city"]
|
uniques:["+15% Production when building Mounted Units in this city"]
|
||||||
|
@ -269,6 +301,18 @@
|
||||||
hurryCostModifier:25,
|
hurryCostModifier:25,
|
||||||
requiredTech:"Currency"
|
requiredTech:"Currency"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
{ //Must be built in or near Desert
|
||||||
|
name:"Petra",
|
||||||
|
culture:1,
|
||||||
|
isWonder:true,
|
||||||
|
greatPersonPoints:{production:1},
|
||||||
|
uniques:["+1 Food and +1 Production from all worked Desert tiles in the City (except Flood plains).","+6 Culture when discovering Archeology."],
|
||||||
|
requiredTech:"Currency"
|
||||||
|
quote:"'...who drinks the water I shall give him, says the Lord, will have a spring inside him welling up for eternal life. Let them bring me to your holy mountain in the place where you dwell. Across the desert and through the mountain to the Canyon of the Crescent Moon...' - Indiana Jones"
|
||||||
|
},
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
name:"Aqueduct",
|
name:"Aqueduct",
|
||||||
maintenance:1,
|
maintenance:1,
|
||||||
|
|
|
@ -2,96 +2,160 @@
|
||||||
{
|
{
|
||||||
name:"Settler",
|
name:"Settler",
|
||||||
baseHappiness:15,
|
baseHappiness:15,
|
||||||
|
extraHappinessPerLuxury:1,
|
||||||
researchCostModifier:0.9,
|
researchCostModifier:0.9,
|
||||||
|
unitCostModifier:0.5,
|
||||||
|
buildingCostModifier:0.5,
|
||||||
|
policyCostModifier:0.5,
|
||||||
unhappinessModifier:0.4,
|
unhappinessModifier:0.4,
|
||||||
aiCityGrowthModifier:1.6, // that is to say it'll take them 1.6 times as long to grow the city
|
aiCityGrowthModifier:1.6, // that is to say it'll take them 1.6 times as long to grow the city
|
||||||
|
aiUnitCostModifier:1.75,
|
||||||
|
aiBuildingCostModifier:1.6,
|
||||||
|
aiWonderCostModifier:1.6,
|
||||||
|
aiBuildingMaintenanceModifier:1,
|
||||||
aiUnitMaintenanceModifier:1,
|
aiUnitMaintenanceModifier:1,
|
||||||
aiYieldModifier:0.6, // Replaces "Construction rate" and "Create rate" in original config
|
|
||||||
aiFreeTechs:[],
|
aiFreeTechs:[],
|
||||||
|
aiFreeUnits:[],
|
||||||
aiUnhappinessModifier:1,
|
aiUnhappinessModifier:1,
|
||||||
aisExchangeTechs:false
|
aisExchangeTechs:false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Chieftain",
|
name:"Chieftain",
|
||||||
baseHappiness:12,
|
baseHappiness:12,
|
||||||
|
extraHappinessPerLuxury:1,
|
||||||
researchCostModifier:0.95,
|
researchCostModifier:0.95,
|
||||||
|
unitCostModifier:0.67,
|
||||||
|
buildingCostModifier:0.67,
|
||||||
|
policyCostModifier:0.67,
|
||||||
unhappinessModifier:0.6,
|
unhappinessModifier:0.6,
|
||||||
aiCityGrowthModifier:1.3,
|
aiCityGrowthModifier:1.3,
|
||||||
|
aiUnitCostModifier:1.3,
|
||||||
|
aiBuildingCostModifier:1.3,
|
||||||
|
aiWonderCostModifier:1.3,
|
||||||
|
aiBuildingMaintenanceModifier:1,
|
||||||
aiUnitMaintenanceModifier:1,
|
aiUnitMaintenanceModifier:1,
|
||||||
aiYieldModifier:0.75,
|
|
||||||
aiFreeTechs:[],
|
aiFreeTechs:[],
|
||||||
|
aiFreeUnits:[],
|
||||||
aiUnhappinessModifier:1,
|
aiUnhappinessModifier:1,
|
||||||
aisExchangeTechs:false
|
aisExchangeTechs:false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Warlord",
|
name:"Warlord",
|
||||||
baseHappiness:12,
|
baseHappiness:12,
|
||||||
|
extraHappinessPerLuxury:0,
|
||||||
researchCostModifier:1,
|
researchCostModifier:1,
|
||||||
|
unitCostModifier:0.85,
|
||||||
|
buildingCostModifier:0.85,
|
||||||
|
policyCostModifier:0.85,
|
||||||
unhappinessModifier:0.75,
|
unhappinessModifier:0.75,
|
||||||
aiCityGrowthModifier:1.1,
|
aiCityGrowthModifier:1.1,
|
||||||
|
aiUnitCostModifier:1.1,
|
||||||
|
aiBuildingCostModifier:1.1,
|
||||||
|
aiWonderCostModifier:1.1,
|
||||||
|
aiBuildingMaintenanceModifier:1,
|
||||||
aiUnitMaintenanceModifier:1,
|
aiUnitMaintenanceModifier:1,
|
||||||
aiYieldModifier:0.9,
|
|
||||||
aiFreeTechs:[],
|
aiFreeTechs:[],
|
||||||
|
aiFreeUnits:[],
|
||||||
aiUnhappinessModifier:1,
|
aiUnhappinessModifier:1,
|
||||||
aisExchangeTechs:false
|
aisExchangeTechs:false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Prince",
|
name:"Prince",
|
||||||
baseHappiness:9,
|
baseHappiness:9,
|
||||||
|
extraHappinessPerLuxury:0,
|
||||||
researchCostModifier:1,
|
researchCostModifier:1,
|
||||||
|
unitCostModifier:1,
|
||||||
|
buildingCostModifier:1,
|
||||||
|
policyCostModifier:1,
|
||||||
unhappinessModifier:1,
|
unhappinessModifier:1,
|
||||||
aiCityGrowthModifier:1,
|
aiCityGrowthModifier:1,
|
||||||
|
aiUnitCostModifier:1,
|
||||||
|
aiBuildingCostModifier:1,
|
||||||
|
aiWonderCostModifier:1,
|
||||||
|
aiBuildingMaintenanceModifier:1,
|
||||||
aiUnitMaintenanceModifier:0.85,
|
aiUnitMaintenanceModifier:0.85,
|
||||||
aiYieldModifier:1,
|
|
||||||
aiFreeTechs:[],
|
aiFreeTechs:[],
|
||||||
|
aiFreeUnits:[],
|
||||||
aiUnhappinessModifier:1,
|
aiUnhappinessModifier:1,
|
||||||
aisExchangeTechs:true
|
aisExchangeTechs:true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"King",
|
name:"King",
|
||||||
baseHappiness:9,
|
baseHappiness:9,
|
||||||
researchCostModifier:1.1,
|
extraHappinessPerLuxury:0,
|
||||||
|
researchCostModifier:1,
|
||||||
|
unitCostModifier:1,
|
||||||
|
buildingCostModifier:1,
|
||||||
|
policyCostModifier:1,
|
||||||
unhappinessModifier:1,
|
unhappinessModifier:1,
|
||||||
aiCityGrowthModifier:0.9,
|
aiCityGrowthModifier:0.9,
|
||||||
|
aiUnitCostModifier:0.85,
|
||||||
|
aiBuildingCostModifier:0.85,
|
||||||
|
aiWonderCostModifier:1,
|
||||||
|
aiBuildingMaintenanceModifier:0.85,
|
||||||
aiUnitMaintenanceModifier:0.8,
|
aiUnitMaintenanceModifier:0.8,
|
||||||
aiYieldModifier:1.15,
|
|
||||||
aiFreeTechs:["Pottery"],
|
aiFreeTechs:["Pottery"],
|
||||||
|
aiFreeUnits:["Warrior"],
|
||||||
aiUnhappinessModifier:0.9,
|
aiUnhappinessModifier:0.9,
|
||||||
aisExchangeTechs:true
|
aisExchangeTechs:true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Emperor",
|
name:"Emperor",
|
||||||
baseHappiness:9,
|
baseHappiness:9,
|
||||||
researchCostModifier:1.2,
|
extraHappinessPerLuxury:0,
|
||||||
|
researchCostModifier:1,
|
||||||
|
unitCostModifier:1,
|
||||||
|
buildingCostModifier:1,
|
||||||
|
policyCostModifier:1,
|
||||||
unhappinessModifier:1,
|
unhappinessModifier:1,
|
||||||
aiCityGrowthModifier:0.85,
|
aiCityGrowthModifier:0.85,
|
||||||
|
aiUnitCostModifier:0.8,
|
||||||
|
aiBuildingCostModifier:0.8,
|
||||||
|
aiWonderCostModifier:1,
|
||||||
|
aiBuildingMaintenanceModifier:0.8,
|
||||||
aiUnitMaintenanceModifier:0.75,
|
aiUnitMaintenanceModifier:0.75,
|
||||||
aiYieldModifier:1.25,
|
|
||||||
aiFreeTechs:["Pottery","Animal Husbandry"],
|
aiFreeTechs:["Pottery","Animal Husbandry"],
|
||||||
|
aiFreeUnits:["Warrior", "Scout"],
|
||||||
aiUnhappinessModifier:0.85,
|
aiUnhappinessModifier:0.85,
|
||||||
aisExchangeTechs:true
|
aisExchangeTechs:true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Immortal",
|
name:"Immortal",
|
||||||
baseHappiness:9,
|
baseHappiness:9,
|
||||||
researchCostModifier:1.3,
|
extraHappinessPerLuxury:0,
|
||||||
|
researchCostModifier:1,
|
||||||
|
unitCostModifier:1,
|
||||||
|
buildingCostModifier:1,
|
||||||
|
policyCostModifier:1,
|
||||||
unhappinessModifier:1,
|
unhappinessModifier:1,
|
||||||
aiCityGrowthModifier:0.75,
|
aiCityGrowthModifier:0.75,
|
||||||
|
aiUnitCostModifier:0.65,
|
||||||
|
aiBuildingCostModifier:0.65,
|
||||||
|
aiWonderCostModifier:1,
|
||||||
|
aiBuildingMaintenanceModifier:0.65,
|
||||||
aiUnitMaintenanceModifier:0.65,
|
aiUnitMaintenanceModifier:0.65,
|
||||||
aiYieldModifier:1.5,
|
|
||||||
aiFreeTechs:["Pottery","Animal Husbandry","Mining"],
|
aiFreeTechs:["Pottery","Animal Husbandry","Mining"],
|
||||||
|
aiFreeUnits:["Warrior", "Warrior", "Worker", "Scout"],
|
||||||
aiUnhappinessModifier:0.75,
|
aiUnhappinessModifier:0.75,
|
||||||
aisExchangeTechs:true
|
aisExchangeTechs:true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Deity",
|
name:"Deity",
|
||||||
baseHappiness:9,
|
baseHappiness:9,
|
||||||
researchCostModifier:1.5,
|
extraHappinessPerLuxury:0,
|
||||||
|
researchCostModifier:1,
|
||||||
|
unitCostModifier:1,
|
||||||
|
buildingCostModifier:1,
|
||||||
|
policyCostModifier:1,
|
||||||
unhappinessModifier:1,
|
unhappinessModifier:1,
|
||||||
aiCityGrowthModifier:0.6,
|
aiCityGrowthModifier:0.6,
|
||||||
|
aiUnitCostModifier:0.5,
|
||||||
|
aiBuildingCostModifier:0.5,
|
||||||
|
aiWonderCostModifier:1,
|
||||||
|
aiBuildingMaintenanceModifier:0.5,
|
||||||
aiUnitMaintenanceModifier:0.5,
|
aiUnitMaintenanceModifier:0.5,
|
||||||
aiYieldModifier:2,
|
|
||||||
aiFreeTechs:["Pottery","Animal Husbandry","Mining","The Wheel"],
|
aiFreeTechs:["Pottery","Animal Husbandry","Mining","The Wheel"],
|
||||||
|
aiFreeUnits:["Settler", "Warrior", "Warrior", "Worker", "Worker", "Scout"],
|
||||||
aiUnhappinessModifier:0.6,
|
aiUnhappinessModifier:0.6,
|
||||||
aisExchangeTechs:true
|
aisExchangeTechs:true
|
||||||
}
|
}
|
||||||
|
|
|
@ -551,7 +551,7 @@
|
||||||
|
|
||||||
declaringWar:"Sei una peste per Madre Terra! Preparati a combattere!"
|
declaringWar:"Sei una peste per Madre Terra! Preparati a combattere!"
|
||||||
attacked:"Creatura maligna! I miei prodi ti massacreranno!"
|
attacked:"Creatura maligna! I miei prodi ti massacreranno!"
|
||||||
defeated:"Ci avrai anche sconfitti... ma i nostri spiriti sono immortali! Tra cento, mille anni torneremo!"
|
defeated:"Ci avrai anche sconfitti, e io accetto il mio destino... ma i nostri spiriti sono immortali! Tra cento, mille anni, noi torneremo!"
|
||||||
introduction:"Saluti, straniero. Sono Hiawatha, e parlo per il popolo degli Irochesi. Cerchiamo la pace con tutti, ma siamo anche abili guerrieri."
|
introduction:"Saluti, straniero. Sono Hiawatha, e parlo per il popolo degli Irochesi. Cerchiamo la pace con tutti, ma siamo anche abili guerrieri."
|
||||||
|
|
||||||
neutralHello:"Buongiorno."
|
neutralHello:"Buongiorno."
|
||||||
|
@ -586,23 +586,23 @@
|
||||||
startIntroPart1: "La benedizione del cielo scenda su di te, oh amato re Dario di Persia! Tu sei a capo di un popolo forte e saggio. All'alba del mondo, il grande capo persiano Ciro si rivoltò contro l'impero dei Medi, che nel 550 a.C. scomparve del tutto. Grazie alla sua astuta diplomazia e alla sua prodezza militare, il grande Ciro conquistò la florida Lidia e la potente Babilonia, mentre qualche anno più tardi suo figlio Cambise s'impadronì anche dell'orgoglioso Egitto. Col tempo i persiani si espansero fino alla lontana Macedonia, bussando alla porta delle giovani città-stato greche. A lungo avrebbe prosperato la Persia, fino all'arrivo di quello zotico Alessandro di Macedonia, venuto su dal nulla, che distrusse il nostro glorioso impero con un'unica campagna militare senza precedenti."
|
startIntroPart1: "La benedizione del cielo scenda su di te, oh amato re Dario di Persia! Tu sei a capo di un popolo forte e saggio. All'alba del mondo, il grande capo persiano Ciro si rivoltò contro l'impero dei Medi, che nel 550 a.C. scomparve del tutto. Grazie alla sua astuta diplomazia e alla sua prodezza militare, il grande Ciro conquistò la florida Lidia e la potente Babilonia, mentre qualche anno più tardi suo figlio Cambise s'impadronì anche dell'orgoglioso Egitto. Col tempo i persiani si espansero fino alla lontana Macedonia, bussando alla porta delle giovani città-stato greche. A lungo avrebbe prosperato la Persia, fino all'arrivo di quello zotico Alessandro di Macedonia, venuto su dal nulla, che distrusse il nostro glorioso impero con un'unica campagna militare senza precedenti."
|
||||||
startIntroPart2: "Dario, il tuo popolo si rivolge a te per tornare ai giorni della grande e potente Persia! L'impero dei tuoi antenati deve rivivere per trionfare sui suoi nemici e riportare la pace e l'ordine nel mondo. Oh re, risponderai alla chiamata? Riuscirai a plasmare una civiltà in grado di superare la prova del tempo?"
|
startIntroPart2: "Dario, il tuo popolo si rivolge a te per tornare ai giorni della grande e potente Persia! L'impero dei tuoi antenati deve rivivere per trionfare sui suoi nemici e riportare la pace e l'ordine nel mondo. Oh re, risponderai alla chiamata? Riuscirai a plasmare una civiltà in grado di superare la prova del tempo?"
|
||||||
|
|
||||||
declaringWar:"La tua contiuna esistenza rappresenta un imbarazzo per tutti i leader del mondo! Farò loro un favore distruggendoti!"
|
declaringWar:"La tua continua esistenza rappresenta un imbarazzo per tutti i leader del mondo! Farò loro un favore distruggendoti!"
|
||||||
attacked:"Non hai forse udito le storie sulla potenza e sulla grandezza delle mie armate? Forse, se le vedrai, ci penserai due volte prima di affrontarmi!"
|
attacked:"Non hai forse udito le storie sulla potenza e sulla grandezza delle mie armate? Forse, se le vedrai, ci penserai due volte prima di affrontarmi!"
|
||||||
defeated:"Canaglia! Che tu sia maledetto! Il mondo ricorderà a lungo l'errore che hai commesso!"
|
defeated:"Canaglia! Che Ahura Mazda ti maledica! Il mondo ricorderà a lungo l'errore che hai commesso!"
|
||||||
introduction:"Che la pace scenda su di te! Io sono Dario, il grande re dei re della Persia... ma sono certo che tu già lo sappia."
|
introduction:"Che la pace scenda su di te! Io sono Dario, il grande re dei re della Persia... ma sono certo che tu già lo sappia."
|
||||||
|
|
||||||
neutralHello:"Good day to you!"
|
neutralHello:"Buona giornata!"
|
||||||
neutralLetsHearIt:["Go on.","You said?"]
|
neutralLetsHearIt:["Va' avanti.","Parla."]
|
||||||
neutralNo:["You are not serious!","Not good enough."]
|
neutralNo:["È uno scherzo?","Non basta."]
|
||||||
neutralYes:["Good!","Certainly.","Agreed!"]
|
neutralYes:["Va bene!","Certamente!","D'accordo!"]
|
||||||
|
|
||||||
hateHello:"Ahh... you..."
|
hateHello:"Ahh... sei tu..."
|
||||||
hateLetsHearIt:["I'm listening.","Go on!"]
|
hateLetsHearIt:["Sono tutto orecchi.","Vai avanti!"]
|
||||||
hateNo:["Io dico... no!","Certo che no!"]
|
hateNo:["Io dico di no!","Certo che no!"]
|
||||||
hateYes:["Va bene!","D'accordo."]
|
hateYes:["Va bene!","D'accordo."]
|
||||||
|
|
||||||
afterPeace:"Sembra che mi convenga finirla qui..."
|
afterPeace:"Sembra che mi convenga finirla qui... Mettiamoci una pietra sopra."
|
||||||
tradeRequest:"Nella mia infinita misericordia, ti faccio questa offerta. Di certo, sarai d'accordo?"
|
tradeRequest:"Nella mia infinita misericordia, ti faccio questa offerta. Di certo, accetterai?"
|
||||||
|
|
||||||
outerColor:[255,0,0],
|
outerColor:[255,0,0],
|
||||||
innerColor:[255,255,0],
|
innerColor:[255,255,0],
|
||||||
|
|
|
@ -83,6 +83,26 @@
|
||||||
Italian:"'Il tempo sgretola le cose; davanti al suo potere tutto invecchia e viene dimenticato.' - Aristotele"
|
Italian:"'Il tempo sgretola le cose; davanti al suo potere tutto invecchia e viene dimenticato.' - Aristotele"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
"Temple of Artemis":{
|
||||||
|
Italian:"Tempio di Artemide"
|
||||||
|
}
|
||||||
|
|
||||||
|
"'It is not so much for its beauty that the forest makes a claim upon men's hearts, as for that subtle something, that quality of air, that emanation from old trees, that so wonderfully changes and renews a weary spirit.' - Robert Louis Stevenson":{
|
||||||
|
Italian:"'Non è tanto con la sua bellezza che la foresta tocca il cuore degli uomini, ma con un'indefinibile sottigliezza, una certa qualità dell'aria, con l'emanazione degli antichi alberi, che così meravigliosamente muta e rinnova uno spirito fiaccato.' - Robert Louis Stevenson"
|
||||||
|
}
|
||||||
|
|
||||||
|
"+10% Growth in all Cities":{
|
||||||
|
Italian:"+10% Crescita in tutte le Città"
|
||||||
|
}
|
||||||
|
|
||||||
|
"+15% Production towards Ranged Units":{
|
||||||
|
Italian:"+15% Produzione per le unità a distanza"
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
"Library":{
|
"Library":{
|
||||||
Italian:"Biblioteca"
|
Italian:"Biblioteca"
|
||||||
Russian:"Библиотека"
|
Russian:"Библиотека"
|
||||||
|
@ -180,7 +200,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
"'O, let not the pains of death which come upon thee enter into my body. I am the god Tem, and I am the foremost part of the sky, and the power which protecteth me is that which is with all the gods forever.' - The Book of the Dead, translated by Sir Ernest Alfred Wallis Budge":{
|
"'O, let not the pains of death which come upon thee enter into my body. I am the god Tem, and I am the foremost part of the sky, and the power which protecteth me is that which is with all the gods forever.' - The Book of the Dead, translated by Sir Ernest Alfred Wallis Budge":{
|
||||||
Italian:"''Oh, non lasciare che i dolori della morte che piombano su di te entrino nel mio corpo. Io sono il dio Tem, e risiedo nella parte più importante del cielo, e il potere che mi protegge è quello che si accompagna per sempre a tutti gli dèi.' - Il Libro dei Morti, traduzione di Sir Ernest Alfred Wallis Budge"
|
Italian:"'Oh, non lasciare che i dolori della morte che piombano su di te entrino nel mio corpo. Io sono il dio Tem, e risiedo nella parte più importante del cielo, e il potere che mi protegge è quello che si accompagna per sempre a tutti gli dèi.' - Il Libro dei Morti, traduzione di Sir Ernest Alfred Wallis Budge"
|
||||||
}
|
}
|
||||||
|
|
||||||
"Worker construction increased 25%":{ //typo? Removed one instance of "Worker construction increased"
|
"Worker construction increased 25%":{ //typo? Removed one instance of "Worker construction increased"
|
||||||
|
@ -233,7 +253,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
"Culture and Gold costs of acquiring new tiles reduced by 25% in this city":{
|
"Culture and Gold costs of acquiring new tiles reduced by 25% in this city":{
|
||||||
Italian:"-25% costi in Cultura e Oro nell'acquisto di nuove celle nella città"
|
Italian:"-25% costi in Cultura e Oro nell'acquisto di nuove celle nella Città"
|
||||||
Romanian:"Costurile în Cultură și Aur pentru cumpărarea noilor celule în acest oraș sunt reduse cu 25%"
|
Romanian:"Costurile în Cultură și Aur pentru cumpărarea noilor celule în acest oraș sunt reduse cu 25%"
|
||||||
Spanish:"El coste de comprar terrenos en esta ciudad se reduce un 25%"
|
Spanish:"El coste de comprar terrenos en esta ciudad se reduce un 25%"
|
||||||
Simplified_Chinese:"所在城市扩展新地块所需文化和金钱花费-25%"
|
Simplified_Chinese:"所在城市扩展新地块所需文化和金钱花费-25%"
|
||||||
|
@ -454,7 +474,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
"+15% Production when building Mounted Units in this city":{
|
"+15% Production when building Mounted Units in this city":{
|
||||||
Italian:"+15% Produzione nella città nel reclutare unità a cavallo"
|
Italian:"+15% Produzione per le unità a cavallo"
|
||||||
German:"+15% Produktion beim Ausbilden von berittenen Einheiten in dieser Stadt"
|
German:"+15% Produktion beim Ausbilden von berittenen Einheiten in dieser Stadt"
|
||||||
French:"+15% Production lorsqu'une unité montée est produite dans cette ville"
|
French:"+15% Production lorsqu'une unité montée est produite dans cette ville"
|
||||||
Simplified_Chinese:"组建骑乘单位时产能积累速率+15%"
|
Simplified_Chinese:"组建骑乘单位时产能积累速率+15%"
|
||||||
|
@ -506,6 +526,10 @@
|
||||||
Polish:"+15% siły bojowej do ataku na miasta"
|
Polish:"+15% siły bojowej do ataku na miasta"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"'He spoke, the son of Kronos, and nodded his head with the dark brows, and the immortally anointed hair of the great god swept from his divine head, and all Olympos was shaken' - The Iliad":{
|
||||||
|
Italian:"'Così parlò, il figlio di Crono, e con le nere sopracciglia accennò; le chiome immortali del sire si scompigliarono sul capo divino: scosse tutto l'Olimpo.' - L'Iliade"
|
||||||
|
}
|
||||||
|
|
||||||
//New Wonder: Mausoleum of Halicarnassus! Suggested by Smashfanful
|
//New Wonder: Mausoleum of Halicarnassus! Suggested by Smashfanful
|
||||||
"Mausoleum of Halicarnassus":{
|
"Mausoleum of Halicarnassus":{
|
||||||
Italian:"Mausoleo di Alicarnasso"
|
Italian:"Mausoleo di Alicarnasso"
|
||||||
|
@ -520,6 +544,30 @@
|
||||||
Simplified_Chinese:"所在城市开发的每处大理石或花岗石资源额外+2金钱"
|
Simplified_Chinese:"所在城市开发的每处大理石或花岗石资源额外+2金钱"
|
||||||
Polish:"+2 do złota z każdego złoża marmuru i kamienia"
|
Polish:"+2 do złota z każdego złoża marmuru i kamienia"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"Gain 100 Gold when you use a Great Person.":{
|
||||||
|
Italian:"Guadagni 100 Oro ogni volta che consumi un Grande Personaggio"
|
||||||
|
}
|
||||||
|
|
||||||
|
"'The whole earth is the tomb of heroic men and their story is not given only on stone over their clay but abides everywhere without visible symbol woven into the stuff of other men's lives.' - Pericles":{
|
||||||
|
Italian:"'Tutta la terra è tomba di uomini eroici; la loro storia non resta solo sulla pietra sopra la loro creta, ma si ritrova ovunque, invisibile, intessuta nella vita degli altri.' - Pericle"
|
||||||
|
}
|
||||||
|
|
||||||
|
"Petra":{
|
||||||
|
Italian:"Petra"
|
||||||
|
}
|
||||||
|
|
||||||
|
"+1 Food and +1 Production from all worked Desert tiles in the City (except Flood plains)":{
|
||||||
|
Italian:"+1 Cibo e +1 Produzione da tutte le caselle desertiche sfruttate dalla città (eccetto Terreni allagati)"
|
||||||
|
}
|
||||||
|
|
||||||
|
"+6 Culture when discovering Archeology":{
|
||||||
|
Italian:"+6 Cultura quando scopri l'Archeologia"
|
||||||
|
}
|
||||||
|
|
||||||
|
"'...who drinks the water I shall give him, says the Lord, will have a spring inside him welling up for eternal life. Let them bring me to your holy mountain in the place where you dwell. Across the desert and through the mountain to the Canyon of the Crescent Moon...' - Indiana Jones":{
|
||||||
|
Italian:"'...colui che beve l'acqua che io gli darò, dice il Signore, avrà dentro di sé una sorgente inesauribile dalla quale sgorgherà la vita eterna. Lasciate che mi conducano alla tua montagna sacra nel luogo dove dimori, attraverso il deserto e oltre la montagna, nella Gola della Luna Crecente...' - Indiana Jones"
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"Colosseum":{
|
"Colosseum":{
|
||||||
|
|
|
@ -217,7 +217,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
"An enemy [unit] has attacked our [ourUnit]":{
|
"An enemy [unit] has attacked our [ourUnit]":{
|
||||||
Italian:"Un'unità nemica [unit] ha attaccato [ourUnit]"
|
Italian:"L'unità nemica [unit] ha attaccato [ourUnit]"
|
||||||
Russian:"Наш [ourUnit] был атакован вражеским [unit]"
|
Russian:"Наш [ourUnit] был атакован вражеским [unit]"
|
||||||
French:"Un(e) [unit] ennemi(e) a attaqué [ourUnit]" // Gender sensitive
|
French:"Un(e) [unit] ennemi(e) a attaqué [ourUnit]" // Gender sensitive
|
||||||
Romanian:"Un [unit] inamic ne-a atacat un [ourUnit]"
|
Romanian:"Un [unit] inamic ne-a atacat un [ourUnit]"
|
||||||
|
@ -230,7 +230,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
"Enemy city [cityName] has attacked our [ourUnit]":{
|
"Enemy city [cityName] has attacked our [ourUnit]":{
|
||||||
Italian:"La città nemica [cityName] ha attaccato [ourUnit]"
|
Italian:"La città nemica di [cityName] ha attaccato [ourUnit]"
|
||||||
French:"La cité ennemie [cityName] a attaqué notre [ourUnit]"
|
French:"La cité ennemie [cityName] a attaqué notre [ourUnit]"
|
||||||
Russian:"Наш [ourUnit] был атакован вражеским городом [cityName]"
|
Russian:"Наш [ourUnit] был атакован вражеским городом [cityName]"
|
||||||
Simplified_Chinese:"敌方城市[cityName]攻击了我们的[ourUnit]"
|
Simplified_Chinese:"敌方城市[cityName]攻击了我们的[ourUnit]"
|
||||||
|
@ -276,7 +276,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
"Enemy city [cityName] has destroyed our [ourUnit]":{
|
"Enemy city [cityName] has destroyed our [ourUnit]":{
|
||||||
Italian:"La città nemica [cityName] ha distrutto [ourUnit]"
|
Italian:"La città nemica di [cityName] ha distrutto [ourUnit]"
|
||||||
French:"La cité ennemie [cityName] a détruit notre [ourUnit]"
|
French:"La cité ennemie [cityName] a détruit notre [ourUnit]"
|
||||||
Russian:"Наш [ourUnit] был уничтожен вражеским городом [cityName]"
|
Russian:"Наш [ourUnit] был уничтожен вражеским городом [cityName]"
|
||||||
Simplified_Chinese:"敌方城市[cityName]杀死了我们的[ourUnit]"
|
Simplified_Chinese:"敌方城市[cityName]杀死了我们的[ourUnit]"
|
||||||
|
|
|
@ -21,8 +21,8 @@ android {
|
||||||
applicationId "com.unciv.app"
|
applicationId "com.unciv.app"
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 300
|
versionCode 301
|
||||||
versionName "3.0.7"
|
versionName "3.1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Had to add this crap for Travis to build, it wanted to sign the app
|
// Had to add this crap for Travis to build, it wanted to sign the app
|
||||||
|
|
|
@ -12,6 +12,7 @@ class Constants{
|
||||||
const val hill = "Hill"
|
const val hill = "Hill"
|
||||||
const val coast = "Coast"
|
const val coast = "Coast"
|
||||||
const val plains = "Plains"
|
const val plains = "Plains"
|
||||||
|
const val lakes = "Lakes"
|
||||||
const val barbarianEncampment = "Barbarian encampment"
|
const val barbarianEncampment = "Barbarian encampment"
|
||||||
const val ancientRuins = "Ancient ruins"
|
const val ancientRuins = "Ancient ruins"
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,12 @@ class GameStarter{
|
||||||
civ.placeUnitNearTile(startingLocation.position, Constants.settler)
|
civ.placeUnitNearTile(startingLocation.position, Constants.settler)
|
||||||
civ.placeUnitNearTile(startingLocation.position, "Warrior")
|
civ.placeUnitNearTile(startingLocation.position, "Warrior")
|
||||||
civ.placeUnitNearTile(startingLocation.position, "Scout")
|
civ.placeUnitNearTile(startingLocation.position, "Scout")
|
||||||
|
|
||||||
|
if (!civ.isPlayerCivilization()) {
|
||||||
|
for (unit in gameInfo.getDifficulty().aiFreeUnits) {
|
||||||
|
civ.placeUnitNearTile(startingLocation.position, unit)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return gameInfo
|
return gameInfo
|
||||||
|
|
|
@ -167,7 +167,13 @@ class UnitAutomation{
|
||||||
if (tile.isWater) return false // can't attack water units while embarked, only land
|
if (tile.isWater) return false // can't attack water units while embarked, only land
|
||||||
if (combatant.isRanged()) return false
|
if (combatant.isRanged()) return false
|
||||||
}
|
}
|
||||||
if (tile.isLand && combatant.unit.hasUnique("Can only attack water")) return false
|
if (combatant.unit.hasUnique("Can only attack water")) {
|
||||||
|
if (tile.isLand) return false
|
||||||
|
|
||||||
|
// trying to attack lake-to-coast or vice versa
|
||||||
|
if ((tile.baseTerrain == Constants.lakes) != (combatant.getTile().baseTerrain == Constants.lakes))
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val tileCombatant = Battle(combatant.getCivInfo().gameInfo).getMapCombatantOfTile(tile)
|
val tileCombatant = Battle(combatant.getCivInfo().gameInfo).getMapCombatantOfTile(tile)
|
||||||
|
@ -388,7 +394,7 @@ class UnitAutomation{
|
||||||
val cityTilesToAttack = attackableEnemies.filter { it.tileToAttack.isCityCenter() }
|
val cityTilesToAttack = attackableEnemies.filter { it.tileToAttack.isCityCenter() }
|
||||||
val nonCityTilesToAttack = attackableEnemies.filter { !it.tileToAttack.isCityCenter() }
|
val nonCityTilesToAttack = attackableEnemies.filter { !it.tileToAttack.isCityCenter() }
|
||||||
|
|
||||||
// todo add filter undefended tile if is air unit
|
// todo For air units, prefer to attack tiles with lower intercept chance
|
||||||
|
|
||||||
var enemyTileToAttack: AttackableTile? = null
|
var enemyTileToAttack: AttackableTile? = null
|
||||||
val capturableCity = cityTilesToAttack.firstOrNull{it.tileToAttack.getCity()!!.health == 1}
|
val capturableCity = cityTilesToAttack.firstOrNull{it.tileToAttack.getCity()!!.health == 1}
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Battle(val gameInfo:GameInfo) {
|
||||||
val attackedTile = defender.getTile()
|
val attackedTile = defender.getTile()
|
||||||
|
|
||||||
if(attacker is MapUnitCombatant && attacker.getUnitType().isAirUnit()){
|
if(attacker is MapUnitCombatant && attacker.getUnitType().isAirUnit()){
|
||||||
intercept(attacker,defender)
|
tryInterceptAirAttack(attacker,defender)
|
||||||
if(attacker.isDefeated()) return
|
if(attacker.isDefeated()) return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,8 +133,7 @@ class Battle(val gameInfo:GameInfo) {
|
||||||
// and if it's an air unit, it only has 1 movement anyway, so...
|
// and if it's an air unit, it only has 1 movement anyway, so...
|
||||||
if (!attacker.getUnitType().isAirUnit() && !(attacker.getUnitType().isMelee() && defender.isDefeated()))
|
if (!attacker.getUnitType().isAirUnit() && !(attacker.getUnitType().isMelee() && defender.isDefeated()))
|
||||||
unit.useMovementPoints(1f)
|
unit.useMovementPoints(1f)
|
||||||
}
|
} else unit.currentMovement = 0f
|
||||||
else unit.currentMovement = 0f
|
|
||||||
unit.attacksThisTurn += 1
|
unit.attacksThisTurn += 1
|
||||||
if (unit.isFortified() || unit.action == Constants.unitActionSleep)
|
if (unit.isFortified() || unit.action == Constants.unitActionSleep)
|
||||||
attacker.unit.action = null // but not, for instance, if it's Set Up - then it should definitely keep the action!
|
attacker.unit.action = null // but not, for instance, if it's Set Up - then it should definitely keep the action!
|
||||||
|
@ -155,22 +154,13 @@ class Battle(val gameInfo:GameInfo) {
|
||||||
addXp(attacker, 5, defender)
|
addXp(attacker, 5, defender)
|
||||||
addXp(defender, 4, attacker)
|
addXp(defender, 4, attacker)
|
||||||
}
|
}
|
||||||
}
|
} else { // ranged attack
|
||||||
else{ // ranged attack
|
|
||||||
addXp(attacker, 2, defender)
|
addXp(attacker, 2, defender)
|
||||||
addXp(defender, 2, attacker)
|
addXp(defender, 2, attacker)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add culture when defeating a barbarian when Honor policy is adopted (can be either attacker or defender!)
|
// Add culture when defeating a barbarian when Honor policy is adopted (can be either attacker or defender!)
|
||||||
fun tryGetCultureFromHonor(civUnit:ICombatant, barbarianUnit:ICombatant){
|
|
||||||
if(barbarianUnit.isDefeated() && barbarianUnit is MapUnitCombatant
|
|
||||||
&& barbarianUnit.getCivInfo().isBarbarian()
|
|
||||||
&& civUnit.getCivInfo().policies.isAdopted("Honor"))
|
|
||||||
civUnit.getCivInfo().policies.storedCulture +=
|
|
||||||
max(barbarianUnit.unit.baseUnit.strength,barbarianUnit.unit.baseUnit.rangedStrength)
|
|
||||||
}
|
|
||||||
|
|
||||||
tryGetCultureFromHonor(attacker, defender)
|
tryGetCultureFromHonor(attacker, defender)
|
||||||
tryGetCultureFromHonor(defender, attacker)
|
tryGetCultureFromHonor(defender, attacker)
|
||||||
|
|
||||||
|
@ -178,12 +168,21 @@ class Battle(val gameInfo:GameInfo) {
|
||||||
&& attacker.getCivInfo().policies.isAdopted("Honor Complete"))
|
&& attacker.getCivInfo().policies.isAdopted("Honor Complete"))
|
||||||
attacker.getCivInfo().gold += defender.unit.baseUnit.getProductionCost(attacker.getCivInfo()) / 10
|
attacker.getCivInfo().gold += defender.unit.baseUnit.getProductionCost(attacker.getCivInfo()) / 10
|
||||||
|
|
||||||
if(attacker is MapUnitCombatant && attacker.unit.action!=null && attacker.unit.action!!.startsWith("moveTo"))
|
if (attacker is MapUnitCombatant && attacker.unit.action != null
|
||||||
|
&& attacker.unit.action!!.startsWith("moveTo"))
|
||||||
attacker.unit.action = null
|
attacker.unit.action = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun tryGetCultureFromHonor(civUnit:ICombatant, barbarianUnit:ICombatant){
|
||||||
|
if(barbarianUnit.isDefeated() && barbarianUnit is MapUnitCombatant
|
||||||
|
&& barbarianUnit.getCivInfo().isBarbarian()
|
||||||
|
&& civUnit.getCivInfo().policies.isAdopted("Honor"))
|
||||||
|
civUnit.getCivInfo().policies.storedCulture +=
|
||||||
|
max(barbarianUnit.unit.baseUnit.strength,barbarianUnit.unit.baseUnit.rangedStrength)
|
||||||
|
}
|
||||||
|
|
||||||
// XP!
|
// XP!
|
||||||
fun addXp(thisCombatant:ICombatant, amount:Int, otherCombatant:ICombatant){
|
private fun addXp(thisCombatant:ICombatant, amount:Int, otherCombatant:ICombatant){
|
||||||
if(thisCombatant !is MapUnitCombatant) return
|
if(thisCombatant !is MapUnitCombatant) return
|
||||||
if(thisCombatant.unit.promotions.totalXpProduced() >= 30 && otherCombatant.getCivInfo().isBarbarian())
|
if(thisCombatant.unit.promotions.totalXpProduced() >= 30 && otherCombatant.getCivInfo().isBarbarian())
|
||||||
return
|
return
|
||||||
|
@ -211,12 +210,9 @@ class Battle(val gameInfo:GameInfo) {
|
||||||
for(airUnit in airUnits.toList()) airUnit.destroy()
|
for(airUnit in airUnits.toList()) airUnit.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attacker.getCivInfo().isPlayerCivilization())
|
||||||
if (attacker.getCivInfo().isPlayerCivilization()) {
|
|
||||||
attackerCiv.popupAlerts.add(PopupAlert(AlertType.CityConquered, city.name))
|
attackerCiv.popupAlerts.add(PopupAlert(AlertType.CityConquered, city.name))
|
||||||
} else {
|
else city.puppetCity(attacker.getCivInfo())
|
||||||
city.annexCity(attacker.getCivInfo())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMapCombatantOfTile(tile:TileInfo): ICombatant? {
|
fun getMapCombatantOfTile(tile:TileInfo): ICombatant? {
|
||||||
|
@ -226,12 +222,13 @@ class Battle(val gameInfo:GameInfo) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun captureCivilianUnit(attacker: ICombatant, defender: ICombatant){
|
private fun captureCivilianUnit(attacker: ICombatant, defender: ICombatant){
|
||||||
|
// barbarians don't capture civilians, City-states don't capture settlers
|
||||||
if(attacker.getCivInfo().isBarbarian()
|
if(attacker.getCivInfo().isBarbarian()
|
||||||
|| (attacker.getCivInfo().isCityState() && defender.getName()==Constants.settler)){
|
|| (attacker.getCivInfo().isCityState() && defender.getName()==Constants.settler)){
|
||||||
defender.takeDamage(100)
|
defender.takeDamage(100)
|
||||||
return
|
return
|
||||||
} // barbarians don't capture civilians!
|
}
|
||||||
|
|
||||||
if (defender.getCivInfo().isDefeated()) {//Last settler captured
|
if (defender.getCivInfo().isDefeated()) {//Last settler captured
|
||||||
defender.getCivInfo().destroy()
|
defender.getCivInfo().destroy()
|
||||||
|
@ -247,7 +244,7 @@ class Battle(val gameInfo:GameInfo) {
|
||||||
capturedUnit.updateViewableTiles()
|
capturedUnit.updateViewableTiles()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun intercept(attacker:MapUnitCombatant, defender: ICombatant){
|
private fun tryInterceptAirAttack(attacker:MapUnitCombatant, defender: ICombatant) {
|
||||||
val attackedTile = defender.getTile()
|
val attackedTile = defender.getTile()
|
||||||
for (interceptor in defender.getCivInfo().getCivUnits().filter { it.canIntercept(attackedTile) }) {
|
for (interceptor in defender.getCivInfo().getCivUnits().filter { it.canIntercept(attackedTile) }) {
|
||||||
if (Random().nextFloat() > 100f / interceptor.interceptChance()) continue
|
if (Random().nextFloat() > 100f / interceptor.interceptChance()) continue
|
||||||
|
@ -263,15 +260,18 @@ class Battle(val gameInfo:GameInfo) {
|
||||||
val interceptorName = interceptor.name
|
val interceptorName = interceptor.name
|
||||||
|
|
||||||
if (attacker.isDefeated()) {
|
if (attacker.isDefeated()) {
|
||||||
attacker.getCivInfo().addNotification("Our [$attackerName] was destroyed by an intercepting [$interceptorName]",
|
attacker.getCivInfo()
|
||||||
|
.addNotification("Our [$attackerName] was destroyed by an intercepting [$interceptorName]",
|
||||||
Color.RED)
|
Color.RED)
|
||||||
defender.getCivInfo().addNotification("Our [$interceptorName] intercepted and destroyed an enemy [$attackerName]",
|
defender.getCivInfo()
|
||||||
|
.addNotification("Our [$interceptorName] intercepted and destroyed an enemy [$attackerName]",
|
||||||
interceptor.currentTile.position, Color.RED)
|
interceptor.currentTile.position, Color.RED)
|
||||||
}
|
} else {
|
||||||
else{
|
attacker.getCivInfo()
|
||||||
attacker.getCivInfo().addNotification("Our [$attackerName] was attacked by an intercepting [$interceptorName]",
|
.addNotification("Our [$attackerName] was attacked by an intercepting [$interceptorName]",
|
||||||
Color.RED)
|
Color.RED)
|
||||||
defender.getCivInfo().addNotification("Our [$interceptorName] intercepted and attacked an enemy [$attackerName]",
|
defender.getCivInfo()
|
||||||
|
.addNotification("Our [$interceptorName] intercepted and attacked an enemy [$attackerName]",
|
||||||
interceptor.currentTile.position, Color.RED)
|
interceptor.currentTile.position, Color.RED)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
|
@ -62,6 +62,7 @@ class CityConstructions {
|
||||||
var result = currentConstructionSnapshot.tr()
|
var result = currentConstructionSnapshot.tr()
|
||||||
if (currentConstructionSnapshot!=""
|
if (currentConstructionSnapshot!=""
|
||||||
&& SpecialConstruction.getSpecialConstructions().none { it.name==currentConstructionSnapshot })
|
&& SpecialConstruction.getSpecialConstructions().none { it.name==currentConstructionSnapshot })
|
||||||
|
result += ("\r\nCost " + getConstruction(currentConstruction).getProductionCost(cityInfo.civInfo).toString()).tr()
|
||||||
result += "\r\n" + turnsToConstruction(currentConstructionSnapshot ) + " {turns}".tr()
|
result += "\r\n" + turnsToConstruction(currentConstructionSnapshot ) + " {turns}".tr()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -442,7 +442,7 @@ class CityInfo {
|
||||||
But if they don't keep their promise they get a -20 that will only fully disappear in 160 turns.
|
But if they don't keep their promise they get a -20 that will only fully disappear in 160 turns.
|
||||||
There's a lot of triggering going on here.
|
There's a lot of triggering going on here.
|
||||||
*/
|
*/
|
||||||
fun triggerCitiesSettledNearOtherCiv(){
|
private fun triggerCitiesSettledNearOtherCiv(){
|
||||||
val citiesWithin6Tiles = civInfo.gameInfo.civilizations.filter { it.isMajorCiv() && it!=civInfo }
|
val citiesWithin6Tiles = civInfo.gameInfo.civilizations.filter { it.isMajorCiv() && it!=civInfo }
|
||||||
.flatMap { it.cities }
|
.flatMap { it.cities }
|
||||||
.filter { it.getCenterTile().arialDistanceTo(getCenterTile()) <= 6 }
|
.filter { it.getCenterTile().arialDistanceTo(getCenterTile()) <= 6 }
|
||||||
|
|
|
@ -107,22 +107,6 @@ class CityStats {
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getStatPercentBonusesFromDifficulty(): Stats {
|
|
||||||
val stats = Stats()
|
|
||||||
|
|
||||||
val civ = cityInfo.civInfo
|
|
||||||
if (!civ.isPlayerCivilization()) {
|
|
||||||
val modifier = civ.gameInfo.getCurrentPlayerCivilization().getDifficulty().aiYieldModifier
|
|
||||||
stats.production += modifier
|
|
||||||
stats.science += modifier
|
|
||||||
stats.food += modifier
|
|
||||||
stats.gold += modifier
|
|
||||||
stats.culture += modifier
|
|
||||||
}
|
|
||||||
|
|
||||||
return stats
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getStatsFromNationUnique(): Stats {
|
private fun getStatsFromNationUnique(): Stats {
|
||||||
val stats = Stats()
|
val stats = Stats()
|
||||||
|
|
||||||
|
@ -392,7 +376,6 @@ class CityStats {
|
||||||
newStatPercentBonusList["Railroad"]=getStatPercentBonusesFromRailroad()
|
newStatPercentBonusList["Railroad"]=getStatPercentBonusesFromRailroad()
|
||||||
newStatPercentBonusList["Marble"]=getStatPercentBonusesFromMarble()
|
newStatPercentBonusList["Marble"]=getStatPercentBonusesFromMarble()
|
||||||
newStatPercentBonusList["Computers"]=getStatPercentBonusesFromComputers()
|
newStatPercentBonusList["Computers"]=getStatPercentBonusesFromComputers()
|
||||||
newStatPercentBonusList["Difficulty"]=getStatPercentBonusesFromDifficulty()
|
|
||||||
newStatPercentBonusList["National ability"]=getStatPercentBonusesFromNationUnique()
|
newStatPercentBonusList["National ability"]=getStatPercentBonusesFromNationUnique()
|
||||||
newStatPercentBonusList["Puppet City"]=getStatPercentBonusesFromPuppetCity()
|
newStatPercentBonusList["Puppet City"]=getStatPercentBonusesFromPuppetCity()
|
||||||
|
|
||||||
|
@ -470,8 +453,11 @@ class CityStats {
|
||||||
newFinalStatList["Policies"]!!.food += foodFromGrowthBonuses
|
newFinalStatList["Policies"]!!.food += foodFromGrowthBonuses
|
||||||
|
|
||||||
// Same here - will have a different UI display.
|
// Same here - will have a different UI display.
|
||||||
val buildingsMaintenance = cityInfo.cityConstructions.getMaintenanceCosts() // this is AFTER the bonus calculation!
|
var buildingsMaintenance = cityInfo.cityConstructions.getMaintenanceCosts().toFloat() // this is AFTER the bonus calculation!
|
||||||
newFinalStatList["Maintenance"] = Stats().apply { gold -= buildingsMaintenance }
|
if (!cityInfo.civInfo.isPlayerCivilization()) {
|
||||||
|
buildingsMaintenance *= cityInfo.civInfo.gameInfo.getDifficulty().aiBuildingMaintenanceModifier
|
||||||
|
}
|
||||||
|
newFinalStatList["Maintenance"] = Stats().apply { gold -= buildingsMaintenance.toInt() }
|
||||||
|
|
||||||
if (cityInfo.resistanceCounter > 0)
|
if (cityInfo.resistanceCounter > 0)
|
||||||
newFinalStatList.clear() // NOPE
|
newFinalStatList.clear() // NOPE
|
||||||
|
|
|
@ -101,7 +101,7 @@ class CivInfoStats(val civInfo: CivilizationInfo){
|
||||||
val statMap = HashMap<String, Float>()
|
val statMap = HashMap<String, Float>()
|
||||||
statMap["Base happiness"] = civInfo.getDifficulty().baseHappiness.toFloat()
|
statMap["Base happiness"] = civInfo.getDifficulty().baseHappiness.toFloat()
|
||||||
|
|
||||||
var happinessPerUniqueLuxury = 5f
|
var happinessPerUniqueLuxury = 5f + civInfo.getDifficulty().extraHappinessPerLuxury
|
||||||
if (civInfo.policies.isAdopted("Protectionism")) happinessPerUniqueLuxury += 1
|
if (civInfo.policies.isAdopted("Protectionism")) happinessPerUniqueLuxury += 1
|
||||||
statMap["Luxury resources"]= civInfo.getCivResources().map { it.resource }
|
statMap["Luxury resources"]= civInfo.getCivResources().map { it.resource }
|
||||||
.count { it.resourceType === ResourceType.Luxury } * happinessPerUniqueLuxury
|
.count { it.resourceType === ResourceType.Luxury } * happinessPerUniqueLuxury
|
||||||
|
|
|
@ -31,6 +31,8 @@ class PolicyManager {
|
||||||
if (isAdopted("Piety Complete")) policyCultureCost *= 0.9
|
if (isAdopted("Piety Complete")) policyCultureCost *= 0.9
|
||||||
if (civInfo.containsBuildingUnique("Culture cost of adopting new Policies reduced by 10%"))
|
if (civInfo.containsBuildingUnique("Culture cost of adopting new Policies reduced by 10%"))
|
||||||
policyCultureCost *= 0.9
|
policyCultureCost *= 0.9
|
||||||
|
if (civInfo.isPlayerCivilization())
|
||||||
|
policyCultureCost *= civInfo.getDifficulty().policyCostModifier
|
||||||
policyCultureCost *= civInfo.gameInfo.gameParameters.gameSpeed.getModifier()
|
policyCultureCost *= civInfo.gameInfo.gameParameters.gameSpeed.getModifier()
|
||||||
val cost: Int = (policyCultureCost * (1 + cityModifier)).roundToInt()
|
val cost: Int = (policyCultureCost * (1 + cityModifier)).roundToInt()
|
||||||
return cost - (cost % 5)
|
return cost - (cost % 5)
|
||||||
|
|
|
@ -42,6 +42,7 @@ class TechManager {
|
||||||
|
|
||||||
fun costOfTech(techName: String): Int {
|
fun costOfTech(techName: String): Int {
|
||||||
var techCost = GameBasics.Technologies[techName]!!.cost.toFloat()
|
var techCost = GameBasics.Technologies[techName]!!.cost.toFloat()
|
||||||
|
if (civInfo.isPlayerCivilization())
|
||||||
techCost *= civInfo.getDifficulty().researchCostModifier
|
techCost *= civInfo.getDifficulty().researchCostModifier
|
||||||
techCost *= civInfo.gameInfo.gameParameters.gameSpeed.getModifier()
|
techCost *= civInfo.gameInfo.gameParameters.gameSpeed.getModifier()
|
||||||
techCost *= 1 + (civInfo.cities.size -1 ) * 0.02f // each city increases tech cost by 2%, as per https://civilization.fandom.com/wiki/Science_(Civ5)
|
techCost *= 1 + (civInfo.cities.size -1 ) * 0.02f // each city increases tech cost by 2%, as per https://civilization.fandom.com/wiki/Science_(Civ5)
|
||||||
|
|
|
@ -2,8 +2,6 @@ package com.unciv.logic.map
|
||||||
|
|
||||||
import com.badlogic.gdx.math.Vector2
|
import com.badlogic.gdx.math.Vector2
|
||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.Constants.Companion.mountain
|
|
||||||
import com.unciv.Constants.Companion.ocean
|
|
||||||
import com.unciv.logic.HexMath
|
import com.unciv.logic.HexMath
|
||||||
import com.unciv.models.gamebasics.GameBasics
|
import com.unciv.models.gamebasics.GameBasics
|
||||||
import com.unciv.models.gamebasics.tile.ResourceType
|
import com.unciv.models.gamebasics.tile.ResourceType
|
||||||
|
@ -123,7 +121,7 @@ class CelluarAutomataRandomMapGenerator(): SeedRandomMapGenerator() {
|
||||||
val tile=TileInfo()
|
val tile=TileInfo()
|
||||||
tile.position=vector
|
tile.position=vector
|
||||||
if (type == TerrainType.Land) tile.baseTerrain = ""
|
if (type == TerrainType.Land) tile.baseTerrain = ""
|
||||||
else tile.baseTerrain = ocean
|
else tile.baseTerrain = Constants.ocean
|
||||||
return tile
|
return tile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +150,7 @@ class CelluarAutomataRandomMapGenerator(): SeedRandomMapGenerator() {
|
||||||
if (tilesInArea.size <= 10) {
|
if (tilesInArea.size <= 10) {
|
||||||
for (vector in tilesInArea) {
|
for (vector in tilesInArea) {
|
||||||
val tile = map[vector.toString()]!!
|
val tile = map[vector.toString()]!!
|
||||||
tile.baseTerrain = "Lakes"
|
tile.baseTerrain = Constants.lakes
|
||||||
tile.setTransients()
|
tile.setTransients()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +158,7 @@ class CelluarAutomataRandomMapGenerator(): SeedRandomMapGenerator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Coasts
|
//Coasts
|
||||||
for (tile in map.values.filter { it.baseTerrain == ocean }) {
|
for (tile in map.values.filter { it.baseTerrain == Constants.ocean }) {
|
||||||
if (HexMath().getVectorsInDistance(tile.position,2).any { hasLandTile(map,it) }) {
|
if (HexMath().getVectorsInDistance(tile.position,2).any { hasLandTile(map,it) }) {
|
||||||
tile.baseTerrain = Constants.coast
|
tile.baseTerrain = Constants.coast
|
||||||
tile.setTransients()
|
tile.setTransients()
|
||||||
|
@ -170,7 +168,7 @@ class CelluarAutomataRandomMapGenerator(): SeedRandomMapGenerator() {
|
||||||
|
|
||||||
override fun randomizeTile(tileInfo: TileInfo, map: HashMap<String, TileInfo>){
|
override fun randomizeTile(tileInfo: TileInfo, map: HashMap<String, TileInfo>){
|
||||||
if(tileInfo.getBaseTerrain().type==TerrainType.Land && Math.random()<0.05f){
|
if(tileInfo.getBaseTerrain().type==TerrainType.Land && Math.random()<0.05f){
|
||||||
tileInfo.baseTerrain = mountain
|
tileInfo.baseTerrain = Constants.mountain
|
||||||
tileInfo.setTransients()
|
tileInfo.setTransients()
|
||||||
}
|
}
|
||||||
addRandomTerrainFeature(tileInfo)
|
addRandomTerrainFeature(tileInfo)
|
||||||
|
@ -185,8 +183,8 @@ class CelluarAutomataRandomMapGenerator(): SeedRandomMapGenerator() {
|
||||||
fun divideIntoAreas2(averageTilesPerArea: Int, waterPercent: Float, distance: Int, map: HashMap<Vector2, TileInfo>) {
|
fun divideIntoAreas2(averageTilesPerArea: Int, waterPercent: Float, distance: Int, map: HashMap<Vector2, TileInfo>) {
|
||||||
val areas = ArrayList<Area>()
|
val areas = ArrayList<Area>()
|
||||||
|
|
||||||
val terrains = GameBasics.Terrains.values.filter { it.type === TerrainType.Land && it.name != "Lakes"
|
val terrains = GameBasics.Terrains.values.filter { it.type === TerrainType.Land && it.name != Constants.lakes
|
||||||
&& it.name != mountain}
|
&& it.name != Constants.mountain}
|
||||||
|
|
||||||
while(map.values.any { it.baseTerrain=="" }) // the world could be split into lots off tiny islands, and every island deserves land types
|
while(map.values.any { it.baseTerrain=="" }) // the world could be split into lots off tiny islands, and every island deserves land types
|
||||||
{
|
{
|
||||||
|
@ -196,7 +194,7 @@ class CelluarAutomataRandomMapGenerator(): SeedRandomMapGenerator() {
|
||||||
|
|
||||||
for (i in 0 until numberOfSeeds) {
|
for (i in 0 until numberOfSeeds) {
|
||||||
var terrain = if (Math.random() > waterPercent) terrains.random().name
|
var terrain = if (Math.random() > waterPercent) terrains.random().name
|
||||||
else ocean
|
else Constants.ocean
|
||||||
val tile = emptyTiles.random()
|
val tile = emptyTiles.random()
|
||||||
|
|
||||||
//change grassland to desert or tundra based on y
|
//change grassland to desert or tundra based on y
|
||||||
|
@ -204,7 +202,7 @@ class CelluarAutomataRandomMapGenerator(): SeedRandomMapGenerator() {
|
||||||
if (terrain == "Grassland" || terrain == "Tundra")
|
if (terrain == "Grassland" || terrain == "Tundra")
|
||||||
terrain = "Desert"
|
terrain = "Desert"
|
||||||
} else if (abs(getLatitude(tile.position)) > maxLatitude * 0.7) {
|
} else if (abs(getLatitude(tile.position)) > maxLatitude * 0.7) {
|
||||||
if (terrain == "Grassland" || terrain == Constants.plains || terrain == "Desert" || terrain == ocean) {
|
if (terrain == "Grassland" || terrain == Constants.plains || terrain == "Desert" || terrain == Constants.ocean) {
|
||||||
terrain = "Tundra"
|
terrain = "Tundra"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -263,9 +261,9 @@ class PerlinNoiseRandomMapGenerator:SeedRandomMapGenerator(){
|
||||||
+ Perlin.noise(vector.x*ratio*2,vector.y*ratio*2,mapRandomSeed)/2
|
+ Perlin.noise(vector.x*ratio*2,vector.y*ratio*2,mapRandomSeed)/2
|
||||||
+ Perlin.noise(vector.x*ratio*4,vector.y*ratio*4,mapRandomSeed)/4
|
+ Perlin.noise(vector.x*ratio*4,vector.y*ratio*4,mapRandomSeed)/4
|
||||||
when {
|
when {
|
||||||
height>0.8 -> tile.baseTerrain = mountain
|
height>0.8 -> tile.baseTerrain = Constants.mountain
|
||||||
height>0 -> tile.baseTerrain = "" // we'll leave this to the area division
|
height>0 -> tile.baseTerrain = "" // we'll leave this to the area division
|
||||||
else -> tile.baseTerrain = ocean
|
else -> tile.baseTerrain = Constants.ocean
|
||||||
}
|
}
|
||||||
return tile
|
return tile
|
||||||
}
|
}
|
||||||
|
@ -297,12 +295,12 @@ class AlexanderRandomMapGenerator:RandomMapGenerator(){
|
||||||
if(map[currentSpark]!!.baseTerrain==grassland){
|
if(map[currentSpark]!!.baseTerrain==grassland){
|
||||||
for(tile in emptyTilesAroundSpark){
|
for(tile in emptyTilesAroundSpark){
|
||||||
if(Math.random()<landExpansionChance) map[tile]=TileInfo().apply { baseTerrain=grassland }
|
if(Math.random()<landExpansionChance) map[tile]=TileInfo().apply { baseTerrain=grassland }
|
||||||
else map[tile]=TileInfo().apply { baseTerrain=ocean }
|
else map[tile]=TileInfo().apply { baseTerrain=Constants.ocean }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
for(tile in emptyTilesAroundSpark)
|
for(tile in emptyTilesAroundSpark)
|
||||||
map[tile]=TileInfo().apply { baseTerrain=ocean }
|
map[tile]=TileInfo().apply { baseTerrain=Constants.ocean }
|
||||||
}
|
}
|
||||||
sparkList.remove(currentSpark)
|
sparkList.remove(currentSpark)
|
||||||
sparkList.addAll(emptyTilesAroundSpark)
|
sparkList.addAll(emptyTilesAroundSpark)
|
||||||
|
@ -311,7 +309,7 @@ class AlexanderRandomMapGenerator:RandomMapGenerator(){
|
||||||
val newmap = HashMap<String,TileInfo>()
|
val newmap = HashMap<String,TileInfo>()
|
||||||
for(entry in map){
|
for(entry in map){
|
||||||
entry.value!!.position = entry.key
|
entry.value!!.position = entry.key
|
||||||
if(entry.value!!.baseTerrain==ocean
|
if(entry.value!!.baseTerrain==Constants.ocean
|
||||||
&& HexMath().getAdjacentVectors(entry.key).all { !map.containsKey(it) || map[it]!!.baseTerrain==grassland })
|
&& HexMath().getAdjacentVectors(entry.key).all { !map.containsKey(it) || map[it]!!.baseTerrain==grassland })
|
||||||
entry.value!!.baseTerrain=grassland
|
entry.value!!.baseTerrain=grassland
|
||||||
|
|
||||||
|
@ -364,7 +362,8 @@ open class SeedRandomMapGenerator : RandomMapGenerator() {
|
||||||
open fun divideIntoAreas(averageTilesPerArea: Int, waterPercent: Float, map: HashMap<Vector2, TileInfo>) {
|
open fun divideIntoAreas(averageTilesPerArea: Int, waterPercent: Float, map: HashMap<Vector2, TileInfo>) {
|
||||||
val areas = ArrayList<Area>()
|
val areas = ArrayList<Area>()
|
||||||
|
|
||||||
val terrains = GameBasics.Terrains.values.filter { it.type === TerrainType.Land && it.name != "Lakes" && it.name != mountain }
|
val terrains = GameBasics.Terrains.values
|
||||||
|
.filter { it.type === TerrainType.Land && it.name != Constants.lakes && it.name != Constants.mountain }
|
||||||
|
|
||||||
while(map.values.any { it.baseTerrain=="" }) // the world could be split into lots off tiny islands, and every island deserves land types
|
while(map.values.any { it.baseTerrain=="" }) // the world could be split into lots off tiny islands, and every island deserves land types
|
||||||
{
|
{
|
||||||
|
@ -373,7 +372,7 @@ open class SeedRandomMapGenerator : RandomMapGenerator() {
|
||||||
|
|
||||||
for (i in 0 until numberOfSeeds) {
|
for (i in 0 until numberOfSeeds) {
|
||||||
val terrain = if (Math.random() > waterPercent) terrains.random().name
|
val terrain = if (Math.random() > waterPercent) terrains.random().name
|
||||||
else ocean
|
else Constants.ocean
|
||||||
val area = Area(terrain)
|
val area = Area(terrain)
|
||||||
val tile = emptyTiles.random()
|
val tile = emptyTiles.random()
|
||||||
emptyTiles -= tile
|
emptyTiles -= tile
|
||||||
|
@ -386,10 +385,10 @@ open class SeedRandomMapGenerator : RandomMapGenerator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (area in areas.filter { it.terrain == ocean && it.locations.size <= 10 }) {
|
for (area in areas.filter { it.terrain == Constants.ocean && it.locations.size <= 10 }) {
|
||||||
// areas with 10 or less tiles are lakes.
|
// areas with 10 or less tiles are lakes.
|
||||||
for (location in area.locations)
|
for (location in area.locations)
|
||||||
map[location]!!.baseTerrain = "Lakes"
|
map[location]!!.baseTerrain = Constants.lakes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,7 +438,7 @@ open class RandomMapGenerator {
|
||||||
tileInfo.position = position
|
tileInfo.position = position
|
||||||
val terrains = GameBasics.Terrains.values
|
val terrains = GameBasics.Terrains.values
|
||||||
|
|
||||||
val baseTerrain = terrains.filter { it.type === TerrainType.Land && it.name != "Lakes" }.random()
|
val baseTerrain = terrains.filter { it.type === TerrainType.Land }.random()
|
||||||
tileInfo.baseTerrain = baseTerrain.name
|
tileInfo.baseTerrain = baseTerrain.name
|
||||||
|
|
||||||
addRandomTerrainFeature(tileInfo)
|
addRandomTerrainFeature(tileInfo)
|
||||||
|
@ -498,7 +497,7 @@ open class RandomMapGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun setWaterTiles(map: HashMap<String, TileInfo>) {
|
open fun setWaterTiles(map: HashMap<String, TileInfo>) {
|
||||||
for (tile in map.values.filter { it.baseTerrain == ocean }) {
|
for (tile in map.values.filter { it.baseTerrain == Constants.ocean }) {
|
||||||
if (HexMath().getVectorsInDistance(tile.position,2).any { hasLandTile(map,it) }) {
|
if (HexMath().getVectorsInDistance(tile.position,2).any { hasLandTile(map,it) }) {
|
||||||
tile.baseTerrain = Constants.coast
|
tile.baseTerrain = Constants.coast
|
||||||
tile.setTransients()
|
tile.setTransients()
|
||||||
|
@ -508,12 +507,12 @@ open class RandomMapGenerator {
|
||||||
|
|
||||||
open fun randomizeTile(tileInfo: TileInfo, map: HashMap<String, TileInfo>){
|
open fun randomizeTile(tileInfo: TileInfo, map: HashMap<String, TileInfo>){
|
||||||
if(tileInfo.getBaseTerrain().type==TerrainType.Land && Math.random()<0.05f){
|
if(tileInfo.getBaseTerrain().type==TerrainType.Land && Math.random()<0.05f){
|
||||||
tileInfo.baseTerrain = mountain
|
tileInfo.baseTerrain = Constants.mountain
|
||||||
tileInfo.setTransients()
|
tileInfo.setTransients()
|
||||||
}
|
}
|
||||||
if(tileInfo.getBaseTerrain().type==TerrainType.Land && Math.random()<0.05f
|
if(tileInfo.getBaseTerrain().type==TerrainType.Land && Math.random()<0.05f
|
||||||
&& HexMath().getVectorsInDistance(tileInfo.position,1).all { hasLandTile(map,it) }){
|
&& HexMath().getVectorsInDistance(tileInfo.position,1).all { hasLandTile(map,it) }){
|
||||||
tileInfo.baseTerrain = "Lakes"
|
tileInfo.baseTerrain = Constants.lakes
|
||||||
tileInfo.setTransients()
|
tileInfo.setTransients()
|
||||||
}
|
}
|
||||||
addRandomTerrainFeature(tileInfo)
|
addRandomTerrainFeature(tileInfo)
|
||||||
|
|
|
@ -192,6 +192,17 @@ class Building : NamedStats(), IConstruction{
|
||||||
var productionCost = cost.toFloat()
|
var productionCost = cost.toFloat()
|
||||||
if (!isWonder && culture != 0f && civInfo.policies.isAdopted("Piety"))
|
if (!isWonder && culture != 0f && civInfo.policies.isAdopted("Piety"))
|
||||||
productionCost *= 0.85f
|
productionCost *= 0.85f
|
||||||
|
if (civInfo.isPlayerCivilization()) {
|
||||||
|
if(!isWonder) {
|
||||||
|
productionCost *= civInfo.getDifficulty().buildingCostModifier
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(isWonder) {
|
||||||
|
productionCost *= civInfo.gameInfo.getDifficulty().aiWonderCostModifier
|
||||||
|
} else {
|
||||||
|
productionCost *= civInfo.gameInfo.getDifficulty().aiBuildingCostModifier
|
||||||
|
}
|
||||||
|
}
|
||||||
productionCost *= civInfo.gameInfo.gameParameters.gameSpeed.getModifier()
|
productionCost *= civInfo.gameInfo.gameParameters.gameSpeed.getModifier()
|
||||||
return productionCost.toInt()
|
return productionCost.toInt()
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,20 @@ import java.util.*
|
||||||
class Difficulty: INamed {
|
class Difficulty: INamed {
|
||||||
override lateinit var name: String
|
override lateinit var name: String
|
||||||
var baseHappiness: Int = 0
|
var baseHappiness: Int = 0
|
||||||
|
var extraHappinessPerLuxury: Float = 0f
|
||||||
var researchCostModifier:Float = 1f
|
var researchCostModifier:Float = 1f
|
||||||
var unhappinessModifier = 1f
|
var unitCostModifier:Float = 1f
|
||||||
var aiCityGrowthModifier = 1f
|
var buildingCostModifier:Float = 1f
|
||||||
|
var policyCostModifier:Float = 1f
|
||||||
|
var unhappinessModifier:Float = 1f
|
||||||
|
var aiCityGrowthModifier:Float = 1f
|
||||||
|
var aiUnitCostModifier:Float = 1f
|
||||||
|
var aiBuildingCostModifier:Float = 1f
|
||||||
|
var aiWonderCostModifier:Float = 1f
|
||||||
|
var aiBuildingMaintenanceModifier:Float = 1f
|
||||||
var aiUnitMaintenanceModifier = 1f
|
var aiUnitMaintenanceModifier = 1f
|
||||||
var aiYieldModifier = 1f
|
|
||||||
var aiFreeTechs = ArrayList<String>()
|
var aiFreeTechs = ArrayList<String>()
|
||||||
|
var aiFreeUnits = ArrayList<String>()
|
||||||
var aiUnhappinessModifier = 1f
|
var aiUnhappinessModifier = 1f
|
||||||
var aisExchangeTechs = false
|
var aisExchangeTechs = false
|
||||||
}
|
}
|
|
@ -99,6 +99,10 @@ class BaseUnit : INamed, IConstruction, ICivilopedia {
|
||||||
|
|
||||||
override fun getProductionCost(civInfo: CivilizationInfo): Int {
|
override fun getProductionCost(civInfo: CivilizationInfo): Int {
|
||||||
var productionCost = cost.toFloat()
|
var productionCost = cost.toFloat()
|
||||||
|
if (civInfo.isPlayerCivilization())
|
||||||
|
productionCost *= civInfo.getDifficulty().unitCostModifier
|
||||||
|
else
|
||||||
|
productionCost *= civInfo.gameInfo.getDifficulty().aiUnitCostModifier
|
||||||
productionCost *= civInfo.gameInfo.gameParameters.gameSpeed.getModifier()
|
productionCost *= civInfo.gameInfo.gameParameters.gameSpeed.getModifier()
|
||||||
return productionCost.toInt()
|
return productionCost.toInt()
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,18 +185,20 @@ object ImageGetter {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTechIconGroup(techName: String): Group {
|
fun getTechIconGroup(techName: String): Group {
|
||||||
var TechIconColor = Color.WHITE
|
var techIconColor = Color.WHITE
|
||||||
when (GameBasics.Technologies[techName]!!.era().name) {
|
when (GameBasics.Technologies[techName]!!.era().name) {
|
||||||
"Ancient"-> TechIconColor = Color.FIREBRICK
|
"Ancient" -> techIconColor = colorFromRGB(255, 87, 35)
|
||||||
"Classical"-> TechIconColor = Color.VIOLET
|
"Classical" -> techIconColor = colorFromRGB(233, 31, 99)
|
||||||
"Medieval"-> TechIconColor = Color.TAN
|
"Medieval" -> techIconColor = colorFromRGB(157, 39, 176)
|
||||||
"Renaissance"-> TechIconColor = Color.BROWN
|
"Renaissance" -> techIconColor = colorFromRGB(104, 58, 183)
|
||||||
"Industrial"-> TechIconColor = Color.CHARTREUSE
|
"Industrial" -> techIconColor = colorFromRGB(63, 81, 182)
|
||||||
"Modern"-> TechIconColor = Color.GOLD
|
"Modern" -> techIconColor = colorFromRGB(33, 150, 243)
|
||||||
"Information"-> TechIconColor = Color.CORAL
|
"Information" -> techIconColor = colorFromRGB(0, 150, 136)
|
||||||
"Future"-> TechIconColor = Color.CYAN
|
"Future" -> techIconColor = colorFromRGB(76,176,81)
|
||||||
}
|
}
|
||||||
return getImage("TechIcons/$techName").surroundWithCircle(60f).apply{ this.circle.color = TechIconColor }
|
return getImage("TechIcons/$techName").apply { color = techIconColor.lerp(Color.BLACK,0.6f) }
|
||||||
|
.surroundWithCircle(60f)
|
||||||
|
//.apply { this.circle.color = techIconColor.lerp(Color.WHITE, 0.5f) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getProgressBarVertical(width:Float,height:Float,percentComplete:Float,progressColor:Color,backgroundColor:Color): Table {
|
fun getProgressBarVertical(width:Float,height:Float,percentComplete:Float,progressColor:Color,backgroundColor:Color): Table {
|
||||||
|
|