First step into unifying strength bonuses using conditionals (#5345)

This commit is contained in:
Xander Lenstra
2021-09-29 07:35:37 +02:00
committed by GitHub
parent 8ee36d43d7
commit bb5825a325
10 changed files with 160 additions and 93 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1005 KiB

After

Width:  |  Height:  |  Size: 1010 KiB

View File

@ -89,7 +89,7 @@
{
"name": "Honor",
"era": "Ancient era",
"uniques": ["+[33]% Strength vs [Barbarians]", "Earn [100]% of killed [Barbarian] unit's [Strength] as [Culture]",
"uniques": ["[+33]% Strength <vs [Barbarian] units>", "Earn [100]% of killed [Barbarian] unit's [Strength] as [Culture]",
"Notified of new Barbarian encampments"],
"policies": [
{

View File

@ -46,7 +46,7 @@
{
"name": "Volley",
"prerequisites": ["Accuracy I","Barrage I"],
"uniques": ["+[50]% Strength vs [City]"],
"uniques": ["[+50]% Strength <vs cities>"],
"unitTypes": ["Archery","Ranged Gunpowder","Siege"]
},
{
@ -101,25 +101,25 @@
{
"name": "Charge",
"prerequisites": ["Shock II","Drill II"],
"uniques": ["+[33]% Strength vs [wounded units]"],
"uniques": ["[+33]% Strength <vs [Wounded] units>"],
"unitTypes": ["Mounted","Armored"]
},
{
"name": "Besiege", // Not called "Siege" in order to not conflict with siege type units for translations
"prerequisites": ["Shock II","Drill II"],
"uniques": ["+[50]% Strength vs [City]"],
"uniques": ["[+50]% Strength <vs cities>"],
"unitTypes": ["Sword","Gunpowder"]
},
{
"name": "Formation I",
"prerequisites": ["Shock II","Drill II"], // G&K also has Accuracy II & Barrage II as possible prerequisites for this, but I couldn't find a source for the unittypes
"uniques": ["+[33]% Strength vs [Mounted]"],
"uniques": ["[+33]% Strength <vs [Mounted] units>"],
"unitTypes": ["Sword","Gunpowder","Mounted"]
},
{
"name": "Formation II",
"prerequisites": ["Formation I"],
"uniques": ["+[33]% Strength vs [Mounted]"],
"uniques": ["[+33]% Strength <vs [Mounted] units>"],
"unitTypes": ["Sword","Gunpowder","Mounted"]
},
@ -194,56 +194,56 @@
// Water melee
{
"name": "Boarding Party I",
"uniques": ["+[15]% Strength vs [water units]"],
"uniques": ["[+15]% Strength <vs [Water] units>"],
"unitTypes": ["Melee Water"]
},
{
"name": "Boarding Party II",
"prerequisites": ["Boarding Party I"],
"uniques": ["+[15]% Strength vs [water units]"],
"uniques": ["[+15]% Strength <vs [Water] units>"],
"unitTypes": ["Melee Water"]
},
{
"name": "Boarding Party III",
"prerequisites": ["Boarding Party II"],
"uniques": ["+[15]% Strength vs [water units]"],
"uniques": ["+[15]% Strength <vs [Water] units>"],
"unitTypes": ["Melee Water"]
},
{
"name": "Coastal Raider I",
"uniques": ["+[20]% Strength vs [City]", "Earn [33]% of the damage done to [City] units as [Gold]"],
"uniques": ["[+20]% Strength <vs cities>", "Earn [33]% of the damage done to [City] units as [Gold]"],
"unitTypes": ["Melee Water"]
},
{
"name": "Coastal Raider II",
"prerequisites": ["Coastal Raider I"],
"uniques": ["+[20]% Strength vs [City]", "Earn [33]% of the damage done to [City] units as [Gold]"],
"uniques": ["[+20]% Strength <vs cities>", "Earn [33]% of the damage done to [City] units as [Gold]"],
"unitTypes": ["Melee Water"]
},
{
"name": "Coastal Raider III",
"prerequisites": ["Coastal Raider II"],
"uniques": ["+[20]% Strength vs [City]", "Earn [33]% of the damage done to [City] units as [Gold]"],
"uniques": ["[+20]% Strength <vs cities>", "Earn [33]% of the damage done to [City] units as [Gold]"],
"unitTypes": ["Melee Water"]
},
// Water Ranged
{
"name": "Targeting I",
"uniques": ["+[15]% Strength vs [water units]"],
"uniques": ["[+15]% Strength <vs [Water] units>"],
"unitTypes": ["Ranged Water"]
},
{
"name": "Targeting II",
"prerequisites": ["Targeting I"],
"uniques": ["+[15]% Strength vs [water units]"],
"uniques": ["[+15]% Strength <vs [Water] units>"],
"unitTypes": ["Ranged Water"]
},
{
"name": "Targeting III",
"prerequisites": ["Targeting II"],
"uniques": ["+[15]% Strength vs [water units]"],
"uniques": ["[+15]% Strength <vs [Water] units>"],
"unitTypes": ["Ranged Water"]
},
@ -313,19 +313,19 @@
// Bomber
{
"name": "Siege I",
"uniques": ["+[33]% Strength vs [City]"],
"uniques": ["[+33]% Strength <vs cities>"],
"unitTypes": ["Bomber"]
},
{
"name": "Siege II",
"prerequisites": ["Siege I"],
"uniques": ["+[33]% Strength vs [City]"],
"uniques": ["[+33]% Strength <vs cities>"],
"unitTypes": ["Bomber"]
},
{
"name": "Siege III",
"prerequisites": ["Siege II"],
"uniques": ["+[34]% Strength vs [City]"],
"uniques": ["[+34]% Strength <vs cities>"],
"unitTypes": ["Bomber"]
},
{
@ -376,13 +376,13 @@
{
"name": "Air Targeting I",
"prerequisites": ["Interception I","Dogfighting I", "Siege I","Bombardment I"],
"uniques": ["+[33]% Strength vs [water units]"],
"uniques": ["[+33]% Strength <vs [Water] units>"],
"unitTypes": ["Fighter","Bomber"]
},
{
"name": "Air Targeting II",
"prerequisites": ["Air Targeting I"],
"uniques": ["+[33]% Strength vs [water units]"],
"uniques": ["[+33]% Strength <vs [Water] units>"],
"unitTypes": ["Fighter","Bomber"]
},
@ -420,13 +420,13 @@
},
{
"name": "Anti-Armor I",
"uniques": ["+[25]% Strength vs [Armored]"],
"uniques": ["[+25]% Strength <vs [Armored] units>"],
"unitTypes": ["Helicopter"]
},
{
"name": "Anti-Armor II",
"prerequisites": ["Anti-Armor I"],
"uniques": ["+[25]% Strength vs [Armored]"],
"uniques": ["[+25]% Strength <vs [Armored] units>"],
"unitTypes": ["Helicopter"]
},
@ -472,13 +472,13 @@
{
"name": "Ambush I",
"uniques": ["+[33]% Strength vs [Armored]"],
"uniques": ["[+33]% Strength <vs [Armored] units>"],
"unitTypes": ["Sword","Gunpowder","Fighter","Bomber"]
},
{
"name": "Ambush II",
"prerequisites": ["Ambush I"],
"uniques": ["+[33]% Strength vs [Armored]"],
"uniques": ["[+33]% Strength <vs [Armored] units>"],
"unitTypes": ["Sword","Gunpowder","Fighter","Bomber"]
},
@ -486,26 +486,26 @@
// Water ranged and air units
{
"name": "Bombardment I",
"uniques": ["+[33]% Strength vs [land units]"],
"uniques": ["[+33]% Strength <vs [Land] units>"],
"unitTypes": ["Ranged Water","Fighter","Bomber"]
},
{
"name": "Bombardment II",
"prerequisites": ["Bombardment I"],
"uniques": ["+[33]% Strength vs [land units]"],
"uniques": ["[+33]% Strength <vs [Land] units>"],
"unitTypes": ["Ranged Water","Fighter","Bomber"]
},
{
"name": "Bombardment III",
"prerequisites": ["Bombardment II"],
"uniques": ["+[34]% Strength vs [land units]"],
"uniques": ["[+34]% Strength <vs [Land] units>"],
"unitTypes": ["Ranged Water","Fighter","Bomber"]
},
// Uniques that should be kept on upgrades
{
"name": "Morale", // Heroic Epic
"uniques": ["+[15]% Combat Strength"]
"uniques": ["[+15]% Strength"]
},
{
"name": "Great Generals I", // only for Companion Cavalry, Keshik and their subsequent upgrades

View File

@ -185,7 +185,7 @@
"rangedStrength": 10,
"cost": 56,
"requiredTech": "Sailing",
"uniques": ["Cannot enter ocean tiles", "+[50]% Strength vs [Water] units"],
"uniques": ["Cannot enter ocean tiles", "[+50]% Strength <vs [Water] units>"],
"upgradesTo": "Galleass",
"obsoleteTech": "Astronomy",
"attackSound": "arrow"
@ -273,7 +273,7 @@
"requiredTech": "Bronze Working",
"obsoleteTech": "Civil Service",
"upgradesTo": "Pikeman",
"uniques": ["+[50]% Strength vs [Mounted]"],
"uniques": ["[+50]% Strength <vs [Mounted] units>"],
"attackSound": "metalhit"
},
{
@ -287,7 +287,7 @@
"requiredTech": "Bronze Working",
"obsoleteTech": "Civil Service",
"upgradesTo": "Pikeman",
"uniques": ["+[50]% Strength vs [Mounted]"],
"uniques": ["[+50]% Strength <vs [Mounted] units>"],
"attackSound": "metalhit"
},
{
@ -301,7 +301,7 @@
"requiredTech": "Bronze Working",
"obsoleteTech": "Civil Service",
"upgradesTo": "Pikeman",
"uniques": ["+[50]% Strength vs [Mounted]","[+10] HP when healing"],
"uniques": ["[+50]% Strength <vs [Mounted] units>","[+10] HP when healing"],
"attackSound": "metalhit"
},
{
@ -315,7 +315,7 @@
"requiredTech": "Bronze Working",
"obsoleteTech": "Physics",
"upgradesTo": "Trebuchet",
"uniques": ["+[300]% Strength vs [City]", "No defensive terrain bonus", "+[-33]% Strength when defending",
"uniques": ["[+300]% Strength <vs cities>", "No defensive terrain bonus", "+[-33]% Strength when defending",
"-[1] Visibility Range", "Can only attack [City] units"],
"promotions": ["Cover I"],
"attackSound": "throw"
@ -330,7 +330,7 @@
"requiredTech": "Bronze Working",
"obsoleteTech": "Civil Service",
"upgradesTo": "Pikeman",
"uniques": ["+[50]% Strength vs [Mounted]"],
"uniques": ["[+50]% Strength <vs [Mounted] units>"],
"attackSound": "metalhit"
// Barbarian unique Spearman. Has same icon and name but slightly different 3d texture
},
@ -347,7 +347,7 @@
"requiredResource": "Horses",
"upgradesTo": "Knight",
"obsoleteTech": "Chivalry",
"uniques": ["Can move after attacking","No defensive terrain bonus","-[33]% Strength vs [City]" ],
"uniques": ["Can move after attacking","No defensive terrain bonus","[-33]% Strength <vs cities>" ],
"hurryCostModifier": 20,
"attackSound": "horse"
},
@ -364,7 +364,7 @@
"obsoleteTech": "Chivalry",
"promotions": ["Great Generals I"],
"requiredResource": "Horses",
"uniques": ["Can move after attacking", "No defensive terrain bonus", "-[33]% Strength vs [City]"],
"uniques": ["Can move after attacking", "No defensive terrain bonus", "[-33]% Strength <vs cities>"],
"hurryCostModifier": 20,
"attackSound": "horse"
},
@ -380,7 +380,7 @@
"upgradesTo": "Knight",
"obsoleteTech": "Chivalry",
"promotions": ["Great Generals II"],
"uniques": ["Can move after attacking", "No defensive terrain bonus", "-[33]% Strength vs [City]",
"uniques": ["Can move after attacking", "No defensive terrain bonus", "[-33]% Strength <vs cities>",
"[-10]% Strength for enemy [Military] units in adjacent [All] tiles"],
"hurryCostModifier": 20,
"attackSound": "elephant"
@ -396,7 +396,7 @@
"requiredTech": "Horseback Riding",
"upgradesTo": "Knight",
"obsoleteTech": "Chivalry",
"uniques": ["Can move after attacking", "-[25]% Strength vs [City]"],
"uniques": ["Can move after attacking", "[-25]% Strength <vs cities>"],
"hurryCostModifier": 20,
"attackSound": "horse"
},
@ -410,7 +410,7 @@
"requiredTech": "Mathematics",
"obsoleteTech": "Physics",
"upgradesTo": "Trebuchet",
"uniques": ["+[200]% Strength vs [City]", "No defensive terrain bonus",
"uniques": ["[+200]% Strength <vs cities>", "No defensive terrain bonus",
"Must set up to ranged attack", "Limited Visibility"],
"hurryCostModifier": 20,
"attackSound": "throw"
@ -427,7 +427,7 @@
"requiredTech": "Mathematics",
"obsoleteTech": "Physics",
"upgradesTo": "Trebuchet",
"uniques": ["+[200]% Strength vs [City]", "No defensive terrain bonus",
"uniques": ["[+200]% Strength <vs cities>", "No defensive terrain bonus",
"Must set up to ranged attack", "Limited Visibility"],
"hurryCostModifier": 20,
"attackSound": "throw"
@ -513,7 +513,7 @@
"strength": 16,
"cost": 90,
"requiredTech": "Civil Service",
"uniques": ["+[50]% Strength vs [Mounted]"],
"uniques": ["[+50]% Strength <vs [Mounted] units>"],
"upgradesTo": "Lancer",
"obsoleteTech": "Gunpowder",
"attackSound": "metalhit"
@ -527,7 +527,7 @@
"strength": 16,
"cost": 45,
"requiredTech": "Civil Service",
"uniques": ["+[50]% Strength vs [Mounted]", "Can move immediately once bought" ],
"uniques": ["[+50]% Strength <vs [Mounted] units>", "Can move immediately once bought" ],
"upgradesTo": "Lancer",
"obsoleteTech": "Gunpowder",
"attackSound": "metalhit"
@ -556,7 +556,7 @@
"obsoleteTech": "Military Science",
"upgradesTo": "Cavalry",
"requiredResource": "Horses",
"uniques": ["Can move after attacking","No defensive terrain bonus","-[33]% Strength vs [City]" ],
"uniques": ["Can move after attacking","No defensive terrain bonus","[-33]% Strength <vs cities>" ],
"attackSound": "horse"
},
{
@ -604,7 +604,7 @@
"requiredTech": "Chivalry",
"obsoleteTech": "Military Science",
"upgradesTo": "Cavalry",
"uniques": ["Can move after attacking","No defensive terrain bonus","+[50]% Strength vs [Mounted]","-[33]% Strength vs [City]"],
"uniques": ["Can move after attacking","No defensive terrain bonus","[+50]% Strength <vs [Mounted] units>","[-33]% Strength <vs cities>"],
"attackSound": "elephant"
},
{
@ -694,7 +694,7 @@
"requiredTech": "Physics",
"obsoleteTech": "Chemistry",
"upgradesTo": "Cannon",
"uniques": ["+[200]% Strength vs [City]","No defensive terrain bonus","Must set up to ranged attack","Limited Visibility"],
"uniques": ["[+200]% Strength <vs cities>","No defensive terrain bonus","Must set up to ranged attack","Limited Visibility"],
"attackSound": "throw"
},
{
@ -852,7 +852,7 @@
"requiredTech": "Gunpowder",
"upgradesTo": "Rifleman",
"obsoleteTech": "Rifling",
"uniques": ["+[50]% Strength vs [Mounted]"],
"uniques": ["[+50]% Strength <vs [Mounted] units>"],
"attackSound": "shot"
},
{
@ -920,7 +920,7 @@
"cost": 185,
"requiredTech": "Metallurgy",
"requiredResource": "Horses",
"uniques": ["Can move after attacking","No defensive terrain bonus","-[33]% Strength vs [City]"],
"uniques": ["Can move after attacking","No defensive terrain bonus","[-33]% Strength <vs cities>"],
"promotions": ["Formation I"],
"upgradesTo": "Anti-Tank Gun",
"obsoleteTech": "Combined Arms",
@ -936,7 +936,7 @@
"cost": 185,
"requiredTech": "Metallurgy",
"requiredResource": "Horses",
"uniques": ["Can move after attacking","No defensive terrain bonus","-[33]% Strength vs [City]",
"uniques": ["Can move after attacking","No defensive terrain bonus","[-33]% Strength <vs cities>",
"[+1] Visibility Range", "No movement cost to pillage"],
"promotions": ["Formation I"],
"upgradesTo": "Anti-Tank Gun",
@ -953,7 +953,7 @@
"cost": 185,
"requiredTech": "Metallurgy",
"requiredResource": "Horses",
"uniques": ["Can move after attacking","No defensive terrain bonus","-[33]% Strength vs [City]",
"uniques": ["Can move after attacking","No defensive terrain bonus","[-33]% Strength <vs cities>",
"Transfer Movement to [Great General]", "[+15]% Strength when stacked with [Great General]"],
"promotions": ["Formation I"],
"upgradesTo": "Anti-Tank Gun",
@ -970,7 +970,7 @@
"requiredTech": "Chemistry",
"upgradesTo": "Artillery",
"obsoleteTech": "Dynamite",
"uniques": ["+[200]% Strength vs [City]","No defensive terrain bonus","Must set up to ranged attack","Limited Visibility"],
"uniques": ["[+200]% Strength <vs cities>","No defensive terrain bonus","Must set up to ranged attack","Limited Visibility"],
"attackSound": "cannon"
},
@ -1043,7 +1043,7 @@
"obsoleteTech": "Combustion",
"requiredResource": "Horses",
"upgradesTo": "Landship",
"uniques": ["Can move after attacking","No defensive terrain bonus","-[33]% Strength vs [City]" ],
"uniques": ["Can move after attacking","No defensive terrain bonus","[-33]% Strength <vs cities>" ],
"attackSound": "horse"
},
{
@ -1059,7 +1059,7 @@
"requiredResource": "Horses",
"upgradesTo": "Landship",
"uniques": ["Can move after attacking","No defensive terrain bonus",
"-[33]% Strength vs [City]", "+[50]% Strength vs [wounded units]"],
"[-33]% Strength <vs cities>", "[+50]% Strength <vs [Wounded] units>"],
"attackSound": "horse"
},
{
@ -1074,7 +1074,7 @@
"obsoleteTech": "Combustion",
"requiredResource": "Horses",
"upgradesTo": "Landship",
"uniques": ["Can move after attacking","No defensive terrain bonus","-[33]% Strength vs [City]" ,
"uniques": ["Can move after attacking","No defensive terrain bonus","[-33]% Strength <vs cities>" ,
"[+1] Visibility Range", "[+50]% to Flank Attack bonuses" ],
"attackSound": "horse"
},
@ -1088,7 +1088,7 @@
"requiredResource": "Coal",
"upgradesTo": "Destroyer",
"obsoleteTech": "Combustion",
"uniques": ["+[33]% Strength vs [City]","Double movement in [Coast]"],
"uniques": ["[+33]% Strength <vs cities>","Double movement in [Coast]"],
"attackSound": "shipguns"
},
{
@ -1101,7 +1101,7 @@
"cost": 320,
"requiredTech": "Dynamite",
"upgradesTo": "Rocket Artillery",
"uniques": ["+[200]% Strength vs [City]","No defensive terrain bonus",
"uniques": ["[+200]% Strength <vs cities>","No defensive terrain bonus",
"Must set up to ranged attack","Limited Visibility","Ranged attacks may be performed over obstacles"],
"attackSound": "artillery"
},
@ -1158,7 +1158,7 @@
"requiredResource": "Oil",
"upgradesTo": "Fighter",
"obsoleteTech": "Radar",
"uniques": ["[50]% chance to intercept air attacks", "+[150]% Strength vs [Bomber]", "+[150]% Strength vs [Helicopter]"],
"uniques": ["[50]% chance to intercept air attacks", "[+150]% Strength <vs [Bomber] units>", "[+150]% Strength <vs [Helicopter] units>"],
"attackSound": "machinegun"
},
{
@ -1232,7 +1232,7 @@
"requiredTech": "Ballistics",
"upgradesTo": "Mobile SAM",
"obsoleteTech": "Rocketry",
"uniques": ["[100]% chance to intercept air attacks", "+[150]% Strength vs [air units]", "+[150]% Strength vs [Helicopter]"],
"uniques": ["[100]% chance to intercept air attacks", "[+150]% Strength <vs [Air] units>", "[+150]% Strength <vs [Helicopter] units>"],
"attackSound": "machinegun"
},
{
@ -1257,7 +1257,7 @@
"cost": 375,
"requiredTech": "Combustion",
"uniques": ["Can see invisible [Submarine] units", "[40]% chance to intercept air attacks",
"May withdraw before melee ([80]%)", "+[100]% Strength vs [submarine units]"],
"May withdraw before melee ([80]%)", "[+100]% Strength <vs [Submarine] units>"],
"attackSound": "shipguns"
},
@ -1286,7 +1286,7 @@
"requiredTech": "Radar",
"requiredResource": "Oil",
"upgradesTo": "Jet Fighter",
"uniques": ["[100]% chance to intercept air attacks", "+[150]% Strength vs [Bomber]", "+[150]% Strength vs [Helicopter]"],
"uniques": ["[100]% chance to intercept air attacks", "[+150]% Strength <vs [Bomber] units>", "[+150]% Strength <vs [Helicopter] units>"],
"attackSound": "machinegun"
},
{
@ -1302,8 +1302,8 @@
"cost": 375,
"requiredTech": "Radar",
"upgradesTo": "Jet Fighter",
"uniques": ["[100]% chance to intercept air attacks", "+[150]% Strength vs [Bomber]", "+[150]% Strength vs [Helicopter]",
"+[33]% Strength vs [Fighter]"],
"uniques": ["[100]% chance to intercept air attacks", "[+150]% Strength <vs [Bomber] units>", "[+150]% Strength <vs [Helicopter] units>",
"[+33]% Strength <vs [Fighter] units>"],
"attackSound": "machinegun"
},
{
@ -1381,7 +1381,7 @@
"cost": 300,
"requiredTech": "Combined Arms",
"upgradesTo": "Helicopter Gunship",
"uniques": ["+[100]% Strength vs [Armored]"],
"uniques": ["[+100]% Strength <vs [Armored] units>"],
"attackSound": "machinegun"
},
{
@ -1411,7 +1411,7 @@
"cost": 425,
"requiredTech": "Rocketry",
"requiredResource": "Aluminum",
"uniques": ["+[200]% Strength vs [City]","No defensive terrain bonus",
"uniques": ["[+200]% Strength <vs cities>","No defensive terrain bonus",
"Limited Visibility","Ranged attacks may be performed over obstacles"],
"attackSound": "artillery"
},
@ -1423,7 +1423,7 @@
"strength": 65,
"cost": 425,
"requiredTech": "Rocketry",
"uniques": ["[100]% chance to intercept air attacks", "+[150]% Strength vs [air units]", "+[150]% Strength vs [Helicopter]"],
"uniques": ["[100]% chance to intercept air attacks", "[+150]% Strength <vs [Air] units>", "[+150]% Strength <vs [Helicopter] units>"],
"attackSound": "missile"
},
{
@ -1460,7 +1460,7 @@
"cost": 425,
"requiredTech": "Computers",
"requiredResource": "Aluminum",
"uniques": ["+[100]% Strength vs [Armored]", "No defensive terrain bonus", "Can move after attacking",
"uniques": ["[+100]% Strength <vs [Armored] units>", "No defensive terrain bonus", "Can move after attacking",
"All tiles cost 1 movement", "Ignores Zone of Control", "Unable to capture cities"],
"attackSound": "machinegun"
},
@ -1499,7 +1499,7 @@
"requiredTech": "Robotics",
"uniques": ["[100]% chance to intercept air attacks", "Can see invisible [Submarine] units",
"Ranged attacks may be performed over obstacles", "Can carry [3] [Missile] units",
"+[100]% Strength vs [submarine units]"],
"[+100]% Strength <vs [Submarine] units>"],
"attackSound": "shipguns"
},
{
@ -1525,7 +1525,7 @@
"cost": 425,
"requiredTech": "Lasers",
"requiredResource": "Aluminum",
"uniques": ["[100]% chance to intercept air attacks", "+[150]% Strength vs [Bomber]", "+[150]% Strength vs [Helicopter]"],
"uniques": ["[100]% chance to intercept air attacks", "[+150]% Strength <vs [Bomber] units>", "[+150]% Strength <vs [Helicopter] units>"],
"attackSound": "jetgun"
},
{

View File

@ -2,6 +2,8 @@ package com.unciv.logic.battle
import com.unciv.logic.map.TileInfo
import com.unciv.models.Counter
import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.ui.utils.toPercent
import java.util.*
import kotlin.collections.set
@ -21,23 +23,30 @@ object BattleDamage {
val civInfo = combatant.getCivInfo()
if (combatant is MapUnitCombatant) {
for (unique in
combatant.unit.getMatchingUniques("+[]% Strength vs []") +
civInfo.getMatchingUniques("+[]% Strength vs []")
for (unique in combatant.unit.getMatchingUniques(
UniqueType.Strength,
StateForConditionals(civInfo, defender = enemy))
) {
if (enemy.matchesCategory(unique.params[1]))
modifiers.add("vs [${unique.params[1]}]", unique.params[0].toInt())
modifiers.add("${unique.sourceObjectName} (${unique.sourceObjectType})", unique.params[0].toInt())
}
for (unique in combatant.unit.getMatchingUniques("-[]% Strength vs []")+
civInfo.getMatchingUniques("-[]% Strength vs []")
) {
if (enemy.matchesCategory(unique.params[1]))
modifiers.add("vs [${unique.params[1]}]", -unique.params[0].toInt())
}
for (unique in combatant.unit.getMatchingUniques("+[]% Combat Strength"))
modifiers.add("Combat Strength", unique.params[0].toInt())
// Deprecated since 3.17.3
for (unique in
combatant.unit.getMatchingUniques("+[]% Strength vs []")
) {
if (enemy.matchesCategory(unique.params[1]))
modifiers.add("vs [${unique.params[1]}]", unique.params[0].toInt())
}
for (unique in combatant.unit.getMatchingUniques("-[]% Strength vs []")
) {
if (enemy.matchesCategory(unique.params[1]))
modifiers.add("vs [${unique.params[1]}]", -unique.params[0].toInt())
}
for (unique in combatant.unit.getMatchingUniques("+[]% Combat Strength"))
modifiers.add("Combat Strength", unique.params[0].toInt())
//
//https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php
val civHappiness = if (civInfo.isCityState() && civInfo.getAllyCiv() != null)
// If we are a city state with an ally we are vulnerable to their unhappiness.

View File

@ -14,6 +14,7 @@ import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.tile.TerrainType
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.tile.TileImprovement
import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.models.ruleset.unit.UnitType
@ -228,9 +229,12 @@ class MapUnit {
tempUniques.asSequence().filter { it.placeholderText == placeholderText } +
civInfo.getMatchingUniques(placeholderText)
fun getMatchingUniques(uniqueType: UniqueType): Sequence<Unique> =
tempUniques.asSequence().filter { it.type == uniqueType } +
civInfo.getMatchingUniques(uniqueType)
fun getMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals? = null) = sequence {
yieldAll(tempUniques.asSequence()
.filter { it.type == uniqueType && it.conditionalsApply(stateForConditionals)}
)
yieldAll(civInfo.getMatchingUniques(uniqueType, stateForConditionals))
}
fun hasUnique(unique: String): Boolean {
return tempUniques.any { it.placeholderText == unique } || civInfo.hasUnique(unique)

View File

@ -1,9 +1,21 @@
package com.unciv.models.ruleset.unique
import com.unciv.logic.battle.ICombatant
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.TileInfo
data class StateForConditionals(
val civInfo: CivilizationInfo? = null,
val cityInfo: CityInfo? = null,
)
val defender: ICombatant? = null,
// val attacker: ICombatant? = null,
// val attackedTile: TileInfo? = null,
// val combatAction: CombatAction? = null,
)
//enum class CombatAction() {
// Attack,
// Defend,
// Intercept,
//}

View File

@ -50,6 +50,10 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
state.cityInfo != null && state.cityInfo.population.getNumberOfSpecialists() >= condition.params[0].toInt()
UniqueType.ConditionalHappy.placeholderText ->
state.civInfo != null && state.civInfo.statsForNextTurn.happiness >= 0
UniqueType.ConditionalVsCity.placeholderText ->
state.defender != null && state.defender.matchesCategory("City")
UniqueType.ConditionalVsUnits.placeholderText ->
state.defender != null && state.defender.matchesCategory(condition.params[0])
else -> false
}
}

View File

@ -80,7 +80,6 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget) {
TileProvidesYieldWithoutPopulation("Tile provides yield without assigned population", UniqueTarget.Improvement),
@Deprecated("As of 3.16.16", ReplaceWith("[amount]% maintenance costs for [mapUnitFilter] units"), DeprecationLevel.WARNING)
DecreasedUnitMaintenanceCostsByFilter("-[amount]% [mapUnitFilter] unit maintenance costs"), // No conditional support
@Deprecated("As of 3.16.16", ReplaceWith("[amount]% maintenance costs for [mapUnitFilter] units"), DeprecationLevel.WARNING)
@ -88,6 +87,20 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget) {
@Deprecated("As of 3.16.16", ReplaceWith("[stats] <if this city has at least [amount] specialists>"), DeprecationLevel.WARNING)
StatBonusForNumberOfSpecialists("[stats] if this city has at least [amount] specialists"), // No conditional support
Strength("[amount]% Strength", UniqueTarget.Unit, UniqueTarget.Global),
@Deprecated("As of 3.17.3", ReplaceWith("[amount]% Strength"), DeprecationLevel.WARNING)
StrengthPlus("+[amount]% Strength"),
@Deprecated("As of 3.17.3", ReplaceWith("[amount]% Strength"), DeprecationLevel.WARNING)
StrengthMin("-[amount]% Strength"),
@Deprecated("As of 3.17.3", ReplaceWith("[amount]% Strength <vs [unitFilter] units> OR [amount]% Strength <vs cities>"), DeprecationLevel.WARNING)
StrengthPlusVs("+[amount]% Strength vs [combatantFilter]"),
@Deprecated("As of 3.17.3", ReplaceWith("[amount]% Strength <vs [unitFilter] units> OR [amount]% Strength <vs cities>"), DeprecationLevel.WARNING)
StrengthMinVs("-[amount]% Strength vs [combatantFilter]"),
@Deprecated("As of 3.17.3", ReplaceWith("[amount]% Strength"), DeprecationLevel.WARNING)
CombatBonus("+[amount]% Combat Strength"),
// TODO: Unify these (I'm in favor of "gain a free" above "provides" because it fits more cases)
ProvidesFreeBuildings("Provides a free [buildingName] [cityFilter]", UniqueTarget.Global),
GainFreeBuildings("Gain a free [buildingName] [cityFilter]", UniqueTarget.Global),
@ -134,12 +147,18 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget) {
CannotEnterOceanUntilAstronomy("Cannot enter ocean tiles until Astronomy", UniqueTarget.Unit),
///// CONDITIONALS
// Conditionals
ConditionalWar("when at war", UniqueTarget.Conditional),
ConditionalNotWar("when not at war", UniqueTarget.Conditional),
ConditionalSpecialistCount("if this city has at least [amount] specialists", UniqueTarget.Conditional),
ConditionalHappy("while the empire is happy", UniqueTarget.Conditional),
ConditionalVsCity("vs cities", UniqueTarget.Conditional),
ConditionalVsUnits("vs [mapUnitFilter] units", UniqueTarget.Conditional),
// ConditionalInTiles("fighting in [tileFilter] tiles", UniqueTarget.Conditional),
// ConditionalAttacking("when attacking", UniqueTarget.Conditional),
// ConditionalDefending("when defending", UniqueTarget.Conditional),
// ConditionalIntercepting("when intercepting", UniqueTarget.Conditional),
;
/** For uniques that have "special" parameters that can accept multiple types, we can override them manually

View File

@ -556,7 +556,10 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
(
isRanged()
&& (uniqueObjects + getType().uniqueObjects)
.any { it.placeholderText == "+[]% Strength vs []" && it.params[1] == "City" }
.any { it.isOfType(UniqueType.Strength)
&& it.params[0].toInt() > 0
&& it.conditionals.any { conditional -> conditional.isOfType(UniqueType.ConditionalVsCity) }
}
)
fun getForceEvaluation(): Int {
@ -593,10 +596,18 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
for (unique in uniqueObjects) {
when {
unique.placeholderText == "+[]% Strength vs []" && unique.params[1] == "City" // City Attack - half the bonus
-> power += (power * unique.params[0].toInt()) / 200
unique.placeholderText == "+[]% Strength vs []" && unique.params[1] != "City" // Bonus vs something else - a quarter of the bonus
-> power += (power * unique.params[0].toInt()) / 400
unique.isOfType(UniqueType.Strength) && unique.params[0].toInt() > 0 -> {
if (unique.conditionals.any { it.isOfType(UniqueType.ConditionalVsCity) })
power += (power * unique.params[0].toInt()) / 200
else if (unique.conditionals.any { it.isOfType(UniqueType.ConditionalVsUnits) })
power += (power * unique.params[0].toInt()) / 400
}
// Deprecated since 3.17.3
unique.placeholderText == "+[]% Strength vs []" && unique.params[1] == "City" // City Attack - half the bonus
-> power += (power * unique.params[0].toInt()) / 200
unique.placeholderText == "+[]% Strength vs []" && unique.params[1] != "City" // Bonus vs something else - a quarter of the bonus
-> power += (power * unique.params[0].toInt()) / 400
//
unique.placeholderText == "+[]% Strength when attacking" // Attack - half the bonus
-> power += (power * unique.params[0].toInt()) / 200
unique.placeholderText == "+[]% Strength when defending" // Defense - half the bonus
@ -614,10 +625,18 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
for (promotionName in promotions) {
for (unique in ruleset.unitPromotions[promotionName]!!.uniqueObjects) {
when {
unique.isOfType(UniqueType.Strength) && unique.params[0].toInt() > 0 -> {
if (unique.conditionals.any { it.isOfType(UniqueType.ConditionalVsCity) })
power += (power * unique.params[0].toInt()) / 200
else if (unique.conditionals.any { it.isOfType(UniqueType.ConditionalVsUnits) })
power += (power * unique.params[0].toInt()) / 400
}
// Deprecated since 3.17.3
unique.placeholderText == "+[]% Strength vs []" && unique.params[1] == "City" // City Attack - half the bonus
-> power += (power * unique.params[0].toInt()) / 200
unique.placeholderText == "+[]% Strength vs []" && unique.params[1] != "City" // Bonus vs something else - a quarter of the bonus
-> power += (power * unique.params[0].toInt()) / 400
//
unique.placeholderText == "+[]% Strength when attacking" // Attack - half the bonus
-> power += (power * unique.params[0].toInt()) / 200
unique.placeholderText == "+[]% Strength when defending" // Defense - half the bonus