New parameterized uniques (#3250)

* -New unit unique "Bonus as Defender []%". "+25% Combat Bonus when defending" now deprecated, but kept for now for mods. Json promotion changed to fit new syntax.
Defender Bonus modifier "Defender Bonus" added to template.properties for translation.

-"All newly-trained [] units in this city receive the [] promotion" now uses unit category checking.

-New building unique "New [] units start with [] Experience in this city"
This can used by Poland's stable unique replacement in BNW, as it gives extra xp for mounted units.
"New [] units start with [] Experience" is the new nation wide version of this.

"New military units start with [] Experience" is now deprecated, but kept for now for mods. Json policy changed to fit new syntax.

-Unit category checking can now check for "non-air", "military", "military units" and uniques.
Added "military" to template.properties for translation.

-New unit unique "No defensive terrain penalty". Admittedly this is for a mod I'm making.

* translations must have spaces after!

* -Attacker Bonus unique changed to "+[]% Strength when attacking"
Changed Units.json and and Wolf Pack from UnitPromotions.json to this syntax

-Defender Bonus unique changed to "+[]% Strength when defending"
Armor Plating promotions were changed to this syntax
This commit is contained in:
givehub99 2020-10-14 00:22:49 -07:00 committed by GitHub
parent b5a32e64ae
commit 8c51833a5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 37 additions and 16 deletions

View File

@ -482,7 +482,7 @@
{ {
"name": "Total War", "name": "Total War",
"effect": "+15% production when building military units and new military units start with 15 Experience", "effect": "+15% production when building military units and new military units start with 15 Experience",
"uniques": ["+[15]% Production when constructing [military units]", "New military units start with [15] Experience"], "uniques": ["+[15]% Production when constructing [military units]", "New [military] units start with [15] Experience"],
"requires": ["Police State","Fascism"], "requires": ["Police State","Fascism"],
"row": 3, "row": 3,
"column": 4 "column": 4

View File

@ -208,38 +208,38 @@
// Submarine // Submarine
{ {
"name": "Wolfpack I", "name": "Wolfpack I",
"effect": "Bonus as Attacker [25]%", "effect": "+[25]% Strength when attacking",
"unitTypes": ["WaterSubmarine"] "unitTypes": ["WaterSubmarine"]
}, },
{ {
"name": "Wolfpack II", "name": "Wolfpack II",
"prerequisites": ["Wolfpack I"], "prerequisites": ["Wolfpack I"],
"effect": "Bonus as Attacker [25]%", "effect": "+[25]% Strength when attacking",
"unitTypes": ["WaterSubmarine"] "unitTypes": ["WaterSubmarine"]
}, },
{ {
"name": "Wolfpack III", "name": "Wolfpack III",
"prerequisites": ["Wolfpack II"], "prerequisites": ["Wolfpack II"],
"effect": "Bonus as Attacker [25]%", "effect": "+[25]% Strength when attacking",
"unitTypes": ["WaterSubmarine"] "unitTypes": ["WaterSubmarine"]
}, },
// Aircraft Carrier // Aircraft Carrier
{ {
"name": "Armor Plating I", "name": "Armor Plating I",
"effect": "+25% Combat Bonus when defending", "effect": "+[25]% Strength when defending",
"unitTypes": ["WaterAircraftCarrier"] "unitTypes": ["WaterAircraftCarrier"]
}, },
{ {
"name": "Armor Plating II", "name": "Armor Plating II",
"prerequisites": ["Armor Plating I"], "prerequisites": ["Armor Plating I"],
"effect": "+25% Combat Bonus when defending", "effect": "+[25]% Strength when defending",
"unitTypes": ["WaterAircraftCarrier"] "unitTypes": ["WaterAircraftCarrier"]
}, },
{ {
"name": "Armor Plating III", "name": "Armor Plating III",
"prerequisites": ["Armor Plating II"], "prerequisites": ["Armor Plating II"],
"effect": "+25% Combat Bonus when defending", "effect": "+[25]% Strength when defending",
"unitTypes": ["WaterAircraftCarrier"] "unitTypes": ["WaterAircraftCarrier"]
}, },
{ {

View File

@ -743,7 +743,7 @@
"requiredTech": "Gunpowder", "requiredTech": "Gunpowder",
"upgradesTo": "Rifleman", "upgradesTo": "Rifleman",
"obsoleteTech": "Rifling", "obsoleteTech": "Rifling",
"uniques": ["Heals [50] damage if it kills a unit", "Bonus as Attacker [25]%"], "uniques": ["Heals [50] damage if it kills a unit", "+[25]% Strength when attacking"],
"attackSound": "shot" "attackSound": "shot"
}, },
{ {
@ -1124,7 +1124,7 @@
"cost": 325, "cost": 325,
"requiredTech": "Refrigeration", "requiredTech": "Refrigeration",
// "upgradesTo": "Nuclear Submarine", // "upgradesTo": "Nuclear Submarine",
"uniques": ["Bonus as Attacker [75]%", "Invisible to others", "Can only attack water", "Can attack submarines", "Can enter ice tiles"] "uniques": ["+[75]% Strength when attacking", "Invisible to others", "Can only attack water", "Can attack submarines", "Can enter ice tiles"]
}, },
{ {
"name": "Great War Infantry", "name": "Great War Infantry",

View File

@ -600,6 +600,7 @@ Captured! =
defence vs ranged = defence vs ranged =
[percentage] to unit defence = [percentage] to unit defence =
Attacker Bonus = Attacker Bonus =
Defender Bonus =
Landing = Landing =
Flanking = Flanking =
vs [unitType] = vs [unitType] =
@ -627,6 +628,7 @@ Occupied City =
Buildings = Buildings =
# For the "when constructing [military units]" translation # For the "when constructing [military units]" translation
military =
military units = military units =
melee units = melee units =
mounted units = mounted units =

View File

@ -118,11 +118,16 @@ object BattleDamage {
if (attacker is MapUnitCombatant) { if (attacker is MapUnitCombatant) {
modifiers.add(getTileSpecificModifiers(attacker, defender.getTile())) modifiers.add(getTileSpecificModifiers(attacker, defender.getTile()))
// As of 3.11.3 This is to be deprecated and converted to "+[]% Strength when attacking" - keeping it here to that mods with this can still work for now
for (ability in attacker.unit.getUniques()) { for (ability in attacker.unit.getUniques()) {
if (ability.placeholderText == "Bonus as Attacker []%") if (ability.placeholderText == "Bonus as Attacker []%")
modifiers.add("Attacker Bonus", ability.params[0].toInt()) modifiers.add("Attacker Bonus", ability.params[0].toInt())
} }
for(unique in attacker.unit.getMatchingUniques("+[]% Strength when attacking")) {
modifiers.add("Attacker Bonus", unique.params[0].toInt())
}
if (attacker.unit.isEmbarked() && !attacker.unit.hasUnique("Amphibious")) if (attacker.unit.isEmbarked() && !attacker.unit.hasUnique("Amphibious"))
modifiers["Landing"] = -50 modifiers["Landing"] = -50
@ -175,7 +180,8 @@ object BattleDamage {
modifiers.putAll(getTileSpecificModifiers(defender, tile)) modifiers.putAll(getTileSpecificModifiers(defender, tile))
val tileDefenceBonus = tile.getDefensiveBonus() val tileDefenceBonus = tile.getDefensiveBonus()
if (!defender.unit.hasUnique("No defensive terrain bonus") || tileDefenceBonus < 0) if ( (!defender.unit.hasUnique("No defensive terrain bonus") && tileDefenceBonus > 0)
|| (!defender.unit.hasUnique("No defensive terrain penalty") && tileDefenceBonus < 0) )
modifiers["Tile"] = (tileDefenceBonus*100).toInt() modifiers["Tile"] = (tileDefenceBonus*100).toInt()
if (attacker.isRanged()) { if (attacker.isRanged()) {
@ -183,8 +189,13 @@ object BattleDamage {
if (defenceVsRanged > 0) modifiers["defence vs ranged"] = defenceVsRanged if (defenceVsRanged > 0) modifiers["defence vs ranged"] = defenceVsRanged
} }
// As of 3.11.2 This is to be deprecated and converted to "+[25]% Strength when defending" - keeping it here to that mods with this can still work for now
val carrierDefenceBonus = 25 * defender.unit.getUniques().count { it.text == "+25% Combat Bonus when defending" } val carrierDefenceBonus = 25 * defender.unit.getUniques().count { it.text == "+25% Combat Bonus when defending" }
if (carrierDefenceBonus > 0) modifiers["Armor Plating"] = carrierDefenceBonus if (carrierDefenceBonus > 0) modifiers["Defender Bonus"] = carrierDefenceBonus
for(unique in defender.unit.getMatchingUniques("+[]% Strength when defending")) {
modifiers.add("Defender Bonus", unique.params[0].toInt())
}
for(unique in defender.unit.getMatchingUniques("+[]% defence in [] tiles")) { for(unique in defender.unit.getMatchingUniques("+[]% defence in [] tiles")) {
if (tile.matchesUniqueFilter(unique.params[1])) if (tile.matchesUniqueFilter(unique.params[1]))

View File

@ -683,6 +683,9 @@ class MapUnit {
if ((category == "Land" || category == "land units") && type.isLandUnit()) return true if ((category == "Land" || category == "land units") && type.isLandUnit()) return true
if ((category == "Water" || category == "water units") && type.isWaterUnit()) return true if ((category == "Water" || category == "water units") && type.isWaterUnit()) return true
if ((category == "Air" || category == "air units") && type.isAirUnit()) return true if ((category == "Air" || category == "air units") && type.isAirUnit()) return true
if (category == "non-air" && !type.isAirUnit()) return true
if ((category == "military" || category == "military units") && type.isMilitary()) return true
if (hasUnique(category)) return true
return false return false
} }

View File

@ -168,18 +168,23 @@ class BaseUnit : INamed, IConstruction {
if (this.unitType.isCivilian()) return true // tiny optimization makes save files a few bytes smaller if (this.unitType.isCivilian()) return true // tiny optimization makes save files a few bytes smaller
var XP = construction.getBuiltBuildings().sumBy { it.xpForNewUnits } var XP = construction.getBuiltBuildings().sumBy { it.xpForNewUnits }
// As of 3.11.2 This is to be deprecated and converted to "New [] units start with [] Experience" - keeping it here to that mods with this can still work for now
for (unique in civInfo.getMatchingUniques("New military units start with [] Experience")) for (unique in civInfo.getMatchingUniques("New military units start with [] Experience"))
XP += unique.params[0].toInt() XP += unique.params[0].toInt()
for (unique in construction.cityInfo.cityConstructions.builtBuildingUniqueMap.getUniques("New [] units start with [] Experience in this city")
+ civInfo.getMatchingUniques("New [] units start with [] Experience")) {
if (unit.matchesCategory(unique.params[0]))
XP += unique.params[1].toInt()
}
unit.promotions.XP = XP unit.promotions.XP = XP
for (unique in construction.cityInfo.cityConstructions.builtBuildingUniqueMap.getUniques("All newly-trained [] units in this city receive the [] promotion")) { for (unique in construction.cityInfo.cityConstructions.builtBuildingUniqueMap.getUniques("All newly-trained [] units in this city receive the [] promotion")) {
val filter = unique.params[0] val filter = unique.params[0]
val promotion = unique.params[1] val promotion = unique.params[1]
if (unit.name == filter
|| (filter == "relevant" && civInfo.gameInfo.ruleSet.unitPromotions.values.any { unit.type.toString() in it.unitTypes && it.name == promotion }) if (unit.matchesCategory(filter) || (filter == "relevant" && civInfo.gameInfo.ruleSet.unitPromotions.values.any { unit.type.toString() in it.unitTypes && it.name == promotion }))
|| unit.type.name == filter
|| (filter == "non-air" && !unit.type.isAirUnit())
|| uniques.contains(filter))
unit.promotions.addPromotion(promotion, isFree = true) unit.promotions.addPromotion(promotion, isFree = true)
} }