Updated and generalized more promotions (#4331)

* Generalized "[1] extra interceptions may be made per turn"

* Generalized and rephrased Cover promotion (requires #4311 to work)

* Generalized Logistics

* According to the civilopedia the defence value of cover has also risen, apparently

* Updated Ambush strength values

* Split up Targeting and Air Targeting (different strength bonus)

* Generalized Haka War Dance

* Added Supply promotion

* Renamed a unique so it matches other uniques

* Implemented May heal outside of friendly territory better

* Implemented requested changes
This commit is contained in:
Xander Lenstra
2021-07-02 13:02:20 +02:00
committed by GitHub
parent 0472309472
commit d94a1d1432
3 changed files with 93 additions and 63 deletions

View File

@ -229,6 +229,25 @@
"unitTypes": ["WaterMelee"]
},
// Water Ranged
{
"name": "Targeting I",
"effect": "+[15]% Strength vs [water units]",
"unitTypes": ["WaterRanged"]
},
{
"name": "Targeting II",
"prerequisites": ["Targeting I"],
"effect": "+[15]% Strength vs [water units]",
"unitTypes": ["WaterRanged"]
},
{
"name": "Targeting III",
"prerequisites": ["Targeting II"],
"effect": "+[15]% Strength vs [water units]",
"unitTypes": ["WaterRanged"]
},
// Submarine
{
"name": "Wolfpack I",
@ -283,6 +302,13 @@
"effect": "Can carry [1] extra [Air] units",
"unitTypes": ["WaterAircraftCarrier"]
},
// Mixed Water
{
"name" : "Supply",
"prerequisites": ["Bombardment III", "Targeting III", "Boarding Party III", "Coastal Raider III"],
"uniques": ["May heal outside of friendly territory", "[+15] HP when healing in [Foreign Land] tiles"],
},
// Bomber
{
@ -312,19 +338,19 @@
// Fighter
{
"name": "Interception I",
"effect": "Bonus when intercepting [33]%",
"effect": "[+33]% Damage when intercepting",
"unitTypes": ["Fighter"]
},
{
"name": "Interception II",
"prerequisites": ["Interception I"],
"effect": "Bonus when intercepting [33]%",
"effect": "[+33]% Damage when intercepting",
"unitTypes": ["Fighter"]
},
{
"name": "Interception III",
"prerequisites": ["Interception II"],
"effect": "Bonus when intercepting [34]%",
"effect": "[+34]% Damage when intercepting",
"unitTypes": ["Fighter"]
},
/*
@ -346,11 +372,24 @@
"unitTypes": ["Fighter"]
}
*/
{
"name": "Air Targeting I",
"prerequisites": ["Interception I","Dogfighting I", "Siege I","Bombardment I"],
"effect": "+[33]% Strength vs [water units]",
"unitTypes": ["Fighter","Bomber"]
},
{
"name": "Air Targeting II",
"prerequisites": ["Air Targeting I"],
"effect": "+[33]% Strength vs [water units]",
"unitTypes": ["Fighter","Bomber"]
},
{
"name": "Sortie",
"prerequisites": ["Interception II", "Dogfighting II"],
"effect": "1 extra Interception may be made per turn",
"effect": "[1] extra interceptions may be made per turn",
"unitTypes": ["Fighter"]
},
@ -370,13 +409,13 @@
// Mixed
{
"name": "Cover I",
"effect": "+25% Defence against ranged attacks",
"effect": "[+33]% Strength when defending vs [Ranged]",
"unitTypes": ["Melee","Ranged","Siege"]
},
{
"name": "Cover II",
"prerequisites": ["Cover I"],
"effect": "+25% Defence against ranged attacks",
"effect": "[+33]% Strength when defending vs [Ranged]",
"unitTypes": ["Melee","Ranged","Siege"]
},
@ -403,19 +442,19 @@
"name": "Logistics",
"prerequisites": ["Accuracy III","Barrage III","Targeting III", "Wolfpack III",
"Bombardment III", "Coastal Raider III","Boarding Party III","Siege III"],
"effect": "1 additional attack per turn",
"effect": "[1] additional attack per turn",
"unitTypes": ["Ranged","Siege","WaterMelee","WaterRanged","WaterSubmarine","Fighter","Bomber"]
},
{
"name": "Ambush I",
"effect": "+[25]% Strength vs [Armor]",
"effect": "+[33]% Strength vs [Armor]",
"unitTypes": ["Melee","Fighter","Bomber"]
},
{
"name": "Ambush II",
"prerequisites": ["Ambush I"],
"effect": "+[25]% Strength vs [Armor]",
"effect": "+[33]% Strength vs [Armor]",
"unitTypes": ["Melee","Fighter","Bomber"]
},
@ -439,31 +478,6 @@
"unitTypes": ["WaterRanged","Fighter","Bomber"]
},
// Targeting I has different requirements for air and waterranged units, this was the cleanest way to do so
{
"name": "Targeting I",
"effect": "+[15]% Strength vs [water units]",
"unitTypes": ["WaterRanged"]
},
{
"name": "Targeting I (air)",
"prerequisites": ["Interception I","Dogfighting I", "Siege I","Bombardment I"],
"effect": "+[15]% Strength vs [water units]",
"unitTypes": ["Fighter","Bomber"]
},
{
"name": "Targeting II",
"prerequisites": ["Targeting I","Targeting I (air)"],
"effect": "+[15]% Strength vs [water units]",
"unitTypes": ["WaterRanged","Fighter","Bomber"]
},
{
"name": "Targeting III",
"prerequisites": ["Targeting II"],
"effect": "+[15]% Strength vs [water units]",
"unitTypes": ["WaterRanged"]
},
// Uniques
{
"name": "Morale", // Heroic Epic
@ -483,7 +497,7 @@
},
{
"name": "Haka War Dance", // only for Maori Warrior and subsequent upgrades
"effect": "-10% combat strength for adjacent enemy units"
"effect": "[-10]% Strength for enemy [Military] units in adjacent [All] tiles"
},
{
"name": "Rejuvenation", // only for Units that have been close to Natural Wonder Fountain of Youth

View File

@ -51,17 +51,19 @@ object BattleDamage {
}
}
var adjacentUnitBonus = 0
val adjacentUnits = combatant.getTile().neighbors.flatMap { it.getUnits() }
for (unique in civInfo.getMatchingUniques("+[]% Strength for [] units which have another [] unit in an adjacent tile")) {
if (combatant.matchesCategory(unique.params[1])
&& combatant.getTile().neighbors.flatMap { it.getUnits() }
.any { it.civInfo == civInfo && it.matchesFilter(unique.params[2]) }
&& adjacentUnits.any { it.civInfo == civInfo && it.matchesFilter(unique.params[2]) }
) {
adjacentUnitBonus += unique.params[0].toInt()
modifiers.add("Adjacent units", unique.params[0].toInt())
}
}
if (adjacentUnitBonus != 0)
modifiers["Adjacent unit"] = adjacentUnitBonus
for (unique in adjacentUnits.flatMap { it.getMatchingUniques("[]% Strength for enemy [] units in adjacent [] tiles") })
if (combatant.matchesCategory(unique.params[1]) && combatant.getTile().matchesFilter(unique.params[2]))
modifiers.add("Adjacent enemy units", unique.params[0].toInt())
val civResources = civInfo.getCivResourcesByName()
for (resource in combatant.unit.baseUnit.getResourceRequirements().keys)
@ -191,11 +193,18 @@ object BattleDamage {
)
modifiers["Tile"] = (tileDefenceBonus * 100).toInt()
if (attacker.isRanged()) {
val defenceVsRanged = 25 * defender.unit.getUniques()
.count { it.text == "+25% Defence against ranged attacks" }
if (defenceVsRanged > 0) modifiers["defence vs ranged"] = defenceVsRanged
for (unique in defender.unit.getMatchingUniques("[]% Strength when defending vs []")) {
if (attacker.matchesCategory(unique.params[1]))
modifiers.add("defence vs [${unique.params[1]}] ", unique.params[0].toInt())
}
// Deprecated since 3.15.7
if (attacker.isRanged()) {
val defenceVsRanged = 25 * defender.unit.getUniques()
.count { it.text == "+25% Defence against ranged attacks" }
if (defenceVsRanged > 0) modifiers.add("defence vs ranged", defenceVsRanged)
}
//
for (unique in defender.unit.getMatchingUniques("+[]% Strength when defending")) {
modifiers.add("Defender Bonus", unique.params[0].toInt())
@ -203,7 +212,7 @@ object BattleDamage {
for (unique in defender.unit.getMatchingUniques("+[]% defence in [] tiles")) {
if (tile.matchesFilter(unique.params[1]))
modifiers["[${unique.params[1]}] defence"] = unique.params[0].toInt()
modifiers.add("[${unique.params[1]}] defence", unique.params[0].toInt())
}
if (defender.unit.isFortified())
@ -244,17 +253,16 @@ object BattleDamage {
)
modifiers[unique.params[2]] = unique.params[0].toInt()
}
if (tile.neighbors.flatMap { it.getUnits() }
.any {
it.hasUnique("-10% combat strength for adjacent enemy units") && it.civInfo.isAtWarWith(
unit.getCivInfo()
)
})
modifiers["Haka War Dance"] = -10
// Deprecated since 3.15.7
if (tile.neighbors.flatMap { it.getUnits() }
.any {
it.hasUnique("-10% combat strength for adjacent enemy units") && it.civInfo.isAtWarWith(
unit.getCivInfo()
)
})
modifiers["Haka War Dance"] = -10
//
return modifiers
}

View File

@ -518,7 +518,7 @@ class MapUnit {
if (civInfo.hasUnique("Can only heal by pillaging")) return
var amountToHealBy = rankTileForHealing(getTile())
if (amountToHealBy == 0) return
if (amountToHealBy == 0 && !(hasUnique("May heal outside of friendly territory") && !getTile().isFriendlyTerritory(civInfo))) return
// Deprecated since 3.15.6
if (hasUnique("+10 HP when healing")) amountToHealBy += 10
@ -551,15 +551,18 @@ class MapUnit {
isFriendlyTerritory -> 15 // Allied territory
else -> 5 // Enemy territory
}
val mayHeal = healing > 0 || (tileInfo.isWater && hasUnique("May heal outside of friendly territory"))
// Deprecated since 3.15.6
if (hasUnique("This unit and all others in adjacent tiles heal 5 additional HP. This unit heals 5 additional HP outside of friendly territory.")
&& !isFriendlyTerritory
&& healing > 0
&& mayHeal
)// Additional healing from medic is only applied when the unit is able to heal
healing += 5
//
if (healing > 0) {
if (mayHeal) {
for (unique in getMatchingUniques("[] HP when healing in [] tiles")) {
if (tileInfo.matchesFilter(unique.params[1])) {
healing += unique.params[0].toInt()
@ -833,9 +836,13 @@ class MapUnit {
}
fun canIntercept(attackedTile: TileInfo): Boolean {
if (attacksThisTurn > 1) return false
if (interceptChance() == 0) return false
if (attacksThisTurn > 0 && !hasUnique("1 extra Interception may be made per turn")) return false
val maxAttacksPerTurn = 1 +
getMatchingUniques("[] extra interceptions may be made per turn").sumBy { it.params[0].toInt() } +
// Deprecated since 3.15.7
getMatchingUniques("1 extra interception may be made per turn").count()
//
if (attacksThisTurn >= maxAttacksPerTurn) return false
if (currentTile.aerialDistanceTo(attackedTile) > baseUnit.interceptRange) return false
return true
}
@ -868,7 +875,8 @@ class MapUnit {
}
fun interceptDamagePercentBonus(): Int {
return getUniques().filter { it.placeholderText == "Bonus when intercepting []%" }
// "Bonus when intercepting []%" deprecated since 3.15.7
return getUniques().filter { it.placeholderText == "Bonus when intercepting []%" || it.placeholderText == "[]% Damage when intercepting"}
.sumBy { it.params[0].toInt() }
}