Aztecs and some other things (#3033)

* Added icons
* [temple](https://thenounproject.com/search/?q=temple&i=28256) By Fabio Meroni for Temple of Artemis
* [Canoe](https://thenounproject.com/term/canoe/402285/) By Viktor Fedyuk (Tim P) for Floating Gardens
* [Garden](https://thenounproject.com/search/?q=garden&i=1478380) By Bharat
Aztecs by Séan https://discord.com/channels/586194543280390151/633733497277775884/727255962754351104
Jaguar by Red11

Reused slinger icon for Slinger Withdraw

* Added buildings and uniques for them
garden - bonus building of the Medieval Era. City "Must border a source of fresh water"
Temple of Artemis - World wonder of the Ancient era
Floating Gardens - Aztec unique building, replaces Water Mill

"[+1 Science] Per [2] Population in this city" - for Library and Public School
"+[]% great person generation in this city" - for garden
"Must border a source of fresh water" - "fresh water" provided by river or tiles with "Fresh water" unique. Added "Fresh water" unique to Lakes and Oasis
"+[10]% growth in all cities" - now has parameter - for Tradition Complete policy and Temple of Artemis
"+[10]% growth in capital" - now has parameter
"+[15]% Production when constructing [ranged units]"   - "ranged units" now valid param
"[stats] once [tech] is discovered" - Petra and Mughal Fort have it
"[+1 Production] from [River] tiles in this city"]  - now can use "River" - for Hydro plant

* Added Jaguar - Aztec unique unit
New unique - "+[]% combat bonus in [param]" unique - Norwegian Ski Infantry, Jaguars and Mohawks have it. param can be terrainFeature or baseTerrain, in case of baseTerrain it implies there are no features like vegetation her
Implemented "Culture for the empire from each enemy unit killed"
tweaked honor policy - it should bring half as much culture, and same as Sacrificial Captives
Fixed penalty for terrain if unit do not have "No defensive terrain bonus" unique

* Added Aztecs

* Update template.properties

* update template.properties

* update template.properties

* update template.properties
This commit is contained in:
HadeanLake 2020-08-30 21:02:59 +03:00 committed by GitHub
parent 683cbb5864
commit e6e31b4e1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 1039 additions and 907 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 871 KiB

After

Width:  |  Height:  |  Size: 879 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 KiB

After

Width:  |  Height:  |  Size: 498 KiB

View file

@ -48,7 +48,7 @@
"name": "Library", "name": "Library",
"hurryCostModifier": 25, "hurryCostModifier": 25,
"maintenance": 1, "maintenance": 1,
"uniques": ["+1 Science Per 2 Population"], "uniques": ["[+1 Science] Per [2] Population in this city"],
"requiredTech": "Writing" "requiredTech": "Writing"
}, },
{ {
@ -68,7 +68,7 @@
"uniqueTo": "China", "uniqueTo": "China",
"hurryCostModifier": 25, "hurryCostModifier": 25,
"gold": 2, "gold": 2,
"uniques": ["+1 Science Per 2 Population"], "uniques": ["[+1 Science] Per [2] Population in this city"],
"requiredTech": "Writing" "requiredTech": "Writing"
}, },
{ {
@ -87,19 +87,29 @@
"uniques": ["Must be next to river"], "uniques": ["Must be next to river"],
"requiredTech": "The Wheel" "requiredTech": "The Wheel"
}, },
{
/* "name": "Floating Gardens",
"replaces": "Water Mill",
"uniqueTo": "Aztecs",
"cost": 75,
"food": 2,
"production": 1,
"uniques": ["[+2 Food] from [Lakes] tiles in this city", "Must border a source of fresh water"],
"hurryCostModifier": 25,
"maintenance": 1,
"percentStatBonus": {"food": 15},
"requiredTech": "The Wheel"
},
{ {
"name": "Temple of Artemis", "name": "Temple of Artemis",
"culture": 1, "culture": 1,
"isWonder": true, "isWonder": true,
"cost": 185,
"greatPersonPoints": {"production": 1}, "greatPersonPoints": {"production": 1},
"uniques": ["+10% Growth in all Cities.","+15% Production towards Ranged Units."], "uniques": ["+[10]% growth in all cities", "+[15]% Production when constructing [ranged units]"],
"requiredTech": "Archery" "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" "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,
@ -309,15 +319,14 @@
"hurryCostModifier": 25, "hurryCostModifier": 25,
"requiredTech": "Currency" "requiredTech": "Currency"
}, },
/* /*
{ //Must be built in or near Desert { // Will be Introduced in Gods & Kings. Flood plains are not supposed to be affected by this wonder. Add stats to all desert tiles and then add negative stats to flood plains to undo the effect on them for now
"name": "Petra", "name": "Petra",
"culture": 1, "culture": 1,
"isWonder": true, "isWonder": true,
"greatPersonPoints": {"production": 1}, "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."], "uniques": ["Must be next to [Desert]", "[+1 Food, +1 Production] from [Desert] tiles in this city", "[-1 Food, -1 Production] from [Flood plains] tiles in this city", "[+6 Culture] once [Archaeology] is discovered"],
"requiredTech": "Currency" "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" "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"
}, },
*/ */
@ -341,6 +350,14 @@
// Medieval Era // Medieval Era
{
"name": "Garden",
"cost": 120,
"uniques": ["+[25]% great person generation in this city", "Must border a source of fresh water"],
"hurryCostModifier": 25,
"maintenance": 1,
"requiredTech": "Theology"
},
{ {
"name": "Monastery", "name": "Monastery",
"maintenance": 0, "maintenance": 0,
@ -481,6 +498,7 @@
"culture": 2, "culture": 2,
"hurryCostModifier": 25, "hurryCostModifier": 25,
"requiredBuilding": "Walls", "requiredBuilding": "Walls",
"uniques": ["[+1 Gold] once [Flight] is discovered"],
"requiredTech": "Chivalry" "requiredTech": "Chivalry"
}, },
{ {
@ -701,7 +719,7 @@
"requiredBuilding": "University", "requiredBuilding": "University",
"maintenance": 3, "maintenance": 3,
"hurryCostModifier": 0, "hurryCostModifier": 0,
"uniques": ["+1 Science Per 2 Population"], "uniques": ["[+1 Science] Per [2] Population in this city"],
"requiredTech": "Scientific Theory" "requiredTech": "Scientific Theory"
}, },
{ {
@ -760,6 +778,17 @@
"requiredTech": "Industrialization", "requiredTech": "Industrialization",
"quote": "'To achieve great things, two things are needed: a plan, and not quite enough time.' - Leonard Bernstein" "quote": "'To achieve great things, two things are needed: a plan, and not quite enough time.' - Leonard Bernstein"
}, },
/* This works and even has icon but AI cannot manage its Aluminum at this moment
{
"name": "Hydro Plant",
"cost": 360,
"requiredResource": "Aluminum",
"hurryCostModifier": 25,
"maintenance": 3,
"uniques": ["Must be next to river","[+1 Production] from [River] tiles in this city"],
"requiredTech": "Electricity"
},
*/
// Modern Era // Modern Era

View file

@ -575,9 +575,7 @@
"Baruun-Urt","Ereen","Batshireet","Choyr","Ulaangom","Tosontsengel","Altay","Uliastay","Bayanhongor", "Baruun-Urt","Ereen","Batshireet","Choyr","Ulaangom","Tosontsengel","Altay","Uliastay","Bayanhongor",
"Har-Ayrag","Nalayh","Tes"] "Har-Ayrag","Nalayh","Tes"]
}, },
/* {
{ // REQUIRES RIVERS
"name": "Aztecs", "name": "Aztecs",
"leaderName": "Montezuma I", "leaderName": "Montezuma I",
"adjective": ["Aztec"], "adjective": ["Aztec"],
@ -586,22 +584,26 @@
"startIntroPart1": "Welcome, O divine Montezuma! We grovel in awe at your magnificence! May the heaven shower all manner of good things upon you all the days of your life! Your are the leader of the mighty Aztec people, wandering nomads from a lost home in the north who in the 12th century came to live in the mesa central in the heart of what would come to be call Mexico. Surrounded by many tribes fighting to control the rich land surrounding the sacred lakes of Texoco, Xaltocan and Zampango. Through cunning alliances and martial prowess, within a mere two hundred years, the Aztecs came to dominate the Central American basin, ruling a mighty empire stretching from sea to sea. But the empire fell soon under the assault of the accursed Spaniards, wielding fiendish weapons the likes of which your faithful warriors had never seen.", "startIntroPart1": "Welcome, O divine Montezuma! We grovel in awe at your magnificence! May the heaven shower all manner of good things upon you all the days of your life! Your are the leader of the mighty Aztec people, wandering nomads from a lost home in the north who in the 12th century came to live in the mesa central in the heart of what would come to be call Mexico. Surrounded by many tribes fighting to control the rich land surrounding the sacred lakes of Texoco, Xaltocan and Zampango. Through cunning alliances and martial prowess, within a mere two hundred years, the Aztecs came to dominate the Central American basin, ruling a mighty empire stretching from sea to sea. But the empire fell soon under the assault of the accursed Spaniards, wielding fiendish weapons the likes of which your faithful warriors had never seen.",
"startIntroPart2": "O great king Montezuma, your people call upon you once more, to rise up and lead them to glory, bring them wealth and power, and give them dominion over their foes and rivals. Will you answer their call, glorious leader? Will you build a civilization that stands the test of time?", "startIntroPart2": "O great king Montezuma, your people call upon you once more, to rise up and lead them to glory, bring them wealth and power, and give them dominion over their foes and rivals. Will you answer their call, glorious leader? Will you build a civilization that stands the test of time?",
"declaringWar": "Xi-miqa-can! Xi-miqa-can! Xi-miqa-can! (Die, die, die!)", "declaringWar": "Xi-miqa-can! Xi-miqa-can! Xi-miqa-can! (Die, die, die!)",
"attacked": "Excellent! Let the blood flow in raging torrents!", "attacked": "Excellent! Let the blood flow in raging torrents!",
"defeated": "Monster! Who are you to destroy my greatness?", "defeated": "Monster! Who are you to destroy my greatness?",
"introduction": "What do I see before me? Another beating heart for my sacrificial fire.", "introduction": "What do I see before me? Another beating heart for my sacrificial fire.",
"neutralHello": "Welcome, friend.", "neutralHello": "Welcome, friend.",
"hateHello": "What do you want?", "hateHello": "What do you want?",
"tradeRequest": " Accept this agreement or suffer the consequences.", "tradeRequest": " Accept this agreement or suffer the consequences.",
"outerColor": [255,51,51],
"innerColor": [153,255,255], "outerColor": [139,32,23],
"innerColor": [134,238,214],
"uniqueName": "Sacrificial Captives",
"uniques": ["Gains culture from each enemy unit killed"],
"cities": ["Tenochtitlan","Teotihuacan","Tlatelolco","Texcoco","Tlaxcala","Calixtlahuaca","Xochicalco","Tlacopan", "cities": ["Tenochtitlan","Teotihuacan","Tlatelolco","Texcoco","Tlaxcala","Calixtlahuaca","Xochicalco","Tlacopan",
"Atzcapotzalco","Tzintzuntzan","Malinalco","Tula","Tamuin","Teayo","Cempoala","Chalco","Tlalmanalco", "Atzcapotzalco","Tzintzuntzan","Malinalco","Tula","Tamuin","Teayo","Cempoala","Chalco","Tlalmanalco",
"Ixtapaluca","Huexotla","Tepexpan","Tepetlaoxtoc","Chiconautla","Zitlaltepec","Coyotepec","Tequixquiac", "Ixtapaluca","Huexotla","Tepexpan","Tepetlaoxtoc","Chiconautla","Zitlaltepec","Coyotepec","Tequixquiac",
"Jilotzingo","Tlapanaloya","Tultitan","Ecatepec","Coatepec","Chalchiuites","Chiauhita","Chapultepec", "Jilotzingo","Tlapanaloya","Tultitan","Ecatepec","Coatepec","Chalchiuites","Chiauhita","Chapultepec",
"Itzapalapa","Ayotzinco","Iztapam"] "Itzapalapa","Ayotzinco","Iztapam"]
}, },
*/
{ {
"name": "Inca", "name": "Inca",
"leaderName": "Pachacuti", "leaderName": "Pachacuti",

View file

@ -29,7 +29,7 @@
{ {
"name": "Landed Elite", "name": "Landed Elite",
"effect": "+10% food growth and +2 food in capital", "effect": "+10% food growth and +2 food in capital",
"uniques": ["+10% food growth in capital", "[+2 Food] in capital"], "uniques": ["+[10]% growth in capital", "[+2 Food] in capital"],
"requires": ["Legalism"], "requires": ["Legalism"],
"row": 2, "row": 2,
"column": 2 "column": 2
@ -45,7 +45,7 @@
{ {
"name": "Tradition Complete", "name": "Tradition Complete",
"effect": "+15% growth and +2 food in all cities", "effect": "+15% growth and +2 food in all cities",
"uniques": ["+15% growth in all cities","[+2 Food] in all cities"] "uniques": ["+[15]% growth in all cities","[+2 Food] in all cities"]
} }
] ]
}, },

