This commit is contained in:
YueR 2019-09-25 10:31:34 +08:00
commit 2a63d53f7e
98 changed files with 2143 additions and 1960 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 937 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 831 B

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 B

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 936 B

After

Width:  |  Height:  |  Size: 731 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1,010 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 542 B

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 922 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 937 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,007 KiB

After

Width:  |  Height:  |  Size: 1,015 KiB

View file

@ -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,

View file

@ -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
} }

View file

@ -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],

View file

@ -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":{

View file

@ -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]"

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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}

View file

@ -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

View file

@ -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
} }

View file

@ -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 }

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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()
} }

View file

@ -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
} }

View file

@ -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()
} }

View file

@ -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 {