mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 22:06:05 -04:00
Typed some uniques and fixed a policy not working (#5848)
* Typed some uniques, fixing a policy not working * Repurposed an unused function to remove .unit in some places * Fixed compilation errors
This commit is contained in:
parent
ea51c7155b
commit
ecadfb53fa
@ -106,7 +106,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Military Tradition",
|
"name": "Military Tradition",
|
||||||
"uniques":["[Military] units gain [50]% more Experience from combat"],
|
"uniques":["[+50]% XP gained from combat <for [Military] units>"],
|
||||||
"requires": ["Warrior Code"],
|
"requires": ["Warrior Code"],
|
||||||
"row": 2,
|
"row": 2,
|
||||||
"column": 2
|
"column": 2
|
||||||
|
@ -517,7 +517,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Quick Study", // only for Keshik and subsequent upgrades
|
"name": "Quick Study", // only for Keshik and subsequent upgrades
|
||||||
"uniques": ["[50]% Bonus XP gain"]
|
"uniques": ["[+50]% XP gained from combat"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Haka War Dance", // only for Maori Warrior and subsequent upgrades
|
"name": "Haka War Dance", // only for Maori Warrior and subsequent upgrades
|
||||||
|
@ -107,7 +107,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Military Tradition",
|
"name": "Military Tradition",
|
||||||
"uniques":["[Military] units gain [50]% more Experience from combat"],
|
"uniques":["[+50]% XP gained from combat <for [Military] units>"],
|
||||||
"requires": ["Warrior Code"],
|
"requires": ["Warrior Code"],
|
||||||
"row": 2,
|
"row": 2,
|
||||||
"column": 2
|
"column": 2
|
||||||
|
@ -517,7 +517,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Quick Study", // only for Keshik and subsequent upgrades
|
"name": "Quick Study", // only for Keshik and subsequent upgrades
|
||||||
"uniques": ["[50]% Bonus XP gain"]
|
"uniques": ["[+50]% XP gained from combat"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Haka War Dance", // only for Maori Warrior and subsequent upgrades
|
"name": "Haka War Dance", // only for Maori Warrior and subsequent upgrades
|
||||||
|
@ -10,6 +10,7 @@ import com.unciv.logic.map.RoadStatus
|
|||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.models.AttackableTile
|
import com.unciv.models.AttackableTile
|
||||||
import com.unciv.models.UnitActionType
|
import com.unciv.models.UnitActionType
|
||||||
|
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||||
import com.unciv.models.ruleset.unique.Unique
|
import com.unciv.models.ruleset.unique.Unique
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.models.stats.Stat
|
import com.unciv.models.stats.Stat
|
||||||
@ -39,7 +40,7 @@ object Battle {
|
|||||||
*/
|
*/
|
||||||
if (attacker.unit.currentMovement == 0f)
|
if (attacker.unit.currentMovement == 0f)
|
||||||
return
|
return
|
||||||
if (attacker.unit.hasUnique(UniqueType.MustSetUp) && !attacker.unit.isSetUpForSiege()) {
|
if (attacker.hasUnique(UniqueType.MustSetUp) && !attacker.unit.isSetUpForSiege()) {
|
||||||
attacker.unit.action = UnitActionType.SetUp.value
|
attacker.unit.action = UnitActionType.SetUp.value
|
||||||
attacker.unit.useMovementPoints(1f)
|
attacker.unit.useMovementPoints(1f)
|
||||||
}
|
}
|
||||||
@ -131,25 +132,22 @@ object Battle {
|
|||||||
private fun tryEarnFromKilling(civUnit: ICombatant, defeatedUnit: MapUnitCombatant) {
|
private fun tryEarnFromKilling(civUnit: ICombatant, defeatedUnit: MapUnitCombatant) {
|
||||||
val unitStr = max(defeatedUnit.unit.baseUnit.strength, defeatedUnit.unit.baseUnit.rangedStrength)
|
val unitStr = max(defeatedUnit.unit.baseUnit.strength, defeatedUnit.unit.baseUnit.rangedStrength)
|
||||||
val unitCost = defeatedUnit.unit.baseUnit.cost
|
val unitCost = defeatedUnit.unit.baseUnit.cost
|
||||||
var bonusUniquePlaceholderText = "Earn []% of killed [] unit's [] as []"
|
|
||||||
|
|
||||||
val bonusUniques = ArrayList<Unique>()
|
val bonusUniques = ArrayList<Unique>()
|
||||||
|
|
||||||
|
val stateForConditionals = StateForConditionals(civInfo = civUnit.getCivInfo(), ourCombatant = civUnit, theirCombatant = defeatedUnit)
|
||||||
if (civUnit is MapUnitCombatant) {
|
if (civUnit is MapUnitCombatant) {
|
||||||
bonusUniques.addAll(civUnit.getMatchingUniques(bonusUniquePlaceholderText))
|
bonusUniques.addAll(civUnit.getMatchingUniques(UniqueType.KillUnitPlunder, stateForConditionals, true))
|
||||||
bonusUniques.addAll(civUnit.getCivInfo().getMatchingUniques(bonusUniquePlaceholderText))
|
|
||||||
} else {
|
} else {
|
||||||
bonusUniques.addAll(civUnit.getCivInfo().getMatchingUniques(bonusUniquePlaceholderText))
|
bonusUniques.addAll(civUnit.getCivInfo().getMatchingUniques(UniqueType.KillUnitPlunder, stateForConditionals))
|
||||||
}
|
}
|
||||||
|
|
||||||
bonusUniquePlaceholderText = "Earn []% of [] unit's [] as [] when killed within 4 tiles of a city following this religion"
|
|
||||||
val cityWithReligion =
|
val cityWithReligion =
|
||||||
civUnit.getTile().getTilesInDistance(4).firstOrNull {
|
civUnit.getTile().getTilesInDistance(4).firstOrNull {
|
||||||
it.isCityCenter() && it.getCity()!!.getMatchingUniques(bonusUniquePlaceholderText).any()
|
it.isCityCenter() && it.getCity()!!.getLocalMatchingUniques(UniqueType.KillUnitPlunderNearCity, stateForConditionals).any()
|
||||||
}?.getCity()
|
}?.getCity()
|
||||||
if (cityWithReligion != null) {
|
if (cityWithReligion != null) {
|
||||||
bonusUniques.addAll(cityWithReligion.getLocalMatchingUniques(bonusUniquePlaceholderText))
|
bonusUniques.addAll(cityWithReligion.getLocalMatchingUniques(UniqueType.KillUnitPlunderNearCity, stateForConditionals))
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unique in bonusUniques) {
|
for (unique in bonusUniques) {
|
||||||
@ -405,29 +403,43 @@ object Battle {
|
|||||||
|
|
||||||
// XP!
|
// XP!
|
||||||
private fun addXp(thisCombatant: ICombatant, amount: Int, otherCombatant: ICombatant) {
|
private fun addXp(thisCombatant: ICombatant, amount: Int, otherCombatant: ICombatant) {
|
||||||
|
var baseXP = amount
|
||||||
if (thisCombatant !is MapUnitCombatant) return
|
if (thisCombatant !is MapUnitCombatant) return
|
||||||
if (thisCombatant.unit.promotions.totalXpProduced() >= thisCombatant.unit.civInfo.gameInfo.ruleSet.modOptions.maxXPfromBarbarians
|
if (thisCombatant.unit.promotions.totalXpProduced() >= thisCombatant.unit.civInfo.gameInfo.ruleSet.modOptions.maxXPfromBarbarians
|
||||||
&& otherCombatant.getCivInfo().isBarbarian())
|
&& otherCombatant.getCivInfo().isBarbarian()
|
||||||
|
) {
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val stateForConditionals = StateForConditionals(civInfo = thisCombatant.getCivInfo(), ourCombatant = thisCombatant, theirCombatant = otherCombatant)
|
||||||
|
|
||||||
|
for (unique in thisCombatant.getMatchingUniques(UniqueType.FlatXPGain, stateForConditionals, true))
|
||||||
|
baseXP += unique.params[0].toInt()
|
||||||
|
|
||||||
var xpModifier = 1f
|
var xpModifier = 1f
|
||||||
for (unique in thisCombatant.getCivInfo().getMatchingUniques("[] units gain []% more Experience from combat")) {
|
// Deprecated since 3.18.12
|
||||||
if (thisCombatant.unit.matchesFilter(unique.params[0]))
|
for (unique in thisCombatant.getCivInfo().getMatchingUniques(UniqueType.BonusXPGainForUnits, stateForConditionals)) {
|
||||||
xpModifier += unique.params[1].toFloat() / 100
|
if (thisCombatant.unit.matchesFilter(unique.params[0]))
|
||||||
}
|
xpModifier += unique.params[1].toFloat() / 100
|
||||||
for (unique in thisCombatant.unit.getMatchingUniques("[]% Bonus XP gain"))
|
}
|
||||||
|
for (unique in thisCombatant.getMatchingUniques(UniqueType.BonuxXPGain, stateForConditionals, true))
|
||||||
|
xpModifier += unique.params[0].toFloat() / 100
|
||||||
|
//
|
||||||
|
|
||||||
|
for (unique in thisCombatant.getMatchingUniques(UniqueType.PercentageXPGain, stateForConditionals, true))
|
||||||
xpModifier += unique.params[0].toFloat() / 100
|
xpModifier += unique.params[0].toFloat() / 100
|
||||||
|
|
||||||
val xpGained = (amount * xpModifier).toInt()
|
val xpGained = (baseXP * xpModifier).toInt()
|
||||||
thisCombatant.unit.promotions.XP += xpGained
|
thisCombatant.unit.promotions.XP += xpGained
|
||||||
|
|
||||||
|
|
||||||
if (thisCombatant.getCivInfo().isMajorCiv() && !otherCombatant.getCivInfo().isBarbarian()) { // Can't get great generals from Barbarians
|
if (thisCombatant.getCivInfo().isMajorCiv() && !otherCombatant.getCivInfo().isBarbarian()) { // Can't get great generals from Barbarians
|
||||||
var greatGeneralPointsModifier = 1f
|
var greatGeneralPointsModifier = 1f
|
||||||
for (unique in thisCombatant.getMatchingUniques("[] is earned []% faster")) {
|
for (unique in thisCombatant.getMatchingUniques(UniqueType.GreatPersonEarnedFaster, stateForConditionals, true)) {
|
||||||
val unitName = unique.params[0]
|
val unitName = unique.params[0]
|
||||||
val unit = thisCombatant.getCivInfo().gameInfo.ruleSet.units[unitName]
|
// From the unique we know this unit exists
|
||||||
if (unit != null && unit.uniques.contains("Great Person - [War]"))
|
val unit = thisCombatant.getCivInfo().gameInfo.ruleSet.units[unitName]!!
|
||||||
|
if (unit.uniques.contains("Great Person - [War]"))
|
||||||
greatGeneralPointsModifier += unique.params[1].toFloat() / 100
|
greatGeneralPointsModifier += unique.params[1].toFloat() / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,6 +451,7 @@ object Battle {
|
|||||||
private fun conquerCity(city: CityInfo, attacker: MapUnitCombatant) {
|
private fun conquerCity(city: CityInfo, attacker: MapUnitCombatant) {
|
||||||
val attackerCiv = attacker.getCivInfo()
|
val attackerCiv = attacker.getCivInfo()
|
||||||
|
|
||||||
|
|
||||||
attackerCiv.addNotification("We have conquered the city of [${city.name}]!", city.location, NotificationIcon.War)
|
attackerCiv.addNotification("We have conquered the city of [${city.name}]!", city.location, NotificationIcon.War)
|
||||||
|
|
||||||
city.hasJustBeenConquered = true
|
city.hasJustBeenConquered = true
|
||||||
@ -448,7 +461,8 @@ object Battle {
|
|||||||
for (airUnit in airUnits.toList()) airUnit.destroy()
|
for (airUnit in airUnits.toList()) airUnit.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unique in attacker.getMatchingUniques("Upon capturing a city, receive [] times its [] production as [] immediately")) {
|
val stateForConditionals = StateForConditionals(civInfo = attackerCiv, unit = attacker.unit, ourCombatant = attacker, attackedTile = city.getCenterTile())
|
||||||
|
for (unique in attacker.getMatchingUniques(UniqueType.CaptureCityPlunder, stateForConditionals, true)) {
|
||||||
attackerCiv.addStat(
|
attackerCiv.addStat(
|
||||||
Stat.valueOf(unique.params[2]),
|
Stat.valueOf(unique.params[2]),
|
||||||
unique.params[0].toInt() * city.cityStats.currentCityStats[Stat.valueOf(unique.params[1])].toInt()
|
unique.params[0].toInt() * city.cityStats.currentCityStats[Stat.valueOf(unique.params[1])].toInt()
|
||||||
@ -548,7 +562,8 @@ object Battle {
|
|||||||
|
|
||||||
fun mayUseNuke(nuke: MapUnitCombatant, targetTile: TileInfo): Boolean {
|
fun mayUseNuke(nuke: MapUnitCombatant, targetTile: TileInfo): Boolean {
|
||||||
val blastRadius =
|
val blastRadius =
|
||||||
if (!nuke.unit.hasUnique(UniqueType.BlastRadius)) 2
|
if (!nuke.hasUnique(UniqueType.BlastRadius)) 2
|
||||||
|
// Don't check conditionals as these are not supported
|
||||||
else nuke.unit.getMatchingUniques(UniqueType.BlastRadius).first().params[0].toInt()
|
else nuke.unit.getMatchingUniques(UniqueType.BlastRadius).first().params[0].toInt()
|
||||||
|
|
||||||
var canNuke = true
|
var canNuke = true
|
||||||
@ -582,7 +597,8 @@ object Battle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val blastRadius =
|
val blastRadius =
|
||||||
if (!attacker.unit.hasUnique(UniqueType.BlastRadius)) 2
|
if (!attacker.hasUnique(UniqueType.BlastRadius)) 2
|
||||||
|
// Don't check conditionals as there are not supported
|
||||||
else attacker.unit.getMatchingUniques(UniqueType.BlastRadius).first().params[0].toInt()
|
else attacker.unit.getMatchingUniques(UniqueType.BlastRadius).first().params[0].toInt()
|
||||||
|
|
||||||
val strength = when {
|
val strength = when {
|
||||||
|
@ -42,14 +42,13 @@ object BattleDamage {
|
|||||||
combatAction = combatAction, attackedTile = attackedTile
|
combatAction = combatAction, attackedTile = attackedTile
|
||||||
)
|
)
|
||||||
|
|
||||||
for (unique in combatant.unit.getMatchingUniques(
|
for (unique in combatant.getMatchingUniques(
|
||||||
UniqueType.Strength, conditionalState, true
|
UniqueType.Strength, conditionalState, true
|
||||||
)) {
|
)) {
|
||||||
modifiers.add(getModifierStringFromUnique(unique), unique.params[0].toInt())
|
modifiers.add(getModifierStringFromUnique(unique), unique.params[0].toInt())
|
||||||
}
|
}
|
||||||
for (unique in combatant.unit.getMatchingUniques(
|
for (unique in combatant.getMatchingUniques(
|
||||||
UniqueType.StrengthNearCapital,
|
UniqueType.StrengthNearCapital, conditionalState, true
|
||||||
checkCivInfoUniques = true
|
|
||||||
)) {
|
)) {
|
||||||
if (civInfo.cities.isEmpty()) break
|
if (civInfo.cities.isEmpty()) break
|
||||||
val distance =
|
val distance =
|
||||||
|
@ -4,7 +4,9 @@ import com.unciv.logic.civilization.CivilizationInfo
|
|||||||
import com.unciv.logic.map.MapUnit
|
import com.unciv.logic.map.MapUnit
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.models.UncivSound
|
import com.unciv.models.UncivSound
|
||||||
|
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||||
import com.unciv.models.ruleset.unique.Unique
|
import com.unciv.models.ruleset.unique.Unique
|
||||||
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.models.ruleset.unit.UnitType
|
import com.unciv.models.ruleset.unit.UnitType
|
||||||
|
|
||||||
class MapUnitCombatant(val unit: MapUnit) : ICombatant {
|
class MapUnitCombatant(val unit: MapUnit) : ICombatant {
|
||||||
@ -44,6 +46,10 @@ class MapUnitCombatant(val unit: MapUnit) : ICombatant {
|
|||||||
return unit.name+" of "+unit.civInfo.civName
|
return unit.name+" of "+unit.civInfo.civName
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMatchingUniques(uniqueTemplate: String): Sequence<Unique> = unit.getMatchingUniques(uniqueTemplate)
|
fun getMatchingUniques(uniqueType: UniqueType, conditionalState: StateForConditionals, checkCivUniques: Boolean): Sequence<Unique> =
|
||||||
|
unit.getMatchingUniques(uniqueType, conditionalState, checkCivUniques)
|
||||||
|
|
||||||
|
fun hasUnique(uniqueType: UniqueType, conditionalState: StateForConditionals? = null): Boolean =
|
||||||
|
if (conditionalState == null) unit.hasUnique(uniqueType)
|
||||||
|
else unit.hasUnique(uniqueType, conditionalState)
|
||||||
}
|
}
|
@ -425,8 +425,9 @@ class CityInfo {
|
|||||||
buildingsCounter.add(building.greatPersonPoints)
|
buildingsCounter.add(building.greatPersonPoints)
|
||||||
sourceToGPP["Buildings"] = buildingsCounter
|
sourceToGPP["Buildings"] = buildingsCounter
|
||||||
|
|
||||||
|
val stateForConditionals = StateForConditionals(civInfo = civInfo, cityInfo = this)
|
||||||
for ((_, gppCounter) in sourceToGPP) {
|
for ((_, gppCounter) in sourceToGPP) {
|
||||||
for (unique in civInfo.getMatchingUniques("[] is earned []% faster")) {
|
for (unique in civInfo.getMatchingUniques(UniqueType.GreatPersonEarnedFaster, stateForConditionals)) {
|
||||||
val unitName = unique.params[0]
|
val unitName = unique.params[0]
|
||||||
if (!gppCounter.containsKey(unitName)) continue
|
if (!gppCounter.containsKey(unitName)) continue
|
||||||
gppCounter.add(unitName, gppCounter[unitName]!! * unique.params[1].toInt() / 100)
|
gppCounter.add(unitName, gppCounter[unitName]!! * unique.params[1].toInt() / 100)
|
||||||
@ -440,9 +441,8 @@ class CityInfo {
|
|||||||
|
|
||||||
// Sweden UP
|
// Sweden UP
|
||||||
for (otherCiv in civInfo.getKnownCivs()) {
|
for (otherCiv in civInfo.getKnownCivs()) {
|
||||||
if (!civInfo.getDiplomacyManager(otherCiv)
|
if (!civInfo.getDiplomacyManager(otherCiv).hasFlag(DiplomacyFlags.DeclarationOfFriendship))
|
||||||
.hasFlag(DiplomacyFlags.DeclarationOfFriendship)
|
continue
|
||||||
) continue
|
|
||||||
|
|
||||||
for (ourUnique in civInfo.getMatchingUniques("When declaring friendship, both parties gain a []% boost to great person generation"))
|
for (ourUnique in civInfo.getMatchingUniques("When declaring friendship, both parties gain a []% boost to great person generation"))
|
||||||
allGppPercentageBonus += ourUnique.params[0].toInt()
|
allGppPercentageBonus += ourUnique.params[0].toInt()
|
||||||
|
@ -60,6 +60,15 @@ enum class UniqueParameterType(val parameterName:String) {
|
|||||||
return UniqueType.UniqueComplianceErrorSeverity.WarningOnly
|
return UniqueType.UniqueComplianceErrorSeverity.WarningOnly
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
GreatPerson("greatPerson") {
|
||||||
|
override fun getErrorSeverity(
|
||||||
|
parameterText: String,
|
||||||
|
ruleset: Ruleset
|
||||||
|
): UniqueType.UniqueComplianceErrorSeverity? {
|
||||||
|
return if (parameterText in ruleset.units && ruleset.units[parameterText]!!.hasUnique("Great Person - []")) null
|
||||||
|
else UniqueType.UniqueComplianceErrorSeverity.RulesetSpecific
|
||||||
|
}
|
||||||
|
},
|
||||||
Stats("stats") {
|
Stats("stats") {
|
||||||
override fun getErrorSeverity(parameterText: String, ruleset: Ruleset):
|
override fun getErrorSeverity(parameterText: String, ruleset: Ruleset):
|
||||||
UniqueType.UniqueComplianceErrorSeverity? {
|
UniqueType.UniqueComplianceErrorSeverity? {
|
||||||
@ -265,6 +274,16 @@ enum class UniqueParameterType(val parameterName:String) {
|
|||||||
else UniqueType.UniqueComplianceErrorSeverity.RulesetInvariant
|
else UniqueType.UniqueComplianceErrorSeverity.RulesetInvariant
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
CostOrStrength("costOrStrength") {
|
||||||
|
private val knownValues = setOf("Cost", "Strength")
|
||||||
|
override fun getErrorSeverity(
|
||||||
|
parameterText: String,
|
||||||
|
ruleset: Ruleset
|
||||||
|
): UniqueType.UniqueComplianceErrorSeverity? {
|
||||||
|
return if (parameterText in knownValues) null
|
||||||
|
else UniqueType.UniqueComplianceErrorSeverity.RulesetInvariant
|
||||||
|
}
|
||||||
|
},
|
||||||
/** Behaves like [Unknown], but states explicitly the parameter is OK and its contents are ignored */
|
/** Behaves like [Unknown], but states explicitly the parameter is OK and its contents are ignored */
|
||||||
Comment("comment") {
|
Comment("comment") {
|
||||||
override fun getErrorSeverity(parameterText: String, ruleset: Ruleset):
|
override fun getErrorSeverity(parameterText: String, ruleset: Ruleset):
|
||||||
|
@ -223,7 +223,7 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
|
|||||||
CanSeeInvisibleUnits("Can see invisible [mapUnitFilter] units", UniqueTarget.Unit),
|
CanSeeInvisibleUnits("Can see invisible [mapUnitFilter] units", UniqueTarget.Unit),
|
||||||
|
|
||||||
Strength("[amount]% Strength", UniqueTarget.Unit, UniqueTarget.Global),
|
Strength("[amount]% Strength", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
StrengthNearCapital("[amount]% Strength decreasing with distance from the capital", UniqueTarget.Unit),
|
StrengthNearCapital("[amount]% Strength decreasing with distance from the capital", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
|
|
||||||
|
|
||||||
Movement("[amount] Movement", UniqueTarget.Unit, UniqueTarget.Global),
|
Movement("[amount] Movement", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
@ -244,7 +244,15 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
|
|||||||
CarryExtraAirUnits("Can carry [amount] extra [mapUnitFilter] units", UniqueTarget.Unit),
|
CarryExtraAirUnits("Can carry [amount] extra [mapUnitFilter] units", UniqueTarget.Unit),
|
||||||
CannotBeCarriedBy("Cannot be carried by [mapUnitFilter] units", UniqueTarget.Unit),
|
CannotBeCarriedBy("Cannot be carried by [mapUnitFilter] units", UniqueTarget.Unit),
|
||||||
|
|
||||||
UnitMaintenanceDiscount("[amount]% maintenance costs", UniqueTarget.Unit),
|
UnitMaintenanceDiscount("[amount]% maintenance costs", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
|
GreatPersonEarnedFaster("[greatPerson] is earned [amount]% faster", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
|
|
||||||
|
CaptureCityPlunder("Upon capturing a city, receive [amount] times its [stat] production as [stat] immediately", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
|
KillUnitPlunder("Earn [amount]% of killed [mapUnitFilter] unit's [costOrStrength] as [stat]", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
|
KillUnitPlunderNearCity("Earn [amount]% of [mapUnitFilter] unit's [costOrStrength] as [stat] when killed within 4 tiles of a city following this religion", UniqueTarget.FollowerBelief),
|
||||||
|
|
||||||
|
FlatXPGain("[amount] XP gained from combat", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
|
PercentageXPGain("[amount]% XP gained from combat", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
|
|
||||||
// The following block gets cached in MapUnit for faster getMovementCostBetweenAdjacentTiles
|
// The following block gets cached in MapUnit for faster getMovementCostBetweenAdjacentTiles
|
||||||
DoubleMovementOnTerrain("Double movement in [terrainFilter]", UniqueTarget.Unit),
|
DoubleMovementOnTerrain("Double movement in [terrainFilter]", UniqueTarget.Unit),
|
||||||
@ -554,6 +562,10 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
|
|||||||
@Deprecated("As of 3.16.16 - removed 3.17.11", ReplaceWith("[stats] <if this city has at least [amount] specialists>"), DeprecationLevel.ERROR)
|
@Deprecated("As of 3.16.16 - removed 3.17.11", ReplaceWith("[stats] <if this city has at least [amount] specialists>"), DeprecationLevel.ERROR)
|
||||||
StatBonusForNumberOfSpecialists("[stats] if this city has at least [amount] specialists", UniqueTarget.Global),
|
StatBonusForNumberOfSpecialists("[stats] if this city has at least [amount] specialists", UniqueTarget.Global),
|
||||||
|
|
||||||
|
@Deprecated("As of 3.18.12", ReplaceWith("[amount]% XP gained from combat"))
|
||||||
|
BonuxXPGain("[amount]% Bonus XP gain", UniqueTarget.Unit),
|
||||||
|
@Deprecated("As of 3.18.12", ReplaceWith("[amount]% XP gained from combat <for [mapUnitFilter] units>"))
|
||||||
|
BonusXPGainForUnits("[mapUnitFilter] units gain [amount]% more Experience from combat", UniqueTarget.Global),
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
@ -220,6 +220,11 @@ Example: "[20]% Strength"
|
|||||||
|
|
||||||
Applicable to: Global, Unit
|
Applicable to: Global, Unit
|
||||||
|
|
||||||
|
#### [amount]% Strength decreasing with distance from the capital
|
||||||
|
Example: "[20]% Strength decreasing with distance from the capital"
|
||||||
|
|
||||||
|
Applicable to: Global, Unit
|
||||||
|
|
||||||
#### [amount] Movement
|
#### [amount] Movement
|
||||||
Example: "[20] Movement"
|
Example: "[20] Movement"
|
||||||
|
|
||||||
@ -238,6 +243,36 @@ Applicable to: Global, Unit
|
|||||||
#### Normal vision when embarked
|
#### Normal vision when embarked
|
||||||
Applicable to: Global, Unit
|
Applicable to: Global, Unit
|
||||||
|
|
||||||
|
#### [amount]% maintenance costs
|
||||||
|
Example: "[20]% maintenance costs"
|
||||||
|
|
||||||
|
Applicable to: Global, Unit
|
||||||
|
|
||||||
|
#### [greatPerson] is earned [amount]% faster
|
||||||
|
Example: "[greatPerson] is earned [20]% faster"
|
||||||
|
|
||||||
|
Applicable to: Global, Unit
|
||||||
|
|
||||||
|
#### Upon capturing a city, receive [amount] times its [stat] production as [stat] immediately
|
||||||
|
Example: "Upon capturing a city, receive [20] times its [Culture] production as [Culture] immediately"
|
||||||
|
|
||||||
|
Applicable to: Global, Unit
|
||||||
|
|
||||||
|
#### Earn [amount]% of killed [mapUnitFilter] unit's [costOrStrength] as [stat]
|
||||||
|
Example: "Earn [20]% of killed [Wounded] unit's [costOrStrength] as [Culture]"
|
||||||
|
|
||||||
|
Applicable to: Global, Unit
|
||||||
|
|
||||||
|
#### [amount] XP gained from combat
|
||||||
|
Example: "[20] XP gained from combat"
|
||||||
|
|
||||||
|
Applicable to: Global, Unit
|
||||||
|
|
||||||
|
#### [amount]% XP gained from combat
|
||||||
|
Example: "[20]% XP gained from combat"
|
||||||
|
|
||||||
|
Applicable to: Global, Unit
|
||||||
|
|
||||||
#### Free [baseUnitFilter] appears
|
#### Free [baseUnitFilter] appears
|
||||||
Example: "Free [Melee] appears"
|
Example: "Free [Melee] appears"
|
||||||
|
|
||||||
@ -337,6 +372,11 @@ Example: "[20]% [Culture] from every follower, up to [20]%"
|
|||||||
|
|
||||||
Applicable to: FollowerBelief
|
Applicable to: FollowerBelief
|
||||||
|
|
||||||
|
#### Earn [amount]% of [mapUnitFilter] unit's [costOrStrength] as [stat] when killed within 4 tiles of a city following this religion
|
||||||
|
Example: "Earn [20]% of [Wounded] unit's [costOrStrength] as [Culture] when killed within 4 tiles of a city following this religion"
|
||||||
|
|
||||||
|
Applicable to: FollowerBelief
|
||||||
|
|
||||||
## Building uniques
|
## Building uniques
|
||||||
#### Remove extra unhappiness from annexed cities
|
#### Remove extra unhappiness from annexed cities
|
||||||
Applicable to: Building
|
Applicable to: Building
|
||||||
@ -450,11 +490,6 @@ Example: "Can see invisible [Wounded] units"
|
|||||||
|
|
||||||
Applicable to: Unit
|
Applicable to: Unit
|
||||||
|
|
||||||
#### [amount]% Strength decreasing with distance from the capital
|
|
||||||
Example: "[20]% Strength decreasing with distance from the capital"
|
|
||||||
|
|
||||||
Applicable to: Unit
|
|
||||||
|
|
||||||
#### May found a religion
|
#### May found a religion
|
||||||
Applicable to: Unit
|
Applicable to: Unit
|
||||||
|
|
||||||
@ -490,11 +525,6 @@ Example: "Cannot be carried by [Wounded] units"
|
|||||||
|
|
||||||
Applicable to: Unit
|
Applicable to: Unit
|
||||||
|
|
||||||
#### [amount]% maintenance costs
|
|
||||||
Example: "[20]% maintenance costs"
|
|
||||||
|
|
||||||
Applicable to: Unit
|
|
||||||
|
|
||||||
#### Double movement in [terrainFilter]
|
#### Double movement in [terrainFilter]
|
||||||
Example: "Double movement in [Grassland]"
|
Example: "Double movement in [Grassland]"
|
||||||
|
|
||||||
@ -1051,6 +1081,7 @@ Applicable to: Conditional
|
|||||||
- "+[amount]% Production when constructing [constructionFilter] [cityFilter]" - Deprecated As of 3.17.10 - removed 3.18.5, replace with "[amount]% Production when constructing [buildingFilter] buildings [cityFilter]"
|
- "+[amount]% Production when constructing [constructionFilter] [cityFilter]" - Deprecated As of 3.17.10 - removed 3.18.5, replace with "[amount]% Production when constructing [buildingFilter] buildings [cityFilter]"
|
||||||
- "[stats] from every specialist" - Deprecated As of 3.16.16 - removed 3.17.11, replace with "[stats] from every specialist [in all cities]"
|
- "[stats] from every specialist" - Deprecated As of 3.16.16 - removed 3.17.11, replace with "[stats] from every specialist [in all cities]"
|
||||||
- "[stats] if this city has at least [amount] specialists" - Deprecated As of 3.16.16 - removed 3.17.11, replace with "[stats] <if this city has at least [amount] specialists>"
|
- "[stats] if this city has at least [amount] specialists" - Deprecated As of 3.16.16 - removed 3.17.11, replace with "[stats] <if this city has at least [amount] specialists>"
|
||||||
|
- "[mapUnitFilter] units gain [amount]% more Experience from combat" - Deprecated As of 3.18.12, replace with "[amount]% XP gained from combat <for [mapUnitFilter] units>"
|
||||||
- "Not displayed as an available construction unless [buildingName] is built" - Deprecated As of 3.16.11, replace with "Not displayed as an available construction without [buildingName]"
|
- "Not displayed as an available construction unless [buildingName] is built" - Deprecated As of 3.16.11, replace with "Not displayed as an available construction without [buildingName]"
|
||||||
- "[stats] once [tech] is discovered" - Deprecated As of 3.17.10, replace with "[stats] <after discovering [tech]>"
|
- "[stats] once [tech] is discovered" - Deprecated As of 3.17.10, replace with "[stats] <after discovering [tech]>"
|
||||||
- "Double movement in coast" - Deprecated As of 3.17.1 - removed 3.17.13, replace with "Double movement in [terrainFilter]"
|
- "Double movement in coast" - Deprecated As of 3.17.1 - removed 3.17.13, replace with "Double movement in [terrainFilter]"
|
||||||
@ -1068,5 +1099,6 @@ Applicable to: Conditional
|
|||||||
- "+[amount]% Strength in [tileFilter]" - Deprecated As of 3.17.5 - removed 3.18.5, replace with "[amount]% Strength <when fighting in [tileFilter] tiles>"
|
- "+[amount]% Strength in [tileFilter]" - Deprecated As of 3.17.5 - removed 3.18.5, replace with "[amount]% Strength <when fighting in [tileFilter] tiles>"
|
||||||
- "[amount] Visibility Range" - Deprecated As of 3.17.5 - removed 3.18.5, replace with "[amount] Sight"
|
- "[amount] Visibility Range" - Deprecated As of 3.17.5 - removed 3.18.5, replace with "[amount] Sight"
|
||||||
- "Limited Visibility" - Deprecated As of 3.17.5 - removed 3.18.5, replace with "[-1] Sight"
|
- "Limited Visibility" - Deprecated As of 3.17.5 - removed 3.18.5, replace with "[-1] Sight"
|
||||||
|
- "[amount]% Bonus XP gain" - Deprecated As of 3.18.12, replace with "[amount]% XP gained from combat"
|
||||||
- "[stats] on [tileFilter] tiles once [tech] is discovered" - Deprecated As of 3.17.10, replace with "[stats] from [tileFilter] tiles <after discovering [tech]>"
|
- "[stats] on [tileFilter] tiles once [tech] is discovered" - Deprecated As of 3.17.10, replace with "[stats] from [tileFilter] tiles <after discovering [tech]>"
|
||||||
- "Deal 30 damage to adjacent enemy units" - Deprecated As of 3.17.10, replace with "Adjacent enemy units ending their turn take [30] damage"
|
- "Deal 30 damage to adjacent enemy units" - Deprecated As of 3.17.10, replace with "Adjacent enemy units ending their turn take [30] damage"
|
Loading…
x
Reference in New Issue
Block a user