mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 15:27:50 +07:00
Typed all healing uniques (#6087)
* Typed all healing uniques * Fixed tests by replacing placeholder texts by types in BeliefAutomation
This commit is contained in:
@ -150,7 +150,7 @@
|
||||
{
|
||||
"name": "Medic II",
|
||||
"prerequisites": ["Medic"],
|
||||
"uniques": ["[+5] HP when healing in [Foreign Land] tiles", "All adjacent units heal [+5] HP when healing"],
|
||||
"uniques": ["[+5] HP when healing <in [Foreign Land] tiles>", "All adjacent units heal [+5] HP when healing"],
|
||||
"unitTypes": ["Sword","Gunpowder","Mounted","Scout"]
|
||||
},
|
||||
|
||||
@ -174,13 +174,13 @@
|
||||
},
|
||||
{
|
||||
"name": "Survivalism I",
|
||||
"uniques": ["[+5] HP when healing in [Foreign Land] tiles", "[+25]% Strength <when defending>"],
|
||||
"uniques": ["[+5] HP when healing <in [Foreign Land] tiles>", "[+25]% Strength <when defending>"],
|
||||
"unitTypes": ["Scout"]
|
||||
},
|
||||
{
|
||||
"name": "Survivalism II",
|
||||
"prerequisites": ["Survivalism I"],
|
||||
"uniques": ["[+5] HP when healing in [Foreign Land] tiles", "[+25]% Strength <when defending>"],
|
||||
"uniques": ["[+5] HP when healing <in [Foreign Land] tiles>", "[+25]% Strength <when defending>"],
|
||||
"unitTypes": ["Scout"]
|
||||
},
|
||||
{
|
||||
@ -306,7 +306,7 @@
|
||||
{
|
||||
"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"],
|
||||
"uniques": ["May heal outside of friendly territory", "[+15] HP when healing <in [Foreign Land] tiles>"],
|
||||
"unitTypes": ["Melee Water", "Ranged Water"]
|
||||
},
|
||||
|
||||
|
@ -150,7 +150,7 @@
|
||||
{
|
||||
"name": "Medic II",
|
||||
"prerequisites": ["Medic"],
|
||||
"uniques": ["[+5] HP when healing in [Foreign Land] tiles", "All adjacent units heal [+5] HP when healing"],
|
||||
"uniques": ["[+5] HP when healing <in [Foreign Land] tiles>", "All adjacent units heal [+5] HP when healing"],
|
||||
"unitTypes": ["Sword","Gunpowder","Mounted","Scout"]
|
||||
},
|
||||
|
||||
@ -174,13 +174,13 @@
|
||||
},
|
||||
{
|
||||
"name": "Survivalism I",
|
||||
"uniques": ["[+5] HP when healing in [Foreign Land] tiles", "[+25]% Strength <when defending>"],
|
||||
"uniques": ["[+5] HP when healing <in [Foreign Land] tiles>", "[+25]% Strength <when defending>"],
|
||||
"unitTypes": ["Scout"]
|
||||
},
|
||||
{
|
||||
"name": "Survivalism II",
|
||||
"prerequisites": ["Survivalism I"],
|
||||
"uniques": ["[+5] HP when healing in [Foreign Land] tiles", "[+25]% Strength <when defending>"],
|
||||
"uniques": ["[+5] HP when healing <in [Foreign Land] tiles>", "[+25]% Strength <when defending>"],
|
||||
"unitTypes": ["Scout"]
|
||||
},
|
||||
{
|
||||
@ -306,7 +306,7 @@
|
||||
{
|
||||
"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"],
|
||||
"uniques": ["May heal outside of friendly territory", "[+15] HP when healing <in [Foreign Land] tiles>"],
|
||||
"unitTypes": ["Melee Water", "Ranged Water"]
|
||||
},
|
||||
|
||||
|
@ -9,6 +9,7 @@ import com.unciv.models.ruleset.VictoryType
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stat
|
||||
import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
import kotlin.random.Random
|
||||
|
||||
object ChooseBeliefsAutomation {
|
||||
@ -60,29 +61,23 @@ object ChooseBeliefsAutomation {
|
||||
var score = 0f
|
||||
val ruleSet = civInfo.gameInfo.ruleSet
|
||||
for (unique in belief.uniqueObjects) {
|
||||
var modifier = 1f
|
||||
if (unique.conditionals.any { it.isOfType(UniqueType.ConditionalWar)
|
||||
|| it.isOfType(UniqueType.ConditionalNotWar)
|
||||
|| it.isOfType(UniqueType.ConditionalAttacking)
|
||||
|| it.isOfType(UniqueType.ConditionalDefending) }
|
||||
) {
|
||||
modifier *= 0.5f
|
||||
}
|
||||
val modifier = 0.5f.pow(unique.conditionals.count())
|
||||
// Multiply by 3/10 if has an obsoleted era
|
||||
// Multiply by 2 if enough pop/followers (best implemented with conditionals, so left open for now)
|
||||
// If obsoleted, continue
|
||||
score += modifier * when (unique.placeholderText) {
|
||||
UniqueType.GrowthPercentBonus.placeholderText -> unique.params[0].toFloat() / 3f
|
||||
UniqueType.BorderGrowthPercentage.placeholderText -> -unique.params[0].toFloat() * 2f / 10f
|
||||
"[]% Strength for cities" -> unique.params[0].toFloat() / 10f // Modified by personality
|
||||
"[] Units adjacent to this city heal [] HP per turn when healing" -> unique.params[1].toFloat() / 10f
|
||||
"+[]% Production when constructing []" -> unique.params[0].toFloat() / 3f
|
||||
UniqueType.StatsFromCitiesOnSpecificTiles.placeholderText ->
|
||||
score += modifier * when (unique.type) {
|
||||
UniqueType.GrowthPercentBonus -> unique.params[0].toFloat() / 3f
|
||||
UniqueType.BorderGrowthPercentage -> -unique.params[0].toFloat() * 2f / 10f
|
||||
UniqueType.StrengthForCities -> unique.params[0].toFloat() / 10f // Modified by personality
|
||||
UniqueType.CityHealingUnits -> unique.params[1].toFloat() / 10f
|
||||
UniqueType.PercentProductionBuildings -> unique.params[0].toFloat() / 3f
|
||||
UniqueType.PercentProductionWonders -> unique.params[0].toFloat() / 3f
|
||||
UniqueType.PercentProductionUnits -> unique.params[0].toFloat() / 3f
|
||||
UniqueType.StatsFromCitiesOnSpecificTiles ->
|
||||
if (city.getCenterTile().matchesFilter(unique.params[1]))
|
||||
unique.stats.values.sum() // Modified by personality
|
||||
else 0f
|
||||
UniqueType.StatsFromObject.placeholderText,
|
||||
"[] from every [] in cities where this religion has at least [] followers" ->
|
||||
UniqueType.StatsFromObject ->
|
||||
when {
|
||||
ruleSet.buildings.containsKey(unique.params[1]) -> {
|
||||
unique.stats.values.sum() /
|
||||
@ -97,15 +92,15 @@ object ChooseBeliefsAutomation {
|
||||
}
|
||||
else -> 0f
|
||||
}
|
||||
UniqueType.StatsFromXPopulation.placeholderText ->
|
||||
UniqueType.StatsFromXPopulation ->
|
||||
unique.stats.values.sum() // Modified by personality
|
||||
"[] from each Trade Route" ->
|
||||
UniqueType.StatsFromTradeRoute ->
|
||||
unique.stats.values.sum() *
|
||||
if (city.isConnectedToCapital()) 2f
|
||||
else 1f
|
||||
"[]% [] from every follower, up to []%" ->
|
||||
UniqueType.StatPercentFromReligionFollowers ->
|
||||
min(unique.params[0].toFloat() * city.population.population, unique.params[2].toFloat())
|
||||
UniqueType.StatsPerCity.placeholderText ->
|
||||
UniqueType.StatsPerCity ->
|
||||
if (city.matchesFilter(unique.params[1]))
|
||||
unique.stats.values.sum()
|
||||
else 0f
|
||||
|
@ -560,7 +560,7 @@ class MapUnit {
|
||||
}
|
||||
|
||||
private fun adjacentHealingBonus(): Int {
|
||||
return getMatchingUniques("All adjacent units heal [] HP when healing").sumOf { it.params[0].toInt() }
|
||||
return getMatchingUniques(UniqueType.HealAdjacentUnits).sumOf { it.params[0].toInt() } + 15 * getMatchingUniques(UniqueType.HealAdjacentUnitsDeprecated).count()
|
||||
}
|
||||
|
||||
// Only military land units can truly "garrison"
|
||||
@ -688,30 +688,19 @@ class MapUnit {
|
||||
|
||||
private fun heal() {
|
||||
if (isEmbarked()) return // embarked units can't heal
|
||||
if (civInfo.hasUnique("Can only heal by pillaging")) return
|
||||
if (health >= 100) return // No need to heal if at max health
|
||||
if (hasUnique(UniqueType.HealOnlyByPillaging, checkCivInfoUniques = true)) return
|
||||
|
||||
var amountToHealBy = rankTileForHealing(getTile())
|
||||
if (amountToHealBy == 0
|
||||
&& !(hasUnique(UniqueType.HealsOutsideFriendlyTerritory, checkCivInfoUniques = true)
|
||||
&& !getTile().isFriendlyTerritory(civInfo)
|
||||
)
|
||||
) return
|
||||
|
||||
amountToHealBy += getMatchingUniques("[] HP when healing").sumOf { it.params[0].toInt() }
|
||||
|
||||
val maxAdjacentHealingBonus = currentTile.neighbors
|
||||
.flatMap { it.getUnits().asSequence() }.map { it.adjacentHealingBonus() }.maxOrNull()
|
||||
if (maxAdjacentHealingBonus != null)
|
||||
amountToHealBy += maxAdjacentHealingBonus
|
||||
val amountToHealBy = rankTileForHealing(getTile())
|
||||
if (amountToHealBy == 0) return
|
||||
|
||||
healBy(amountToHealBy)
|
||||
}
|
||||
|
||||
fun healBy(amount: Int) {
|
||||
health += if (hasUnique(UniqueType.HealingEffectsDoubled, checkCivInfoUniques = true))
|
||||
amount * 2
|
||||
else
|
||||
amount
|
||||
health += amount *
|
||||
if (hasUnique(UniqueType.HealingEffectsDoubled, checkCivInfoUniques = true)) 2
|
||||
else 1
|
||||
if (health > 100) health = 100
|
||||
}
|
||||
|
||||
@ -723,20 +712,22 @@ class MapUnit {
|
||||
tileInfo.isCityCenter() -> 20
|
||||
tileInfo.isWater && isFriendlyTerritory && (baseUnit.isWaterUnit() || isTransported) -> 15 // Water unit on friendly water
|
||||
tileInfo.isWater -> 0 // All other water cases
|
||||
tileInfo.getOwner() == null -> 10 // Neutral territory
|
||||
isFriendlyTerritory -> 15 // Allied territory
|
||||
tileInfo.getOwner() == null -> 10 // Neutral territory
|
||||
else -> 5 // Enemy territory
|
||||
}
|
||||
|
||||
val mayHeal = healing > 0 || (tileInfo.isWater && hasUnique(UniqueType.HealsOutsideFriendlyTerritory))
|
||||
val mayHeal = healing > 0 || (tileInfo.isWater && hasUnique(UniqueType.HealsOutsideFriendlyTerritory, checkCivInfoUniques = true))
|
||||
if (!mayHeal) return healing
|
||||
|
||||
|
||||
for (unique in getMatchingUniques("[] HP when healing in [] tiles")) {
|
||||
healing += getMatchingUniques(UniqueType.Heal, checkCivInfoUniques = true).sumOf { it.params[0].toInt() }
|
||||
// Deprecated as of 3.19.4
|
||||
for (unique in getMatchingUniques(UniqueType.HealInTiles, checkCivInfoUniques = true)) {
|
||||
if (tileInfo.matchesFilter(unique.params[1], civInfo)) {
|
||||
healing += unique.params[0].toInt()
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
val healingCity = tileInfo.getTilesInDistance(1).firstOrNull {
|
||||
it.isCityCenter() && it.getCity()!!.getMatchingUniques(UniqueType.CityHealingUnits).any()
|
||||
@ -748,12 +739,17 @@ class MapUnit {
|
||||
}
|
||||
}
|
||||
|
||||
val maxAdjacentHealingBonus = currentTile.neighbors
|
||||
.flatMap { it.getUnits().asSequence() }.map { it.adjacentHealingBonus() }.maxOrNull()
|
||||
if (maxAdjacentHealingBonus != null)
|
||||
healing += maxAdjacentHealingBonus
|
||||
|
||||
return healing
|
||||
}
|
||||
|
||||
fun endTurn() {
|
||||
if (currentMovement > 0 &&
|
||||
getTile().improvementInProgress != null
|
||||
if (currentMovement > 0
|
||||
&& getTile().improvementInProgress != null
|
||||
&& canBuildImprovement(getTile().getTileImprovementInProgress()!!)
|
||||
) workOnImprovement()
|
||||
if (currentMovement == getMaxMovement().toFloat() && isFortified()) {
|
||||
@ -765,8 +761,6 @@ class MapUnit {
|
||||
true
|
||||
)
|
||||
}
|
||||
if (hasUnique("Heal adjacent units for an additional 15 HP per turn"))
|
||||
currentTile.neighbors.flatMap { it.getUnits() }.forEach { it.healBy(15) }
|
||||
|
||||
if (currentMovement == getMaxMovement().toFloat() // didn't move this turn
|
||||
|| hasUnique(UniqueType.HealsEvenAfterAction)
|
||||
|
@ -133,8 +133,8 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
|
||||
UniqueType.ConditionalNeighborTilesAnd ->
|
||||
state.cityInfo != null
|
||||
&& state.cityInfo.getCenterTile().neighbors.count {
|
||||
it.matchesFilter(condition.params[2], state.civInfo) &&
|
||||
it.matchesFilter(condition.params[3], state.civInfo)
|
||||
it.matchesFilter(condition.params[2], state.civInfo)
|
||||
&& it.matchesFilter(condition.params[3], state.civInfo)
|
||||
} in (condition.params[0].toInt())..(condition.params[1].toInt())
|
||||
|
||||
UniqueType.ConditionalOnWaterMaps -> state.region?.continentID == -1
|
||||
|
@ -356,7 +356,10 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
Movement("[amount] Movement", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
Sight("[amount] Sight", UniqueTarget.Unit, UniqueTarget.Global, UniqueTarget.Terrain),
|
||||
Range("[amount] Range", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
Heal("[amount] HP when healing", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
SpreadReligionStrength("[amount]% Spread Religion Strength", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
@Deprecated("As of 3.19.4", ReplaceWith("[amount] HP when healing <in [tileFilter] tiles>"))
|
||||
HealInTiles("[amount] HP when healing in [tileFilter] tiles", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
|
||||
MayFoundReligion("May found a religion", UniqueTarget.Unit),
|
||||
MayEnhanceReligion("May enhance a religion", UniqueTarget.Unit),
|
||||
@ -379,11 +382,14 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
CanMoveAfterAttacking("Can move after attacking", UniqueTarget.Unit),
|
||||
MoveImmediatelyOnceBought("Can move immediately once bought", UniqueTarget.Unit),
|
||||
|
||||
|
||||
HealsOutsideFriendlyTerritory("May heal outside of friendly territory", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
HealingEffectsDoubled("All healing effects doubled", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
HealsAfterKilling("Heals [amount] damage if it kills a unit", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
HealOnlyByPillaging("Can only heal by pillaging", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
HealsEvenAfterAction("Unit will heal every turn, even if it performs an action", UniqueTarget.Unit),
|
||||
HealAdjacentUnits("All adjacent units heal [amount] HP when healing", UniqueTarget.Unit),
|
||||
@Deprecated("As of 3.19.3", ReplaceWith("All adjacent units heal [+15] HP when healing"))
|
||||
HealAdjacentUnitsDeprecated("Heal adjacent units for an additional 15 HP per turn", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
|
||||
NormalVisionWhenEmbarked("Normal vision when embarked", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
DefenceBonusWhenEmbarked("Defense bonus when embarked", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
|
@ -481,6 +481,11 @@ Example: "[20] Range"
|
||||
|
||||
Applicable to: Global, Unit
|
||||
|
||||
#### [amount] HP when healing
|
||||
Example: "[20] HP when healing"
|
||||
|
||||
Applicable to: Global, Unit
|
||||
|
||||
#### [amount]% Spread Religion Strength
|
||||
Example: "[20]% Spread Religion Strength"
|
||||
|
||||
@ -506,6 +511,9 @@ Example: "Heals [20] damage if it kills a unit"
|
||||
|
||||
Applicable to: Global, Unit
|
||||
|
||||
#### Can only heal by pillaging
|
||||
Applicable to: Global, Unit
|
||||
|
||||
#### Normal vision when embarked
|
||||
Applicable to: Global, Unit
|
||||
|
||||
@ -839,6 +847,11 @@ Applicable to: Unit
|
||||
#### Unit will heal every turn, even if it performs an action
|
||||
Applicable to: Unit
|
||||
|
||||
#### All adjacent units heal [amount] HP when healing
|
||||
Example: "All adjacent units heal [20] HP when healing"
|
||||
|
||||
Applicable to: Unit
|
||||
|
||||
#### 6 tiles in every direction always visible
|
||||
Applicable to: Unit
|
||||
|
||||
@ -1450,6 +1463,7 @@ Applicable to: Conditional
|
||||
- "+[amount]% attacking strength for cities with garrisoned units" - Deprecated As of 3.19.1, replace with "[+amount]% Strength for cities <with a garrison> <when attacking>"
|
||||
- "Population loss from nuclear attacks -[amount]%" - Deprecated As of 3.19.2, replace with "Population loss from nuclear attacks [-amount]% [in this city]"
|
||||
- "[amount]% Natural religion spread [cityFilter] with [tech/policy]" - Deprecated As of 3.19.3, replace with "[amount]% Natural religion spread [cityFilter] <after discovering [tech]> OR [amount]% natural religion spread [cityFilter] <after adopting [policy]>"
|
||||
- "[amount] HP when healing in [tileFilter] tiles" - Deprecated As of 3.19.4, replace with "[amount] HP when healing <in [tileFilter] tiles>"
|
||||
- "Melee units pay no movement cost to pillage" - Deprecated As of 3.18.17, replace with "No movement cost to pillage <for [Melee] units>"
|
||||
- "[mapUnitFilter] units gain [amount]% more Experience from combat" - Deprecated As of 3.18.12, replace with "[amount]% XP gained from combat <for [mapUnitFilter] units>"
|
||||
- "[amount]% maintenance costs for [mapUnitFilter] units" - Deprecated As of 3.18.14, replace with "[amount]% maintenance costs <for [mapUnitFilter] units>"
|
||||
|
Reference in New Issue
Block a user