View file

@ -50,7 +50,8 @@
"type": "Water", "type": "Water",
"food": 2, "food": 2,
"gold": 1, "gold": 1,
"RGB": [ 200, 200, 255] "RGB": [ 200, 200, 255],
"uniques": ["Fresh water"]
}, },
{ {
"name": "Hill", "name": "Hill",
@ -126,7 +127,8 @@
"movementCost": 1, "movementCost": 1,
"unbuildable": true, "unbuildable": true,
"defenceBonus": -0.1, "defenceBonus": -0.1,
"occursOn": ["Desert"] "occursOn": ["Desert"],
"uniques": ["Fresh water"]
}, },
{ {
"name": "Flood plains", "name": "Flood plains",
@ -188,7 +190,7 @@
"uniques": ["Grants 500 Gold to the first civilization to discover it"], "uniques": ["Grants 500 Gold to the first civilization to discover it"],
"weight": 2 "weight": 2
}, },
{ { // This will count as "Fresh water" in civ 6
"name": "Fountain of Youth", "name": "Fountain of Youth",
"type": "NaturalWonder", "type": "NaturalWonder",
"happiness": 10, "happiness": 10,
@ -263,4 +265,17 @@
"unbuildable": true, "unbuildable": true,
"weight": 10 "weight": 10
} }
/*
{// Will be introduced in Brave New World. Despite being a lake, it cannot be sailed on and it blocks line of sight like a mountain.
"name": "Lake Victoria",
"type": "NaturalWonder",
"food": 6,
"occursOn": [Plains"],
"turnsInto": "Mountain",
"impassable": true,
"unbuildable": true,
"uniques": ["Fresh water"],
"weight": 5
}
*/
] ]

View file

@ -54,23 +54,21 @@
"upgradesTo": "Swordsman", "upgradesTo": "Swordsman",
"attackSound": "nonmetalhit" "attackSound": "nonmetalhit"
}, },
/*
{ {
"name": "Jaguar", "name": "Jaguar",
"unitType": "Melee", "unitType": "Melee",
"uniqueTo": "Aztec", "uniqueTo": "Aztecs",
"replaces": "Warrior", "replaces": "Warrior",
"movement": 2, "movement": 2,
"strength": 8, "strength": 8,
"cost": 40, "cost": 40,
"hurryCostModifier": 20, "hurryCostModifier": 20,
"obsoleteTech": "Metal Casting", "obsoleteTech": "Metal Casting",
"uniques": ["+33% combat bonus in Forest/Jungle","Woodsmah","Heals 25 damage if it kills an Unit"], "uniques": ["+[33]% combat bonus in [Forest]", "+[33]% combat bonus in [Jungle]", "Heals [25] damage if it kills a unit"],
"promotions": ["Woodsman"],
"upgradesTo": "Swordsman", "upgradesTo": "Swordsman",
"attackSound": "nonmetalhit" "attackSound": "nonmetalhit"
//Aztec unique unit, moves faster and fights better in Forest and Jungle. He also heals 25 if he kills an enemy.
}, },
*/
{ {
"name": "Brute", "name": "Brute",
"unitType": "Melee", "unitType": "Melee",
@ -342,7 +340,7 @@
"upgradesTo": "Longswordsman", "upgradesTo": "Longswordsman",
"obsoleteTech": "Gunpowder", "obsoleteTech": "Gunpowder",
"hurryCostModifier": 20, "hurryCostModifier": 20,
"uniques": ["+33% combat bonus in Forest/Jungle"], "uniques": ["+[33]% combat bonus in [Forest]", "+[33]% combat bonus in [Jungle]"],
"attackSound": "metalhit" "attackSound": "metalhit"
}, },
{ {
@ -904,7 +902,7 @@
"requiredTech": "Rifling", "requiredTech": "Rifling",
"obsoleteTech": "Replaceable Parts", "obsoleteTech": "Replaceable Parts",
"upgradesTo": "Great War Infantry", "upgradesTo": "Great War Infantry",
"uniques": ["+25% bonus in Snow, Tundra and Hills", "Double movement in Snow, Tundra and Hills"], "uniques": ["+[25]% combat bonus in [Snow]", "+[25]% combat bonus in [Tundra]", "+[25]% combat bonus in [Hill]", "Double movement in Snow, Tundra and Hills"],
"hurryCostModifier": 20, "hurryCostModifier": 20,
"attackSound": "shot" "attackSound": "shot"
}, },

View file

@ -619,12 +619,14 @@ military units =
melee units = melee units =
mounted units = mounted units =
naval units = naval units =
ranged units =
# For the All "newly-trained [relevant] units in this city receive the [] promotion" translation. Relevant as in 'units that can receive' # For the All "newly-trained [relevant] units in this city receive the [] promotion" translation. Relevant as in 'units that can receive'
relevant = relevant =
# For '[stats] from [Water] tiles in this city' # For '[stats] from [Water] tiles in this city'
Water = Water =
# For [stats] from [Water resource] tiles in this city # For [stats] from [Water resource] tiles in this city
Water resource = Water resource =
River =
Wonders = Wonders =
Base values = Base values =
@ -809,6 +811,7 @@ Mass Media =
# Terrains # Terrains
Impassable = Impassable =
Fresh water =
# Resources # Resources

View file

@ -60,8 +60,6 @@ object Battle {
postBattleNotifications(attacker, defender, attackedTile) postBattleNotifications(attacker, defender, attackedTile)
tryHealAfterAttacking(attacker, defender)
postBattleNationUniques(defender, attackedTile, attacker) postBattleNationUniques(defender, attackedTile, attacker)
// This needs to come BEFORE the move-to-tile, because if we haven't conquered it we can't move there =) // This needs to come BEFORE the move-to-tile, because if we haven't conquered it we can't move there =)
@ -75,13 +73,17 @@ object Battle {
if(!isAlreadyDefeatedCity) postBattleAddXp(attacker, defender) if(!isAlreadyDefeatedCity) postBattleAddXp(attacker, defender)
// 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, gold from enemy killed when honor is complete
tryGetCultureFromHonor(attacker, defender) // or any enemy military unit with Sacrificial captives unique (can be either attacker or defender!)
tryGetCultureFromHonor(defender, attacker) if (defender.isDefeated() && defender is MapUnitCombatant && !defender.getUnitType().isCivilian()) {
tryGetCultureFromKilling(attacker, defender)
if (defender.isDefeated() && defender is MapUnitCombatant && !defender.getUnitType().isCivilian() tryGetGoldFromKilling(attacker, defender)
&& attacker.getCivInfo().hasUnique("Gain gold for each unit killed")) tryHealAfterKilling(attacker, defender)
attacker.getCivInfo().gold += defender.unit.baseUnit.getProductionCost(attacker.getCivInfo()) / 10 } else if (attacker.isDefeated() && attacker is MapUnitCombatant && !attacker.getUnitType().isCivilian()) {
tryGetCultureFromKilling(defender, attacker)
tryGetGoldFromKilling(defender, attacker)
tryHealAfterKilling(defender, attacker)
}
if (attacker is MapUnitCombatant) { if (attacker is MapUnitCombatant) {
if (attacker.getUnitType()==UnitType.Missile) { if (attacker.getUnitType()==UnitType.Missile) {
@ -143,16 +145,13 @@ object Battle {
} }
} }
private fun tryHealAfterAttacking(attacker: ICombatant, defender: ICombatant) { private fun tryHealAfterKilling(attacker: ICombatant, defender: ICombatant) {
if (defender.isDefeated() if (attacker is MapUnitCombatant)
&& defender is MapUnitCombatant
&& attacker is MapUnitCombatant) {
for (unique in attacker.unit.getMatchingUniques("Heals [] damage if it kills a unit")) { for (unique in attacker.unit.getMatchingUniques("Heals [] damage if it kills a unit")) {
val amountToHeal = unique.params[0].toInt() val amountToHeal = unique.params[0].toInt()
attacker.unit.healBy(amountToHeal) attacker.unit.healBy(amountToHeal)
} }
} }
}
private fun postBattleNationUniques(defender: ICombatant, attackedTile: TileInfo, attacker: ICombatant) { private fun postBattleNationUniques(defender: ICombatant, attackedTile: TileInfo, attacker: ICombatant) {
// German unique - needs to be checked before we try to move to the enemy tile, since the encampment disappears after we move in // German unique - needs to be checked before we try to move to the enemy tile, since the encampment disappears after we move in
@ -217,12 +216,19 @@ object Battle {
} }
} }
private fun tryGetCultureFromHonor(civUnit:ICombatant, barbarianUnit:ICombatant){ private fun tryGetCultureFromKilling(civUnit:ICombatant, defeatedUnit:MapUnitCombatant){
if(barbarianUnit.isDefeated() && barbarianUnit is MapUnitCombatant //Aztecs get half the strength of the unit killed in culture and honor opener does the same thing.
&& barbarianUnit.getCivInfo().isBarbarian() //They stack. So you get culture equal to 100% of the dead unit's strength.
&& civUnit.getCivInfo().hasUnique("Gain Culture when you kill a barbarian unit")) val civInfo = civUnit.getCivInfo()
civUnit.getCivInfo().policies.addCulture( if (defeatedUnit.getCivInfo().isBarbarian() && civInfo.hasUnique("Gain Culture when you kill a barbarian unit"))
max(barbarianUnit.unit.baseUnit.strength, barbarianUnit.unit.baseUnit.rangedStrength)) civInfo.policies.addCulture(max(defeatedUnit.unit.baseUnit.strength, defeatedUnit.unit.baseUnit.rangedStrength) / 2)
if (civInfo.hasUnique("Gains culture from each enemy unit killed"))
civInfo.policies.addCulture(max(defeatedUnit.unit.baseUnit.strength, defeatedUnit.unit.baseUnit.rangedStrength) / 2)
}
private fun tryGetGoldFromKilling(civUnit:ICombatant, defeatedUnit:MapUnitCombatant) {
if (civUnit.getCivInfo().hasUnique("Gain gold for each unit killed"))
civUnit.getCivInfo().gold += defeatedUnit.unit.baseUnit.getProductionCost(defeatedUnit.getCivInfo()) / 10
} }
// XP! // XP!

View file

@ -179,11 +179,9 @@ object BattleDamage {
modifiers.putAll(getTileSpecificModifiers(defender, tile)) modifiers.putAll(getTileSpecificModifiers(defender, tile))
if (!defender.unit.hasUnique("No defensive terrain bonus")) {
val tileDefenceBonus = tile.getDefensiveBonus() val tileDefenceBonus = tile.getDefensiveBonus()
if (tileDefenceBonus > 0) if (!defender.unit.hasUnique("No defensive terrain bonus") || tileDefenceBonus < 0)
modifiers["Tile"] = tileDefenceBonus modifiers["Tile"] = tileDefenceBonus
}
if (attacker.isRanged()) { if (attacker.isRanged()) {
val defenceVsRanged = 0.25f * defender.unit.getUniques().count { it.text == "+25% Defence against ranged attacks" } val defenceVsRanged = 0.25f * defender.unit.getUniques().count { it.text == "+25% Defence against ranged attacks" }
@ -212,6 +210,7 @@ object BattleDamage {
if(!tile.isFriendlyTerritory(unit.getCivInfo()) && unit.unit.hasUnique("+20% bonus outside friendly territory")) if(!tile.isFriendlyTerritory(unit.getCivInfo()) && unit.unit.hasUnique("+20% bonus outside friendly territory"))
modifiers["Foreign Land"] = 0.2f modifiers["Foreign Land"] = 0.2f
// This is to be deprecated and converted to "+[]% combat bonus in []" - keeping it here to that mods with this can still work for now
if (unit.unit.hasUnique("+25% bonus in Snow, Tundra and Hills") && if (unit.unit.hasUnique("+25% bonus in Snow, Tundra and Hills") &&
(tile.baseTerrain == Constants.snow (tile.baseTerrain == Constants.snow
|| tile.baseTerrain == Constants.tundra || tile.baseTerrain == Constants.tundra
@ -230,11 +229,18 @@ object BattleDamage {
.any { it.hasUnique("-10% combat strength for adjacent enemy units") && it.civInfo.isAtWarWith(unit.getCivInfo()) }) .any { it.hasUnique("-10% combat strength for adjacent enemy units") && it.civInfo.isAtWarWith(unit.getCivInfo()) })
modifiers["Haka War Dance"] = -0.1f modifiers["Haka War Dance"] = -0.1f
// This is to be deprecated and converted to "+[]% combat bonus in []" - keeping it here to that mods with this can still work for now
if(unit.unit.hasUnique("+33% combat bonus in Forest/Jungle") if(unit.unit.hasUnique("+33% combat bonus in Forest/Jungle")
&& (tile.terrainFeature== Constants.forest || tile.terrainFeature==Constants.jungle)) && (tile.terrainFeature== Constants.forest || tile.terrainFeature==Constants.jungle))
modifiers[tile.terrainFeature!!]=0.33f modifiers[tile.terrainFeature!!]=0.33f
for (unique in unit.unit.getUniques().filter { it.placeholderText == "+[]% combat bonus in []" })
if (tile.terrainFeature == unique.params[1])
modifiers[tile.terrainFeature!!] = unique.params[0].toFloat() / 100
else if (tile.baseTerrain == unique.params[1]
&& tile.terrainFeature == null)
modifiers[tile.baseTerrain] = unique.params[0].toFloat() / 100
val isRoughTerrain = tile.isRoughTerrain() val isRoughTerrain = tile.isRoughTerrain()
for (BDM in getBattleDamageModifiersOfUnit(unit.unit)) { for (BDM in getBattleDamageModifiersOfUnit(unit.unit)) {
val text = BDM.getText() val text = BDM.getText()

View file

@ -71,6 +71,13 @@ class CityConstructions {
val stats = Stats() val stats = Stats()
for (building in getBuiltBuildings()) for (building in getBuiltBuildings())
stats.add(building.getStats(cityInfo.civInfo)) stats.add(building.getStats(cityInfo.civInfo))
for (unique in builtBuildingUniqueMap.getAllUniques()) when (unique.placeholderText) {
"[] Per [] Population in this city" -> stats.add(Stats.parse(unique.params[0]).times(cityInfo.population.population / unique.params[1].toFloat()))
"[] once [] is discovered" -> if (cityInfo.civInfo.tech.isResearched(unique.params[1])) stats.add(Stats.parse(unique.params[0]))
}
// This is to be deprecated and converted to "[stats] Per [N] Population in this city" - keeping it here to that mods with this can still work for now
stats.science += (builtBuildingUniqueMap.getAllUniques().count { it.text == "+1 Science Per 2 Population" } * cityInfo.population.population / 2).toFloat() stats.science += (builtBuildingUniqueMap.getAllUniques().count { it.text == "+1 Science Per 2 Population" } * cityInfo.population.population / 2).toFloat()
return stats return stats
} }

View file

@ -267,7 +267,8 @@ class CityInfo {
if (stat != null) entry.value.add(stat, entry.value.get(stat) * unique.params[1].toFloat()/100) if (stat != null) entry.value.add(stat, entry.value.get(stat) * unique.params[1].toFloat()/100)
} }
for (unique in civInfo.getMatchingUniques("+[]% great person generation in all cities")) for (unique in civInfo.getMatchingUniques("+[]% great person generation in all cities")
+ cityConstructions.builtBuildingUniqueMap.getUniques("+[]% great person generation in this city"))
stats[entry.key] = stats[entry.key]!!.times(1 + (unique.params[0].toFloat() / 100)) stats[entry.key] = stats[entry.key]!!.times(1 + (unique.params[0].toFloat() / 100))
} }

View file

@ -161,13 +161,20 @@ class CityStats {
return stats return stats
} }
fun getGrowthBonusFromPolicies(): Float { fun getGrowthBonusFromPoliciesAndWonders(): Float {
var bonus = 0f var bonus = 0f
// This is to be deprecated and converted to "+[]% growth in all cities" and "+[]% growth in capital" - keeping it here to that mods with this can still work for now
if (cityInfo.civInfo.hasUnique("+10% food growth in capital") && cityInfo.isCapital()) if (cityInfo.civInfo.hasUnique("+10% food growth in capital") && cityInfo.isCapital())
bonus += 0.1f bonus += 10f
if (cityInfo.civInfo.hasUnique("+15% growth in all cities")) if (cityInfo.civInfo.hasUnique("+15% growth in all cities"))
bonus += 0.15f bonus += 15f
return bonus
for(unique in cityInfo.civInfo.getMatchingUniques("+[]% growth in all cities"))
bonus += unique.params[0].toFloat()
if (cityInfo.isCapital()) for(unique in cityInfo.civInfo.getMatchingUniques("+[]% growth in capital"))
bonus += unique.params[0].toFloat()
return bonus/100
} }
// needs to be a separate function because we need to know the global happiness state // needs to be a separate function because we need to know the global happiness state
@ -357,6 +364,7 @@ class CityStats {
return construction.name == filter return construction.name == filter
|| (filter == "land units" && construction is BaseUnit && construction.unitType.isLandUnit()) || (filter == "land units" && construction is BaseUnit && construction.unitType.isLandUnit())
|| (filter == "naval units" && construction is BaseUnit && construction.unitType.isWaterUnit()) || (filter == "naval units" && construction is BaseUnit && construction.unitType.isWaterUnit())
|| (filter == "ranged units" && construction is BaseUnit && construction.unitType == UnitType.Ranged)
|| (filter == "mounted units" && construction is BaseUnit && construction.unitType == UnitType.Mounted) || (filter == "mounted units" && construction is BaseUnit && construction.unitType == UnitType.Mounted)
|| (filter == "military units" && construction is BaseUnit && !construction.unitType.isCivilian()) || (filter == "military units" && construction is BaseUnit && !construction.unitType.isCivilian())
|| (filter == "melee units" && construction is BaseUnit && construction.unitType.isMelee()) || (filter == "melee units" && construction is BaseUnit && construction.unitType.isMelee())
@ -490,7 +498,7 @@ class CityStats {
// Since growth bonuses are special, (applied afterwards) they will be displayed separately in the user interface as well. // Since growth bonuses are special, (applied afterwards) they will be displayed separately in the user interface as well.
if(totalFood>0) { if(totalFood>0) {
val foodFromGrowthBonuses = getGrowthBonusFromPolicies() * totalFood val foodFromGrowthBonuses = getGrowthBonusFromPoliciesAndWonders() * totalFood
newFinalStatList["Policies"]!!.food += foodFromGrowthBonuses newFinalStatList["Policies"]!!.food += foodFromGrowthBonuses
totalFood = newFinalStatList.values.map { it.food }.sum() // recalculate again totalFood = newFinalStatList.values.map { it.food }.sum() // recalculate again
} }

View file

@ -24,6 +24,12 @@ open class TileInfo {
@Transient var isWater = false @Transient var isWater = false
@Transient var isOcean = false @Transient var isOcean = false
// This will be called often - farm can be built on Hill and tundra if adjacent to fresh water
// and farms on adjacent to fresh water tiles will have +1 additional Food after researching Civil Service
@delegate:Transient
val isAdjacentToFreshwater: Boolean by lazy { isAdjacentToRiver() || neighbors.any { it.getBaseTerrain().uniques.contains("Fresh water")
|| it.terrainFeature != null && it.getTerrainFeature()!!.uniques.contains("Fresh water") }}
var militaryUnit: MapUnit? = null var militaryUnit: MapUnit? = null
var civilianUnit: MapUnit? = null var civilianUnit: MapUnit? = null
var airUnits = ArrayList<MapUnit>() var airUnits = ArrayList<MapUnit>()
@ -188,6 +194,7 @@ open class TileInfo {
|| (tileType == "Water" && isWater) || (tileType == "Water" && isWater)
|| (tileType == "Strategic resource" && hasViewableResource(observingCiv) && getTileResource().resourceType == ResourceType.Strategic) || (tileType == "Strategic resource" && hasViewableResource(observingCiv) && getTileResource().resourceType == ResourceType.Strategic)
|| (tileType == "Water resource" && isWater && hasViewableResource(observingCiv)) || (tileType == "Water resource" && isWater && hasViewableResource(observingCiv))
|| (tileType == "River" && isAdjacentToRiver())
) )
stats.add(Stats.parse(unique.params[0])) stats.add(Stats.parse(unique.params[0]))
} }

View file

@ -257,6 +257,10 @@ class Building : NamedStats(), IConstruction {
&& !cityCenter.isCoastalTile()) && !cityCenter.isCoastalTile())
return "Can only be built in coastal cities" return "Can only be built in coastal cities"
if ("Must border a source of fresh water" in uniques
&& !cityCenter.isAdjacentToFreshwater)
return "Must border a source of fresh water"
if ("Can only be built in annexed cities" in uniques if ("Can only be built in annexed cities" in uniques
&& (construction.cityInfo.isPuppet || construction.cityInfo.foundingCiv == "" && (construction.cityInfo.isPuppet || construction.cityInfo.foundingCiv == ""
|| construction.cityInfo.civInfo.civName == construction.cityInfo.foundingCiv)) || construction.cityInfo.civInfo.civName == construction.cityInfo.foundingCiv))

View file

@ -175,6 +175,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
* [Stonehenge](https://thenounproject.com/term/stonehenge/543289/) By icon 54 * [Stonehenge](https://thenounproject.com/term/stonehenge/543289/) By icon 54
* [Ho Chi Minh mausoleum](https://thenounproject.com/thanhloc1009/collection/asia-landmark/?i=2412921) By Phạm Thanh Lộc for Mausoleum of Halicarnassus * [Ho Chi Minh mausoleum](https://thenounproject.com/thanhloc1009/collection/asia-landmark/?i=2412921) By Phạm Thanh Lộc for Mausoleum of Halicarnassus
* Icon for Statue of Zeus made by [JackRainy](https://github.com/JackRainy), based on [King](https://thenounproject.com/eucalyp/collection/game-elements-glyph1/?i=3155251) By Eucalyp * Icon for Statue of Zeus made by [JackRainy](https://github.com/JackRainy), based on [King](https://thenounproject.com/eucalyp/collection/game-elements-glyph1/?i=3155251) By Eucalyp
* [temple](https://thenounproject.com/search/?q=temple&i=28256) By Fabio Meroni for Temple of Artemis
### Classical Era ### Classical Era
@ -192,6 +193,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
* [Aqueduct](https://thenounproject.com/term/aqueduct/24639/) By Arthur Shlain * [Aqueduct](https://thenounproject.com/term/aqueduct/24639/) By Arthur Shlain
* [Great Wall](https://thenounproject.com/search/?q=great%20wall&i=545909) By icon 54 * [Great Wall](https://thenounproject.com/search/?q=great%20wall&i=545909) By icon 54
* [Rice Field](https://thenounproject.com/term/rice-field/2511648/) by Graphic Engineer for Terrace farm * [Rice Field](https://thenounproject.com/term/rice-field/2511648/) by Graphic Engineer for Terrace farm
* [Canoe](https://thenounproject.com/term/canoe/402285/) By Viktor Fedyuk (Tim P) for Floating Gardens
### Medieval Era ### Medieval Era
@ -214,6 +216,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
* [Notre Dame](https://thenounproject.com/term/notre-dame/1361725/) By Marco Livolsi * [Notre Dame](https://thenounproject.com/term/notre-dame/1361725/) By Marco Livolsi
* [Bullets](https://thenounproject.com/term/bullets/810156/) By Aldric Rodriguez for Armory * [Bullets](https://thenounproject.com/term/bullets/810156/) By Aldric Rodriguez for Armory
* [Machu Picchu](https://thenounproject.com/browse/?i=1678226/) By [Chanut is Industries](https://thenounproject.com/chanut-is) * [Machu Picchu](https://thenounproject.com/browse/?i=1678226/) By [Chanut is Industries](https://thenounproject.com/chanut-is)
* [Garden](https://thenounproject.com/search/?q=garden&i=1478380) By Bharat
### Renaissance Era ### Renaissance Era
@ -494,6 +497,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
* [Competition](https://thenounproject.com/search/?q=move%20fast&i=1743826) by luca fruzza * [Competition](https://thenounproject.com/search/?q=move%20fast&i=1743826) by luca fruzza
* Icon for Flight Deck is made by [JackRainy](https://github.com/JackRainy) * Icon for Flight Deck is made by [JackRainy](https://github.com/JackRainy)
* Icon for Armor Plating is made by [JackRainy](https://github.com/JackRainy) * Icon for Armor Plating is made by [JackRainy](https://github.com/JackRainy)
* [Slingshot](https://thenounproject.com/term/slingshot/9106/) by James Keuning for Slinger Withdraw
## Others ## Others