Generalized a few nation uniques (#6443)

* Generalized a few nation uniques

* Fixed a bug and made random less random

* Implemented requested changes
This commit is contained in:
Xander Lenstra
2022-03-28 16:33:31 +02:00
committed by GitHub
parent 7526114281
commit 8820ae6dad
11 changed files with 138 additions and 90 deletions

View File

@ -301,7 +301,7 @@
"innerColor": [185,0,0],
"favoredReligion": "Shinto",
"uniqueName": "Bushido",
"uniques": ["Units fight as though they were at full strength even when damaged"],
"uniques": ["Damage is ignored when determining unit Strength <for [non-air] units>"],
"cities": ["Kyoto","Osaka","Tokyo","Satsuma","Kagoshima","Nara","Nagoya","Izumo","Nagasaki","Yokohama",
"Shimonoseki","Matsuyama","Sapporo","Hakodate","Ise","Toyama","Fukushima","Suo","Bizen","Echizen",
"Izumi","Omi","Echigo","Kozuke","Sado","Kobe","Nagano","Hiroshima","Takayama","Akita","Fukuoka","Aomori",
@ -351,7 +351,7 @@
"innerColor": [60,60,60],
"favoredReligion": "Christianity",
"uniqueName": "Furor Teutonicus",
"uniques": ["67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment",
"uniques": ["When conquering an encampment, earn [25] Gold and recruit a Barbarian unit <with [67]% chance>",
"[-25]% maintenance costs <for [Land] units>"],
"cities": ["Berlin","Hamburg","Munich","Cologne","Frankfurt","Essen","Dortmund","Stuttgart","Düsseldorf","Bremen",
"Hannover","Duisburg","Leipzig","Dresden","Bonn","Bochum","Bielefeld","Karlsruhe","Gelsenkirchen","Wiesbaden",
@ -382,7 +382,7 @@
"favoredReligion": "Islam",
"uniqueName": "Barbary Corsairs",
"uniques": ["[-66]% maintenance costs <for [Water] units>",
"50% chance of capturing defeated Barbarian naval units and earning 25 Gold"],
"When defeating a [{Barbarian} {Water}] unit, earn [25] Gold and recruit it <with [50]% chance>"],
"cities": ["Istanbul","Edirne","Ankara","Bursa","Konya","Samsun","Gaziantep","Diyarbakır","Izmir","Kayseri","Malatya",
"Mersin","Antalya","Zonguldak","Denizli","Ordu","Muğla","Eskişehir","Inebolu","Sinop","Adana","Artvin",
"Bodrum","Eregli","Silifke","Sivas","Amasya","Marmaris","Trabzon","Erzurum","Urfa","Izmit","Afyonkarahisar",
@ -489,7 +489,7 @@
"innerColor": [255,255,78],
"favoredReligion": "Christianity",
"uniqueName": "Wayfinding",
"uniques": ["Enables embarkation for land units <starting from the [Ancient era]>", "Enables [All] units to enter ocean tiles <starting from the [Ancient era]>", "Normal vision when embarked <for [All] units>", "+[10]% Strength if within [2] tiles of a [Moai]"],
"uniques": ["Enables embarkation for land units <starting from the [Ancient era]>", "Enables [All] units to enter ocean tiles <starting from the [Ancient era]>", "Normal vision when embarked <for [All] units>", "[+10]% Strength <within [2] tiles of a [Moai]>"],
"cities": ["Honolulu","Samoa","Tonga","Nuku Hiva","Raiatea","Aotearoa","Tahiti","Hilo","Te Wai Pounamu","Rapa Nui",
"Tuamotu","Rarotonga","Tuvalu","Tubuai","Mangareva","Oahu","Kiritimati","Ontong Java","Niue","Rekohu",
"Rakahanga","Bora Bora","Kailua","Uvea","Futuna","Rotuma","Tokelau","Lahaina","Bellona","Mungava","Tikopia",

View File

@ -290,7 +290,7 @@
"outerColor": [215,225,225],
"innerColor": [185,0,0],
"uniqueName": "Bushido",
"uniques": ["Units fight as though they were at full strength even when damaged"],
"uniques": ["Damage is ignored when determining unit Strength <for [non-air] units>"],
"cities": ["Kyoto","Osaka","Tokyo","Satsuma","Kagoshima","Nara","Nagoya","Izumo","Nagasaki","Yokohama",
"Shimonoseki","Matsuyama","Sapporo","Hakodate","Ise","Toyama","Fukushima","Suo","Bizen","Echizen",
"Izumi","Omi","Echigo","Kozuke","Sado","Kobe","Nagano","Hiroshima","Takayama","Akita","Fukuoka","Aomori",
@ -336,7 +336,7 @@
"outerColor": [150,150,150],
"innerColor": [60,60,60],
"uniqueName": "Furor Teutonicus",
"uniques": ["67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment",
"uniques": ["When conquering an encampment, earn [25] Gold and recruit a Barbarian unit <with [67]% chance>",
"[-25]% maintenance costs <for [Land] units>"],
"cities": ["Berlin","Hamburg","Munich","Cologne","Frankfurt","Essen","Dortmund","Stuttgart","Düsseldorf","Bremen",
"Hannover","Duisburg","Leipzig","Dresden","Bonn","Bochum","Bielefeld","Karlsruhe","Gelsenkirchen","Wiesbaden",
@ -366,7 +366,7 @@
"innerColor": [18,84,30],
"uniqueName": "Barbary Corsairs",
"uniques": ["[-66]% maintenance costs <for [Water] units>",
"50% chance of capturing defeated Barbarian naval units and earning 25 Gold"],
"When defeating a [{Barbarian} {Water}] unit, earn [25] Gold and recruit it <with [50]% chance>"],
"cities": ["Istanbul","Edirne","Ankara","Bursa","Konya","Samsun","Gaziantep","Diyarbakır","Izmir","Kayseri","Malatya",
"Mersin","Antalya","Zonguldak","Denizli","Ordu","Muğla","Eskişehir","Inebolu","Sinop","Adana","Artvin",
"Bodrum","Eregli","Silifke","Sivas","Amasya","Marmaris","Trabzon","Erzurum","Urfa","Izmit","Afyonkarahisar",
@ -469,7 +469,7 @@
"outerColor": [225,105,0],
"innerColor": [255,255,78],
"uniqueName": "Wayfinding",
"uniques": ["Enables embarkation for land units <starting from the [Ancient era]>", "Enables [All] units to enter ocean tiles <starting from the [Ancient era]>", "Normal vision when embarked <for [All] units>", "+[10]% Strength if within [2] tiles of a [Moai]"],
"uniques": ["Enables embarkation for land units <starting from the [Ancient era]>", "Enables [All] units to enter ocean tiles <starting from the [Ancient era]>", "Normal vision when embarked <for [All] units>", "[+10]% Strength <within [2] tiles of a [Moai]>"],
"cities": ["Honolulu","Samoa","Tonga","Nuku Hiva","Raiatea","Aotearoa","Tahiti","Hilo","Te Wai Pounamu","Rapa Nui",
"Tuamotu","Rarotonga","Tuvalu","Tubuai","Mangareva","Oahu","Kiritimati","Ontong Java","Niue","Rekohu",
"Rakahanga","Bora Bora","Kailua","Uvea","Futuna","Rotuma","Tokelau","Lahaina","Bellona","Mungava","Tikopia",

View File

@ -633,6 +633,7 @@ Your [ourUnit] captured an enemy [theirUnit]! =
Your [ourUnit] plundered [amount] [Stat] from [theirUnit] =
We have captured a barbarian encampment and recovered [goldAmount] gold! =
A barbarian [unitType] has joined us! =
We have captured an enemy [unitType]! =
We have found survivors in the ruins - population added to [cityName] =
We have discovered cultural artifacts in the ruins! (+20 Culture) =
We have discovered the lost technology of [techName] in the ruins! =

View File

@ -94,8 +94,11 @@ object Battle {
if (!captureMilitaryUnitSuccess) // capture creates a new unit, but `defender` still is the original, so this function would still show a kill message
postBattleNotifications(attacker, defender, attackedTile, attacker.getTile())
if (defender.getCivInfo().isBarbarian() && attackedTile.improvement == Constants.barbarianEncampment)
defender.getCivInfo().gameInfo.barbarians.campAttacked(attackedTile.position)
postBattleNationUniques(defender, attackedTile, attacker)
// This needs to come BEFORE the move-to-tile, because if we haven't conquered it we can't move there =)
if (defender.isDefeated() && defender is CityCombatant && attacker is MapUnitCombatant
&& attacker.isMelee() && !attacker.unit.hasUnique(UniqueType.CannotCaptureCities)) {
@ -206,21 +209,7 @@ object Battle {
// This is called after takeDamage and so the defeated defender is already destroyed and
// thus removed from the tile - but MapUnit.destroy() will not clear the unit's currentTile.
// Therefore placeUnitNearTile _will_ place the new unit exactly where the defender was
val defenderName = defender.getName()
val newUnit = attacker.getCivInfo().placeUnitNearTile(defender.getTile().position, defenderName)
?: return false // silently fail
attacker.getCivInfo().addNotification(
"Your [${attacker.getName()}] captured an enemy [$defenderName]",
newUnit.getTile().position, attacker.getName(), NotificationIcon.War, defenderName )
// Also capture any civilians on the same tile
if (newUnit.currentTile.civilianUnit != null)
captureCivilianUnit(attacker, MapUnitCombatant(newUnit.currentTile.civilianUnit!!))
newUnit.currentMovement = 0f
newUnit.health = 50
return true
return spawnCapturedUnit(defender.getName(), attacker, defender.getTile(), "Your [${attacker.getName()}] captured an enemy [${defender.getName()}]!")
}
private fun takeDamage(attacker: ICombatant, defender: ICombatant) {
@ -325,38 +314,71 @@ object Battle {
attacker.unit.healBy(amountToHeal)
}
}
/** Places a [unitName] unit near [tile] after being attacked by [attacker].
* Adds a notification to [attacker]'s civInfo and returns whether the captured unit could be placed */
private fun spawnCapturedUnit(unitName: String, attacker: ICombatant, tile: TileInfo, notification: String): Boolean {
val addedUnit = attacker.getCivInfo().placeUnitNearTile(tile.position, unitName) ?: return false
addedUnit.currentMovement = 0f
addedUnit.health = 50
attacker.getCivInfo().addNotification(notification, addedUnit.getTile().position, attacker.getName(), unitName)
// Also capture any civilians on the same tile
if (tile.civilianUnit != null)
captureCivilianUnit(attacker, MapUnitCombatant(tile.civilianUnit!!))
return true
}
private fun postBattleNationUniques(defender: ICombatant, attackedTile: TileInfo, attacker: ICombatant) {
if (!defender.isDefeated()) return
// Barbarians reduce spawn countdown after their camp was attacked "kicking the hornet's nest"
if (defender.getCivInfo().isBarbarian() && attackedTile.improvement == Constants.barbarianEncampment) {
defender.getCivInfo().gameInfo.barbarians.campAttacked(attackedTile.position)
var unitPlaced = false
// German unique - needs to be checked before we try to move to the enemy tile, since the encampment disappears after we move in
if (defender.isDefeated()
&& attacker.getCivInfo().hasUnique(UniqueType.ChanceToRecruitBarbarianFromEncampment)
&& Random().nextDouble() < 0.67) {
attacker.getCivInfo().placeUnitNearTile(attackedTile.position, defender.getName())
attacker.getCivInfo().addGold(25)
attacker.getCivInfo().addNotification("A barbarian [${defender.getName()}] has joined us!", attackedTile.position, defender.getName())
// Also capture any civilians on the same tile
if (attackedTile.civilianUnit != null)
captureCivilianUnit(attacker, MapUnitCombatant(attackedTile.civilianUnit!!))
// Deprecated as of 4.0.3
if (attacker.getCivInfo().hasUnique(UniqueType.ChanceToRecruitBarbarianFromEncampment)
&& Random().nextDouble() < 0.67
) {
attacker.getCivInfo().addGold(25)
unitPlaced = spawnCapturedUnit(defender.getName(), attacker, attackedTile,"A barbarian [${defender.getName()}] has joined us!")
}
// New version of unique
//
for (unique in attacker.getCivInfo().getMatchingUniques(UniqueType.GainFromEncampment)) {
attacker.getCivInfo().addGold(unique.params[0].toInt())
if (unitPlaced) continue
unitPlaced = spawnCapturedUnit(defender.getName(), attacker, attackedTile,"A barbarian [${defender.getName()}] has joined us!")
}
}
// Similarly, Ottoman unique
if (attacker.getCivInfo().hasUnique(UniqueType.ChanceToRecruitNavalBarbarian)
&& defender.isDefeated()
&& defender is MapUnitCombatant
&& defender.unit.baseUnit.isWaterUnit()
&& defender.getCivInfo().isBarbarian()
&& attacker.isMelee()
&& attacker is MapUnitCombatant
&& attacker.unit.baseUnit.isWaterUnit()
&& Random().nextDouble() > 0.5) {
attacker.getCivInfo().placeUnitNearTile(attackedTile.position, defender.getName())
attacker.getCivInfo().addGold(25)
// Deprecated as of 4.0.3
if (attacker.getCivInfo().hasUnique(UniqueType.ChanceToRecruitNavalBarbarian)
&& defender.isDefeated()
&& defender is MapUnitCombatant
&& defender.unit.baseUnit.isWaterUnit()
&& defender.getCivInfo().isBarbarian()
&& attacker.isMelee()
&& attacker is MapUnitCombatant
&& attacker.unit.baseUnit.isWaterUnit()
&& Random().nextDouble() < 0.5) {
attacker.getCivInfo().addGold(25)
spawnCapturedUnit(defender.getName(), attacker, attackedTile, "We have captured an enemy [${defender.getName()}]!")
}
//
if (defender.isDefeated() && defender is MapUnitCombatant) {
var unitPlaced = false
for (unique in attacker.getCivInfo().getMatchingUniques(UniqueType.GainFromDefeatingUnit)) {
if (defender.unit.matchesFilter(unique.params[0])
&& attacker.isMelee()
) {
attacker.getCivInfo().addGold(unique.params[1].toInt())
if (unitPlaced) continue
unitPlaced = spawnCapturedUnit(defender.getName(), attacker, attackedTile, "We have captured an enemy [${defender.getName()}]!")
}
}
}
}

View File

@ -206,6 +206,7 @@ object BattleDamage {
return modifiers
}
@Deprecated("As of 4.0.3", level=DeprecationLevel.WARNING)
private fun getTileSpecificModifiers(unit: MapUnitCombatant, tile: TileInfo): Counter<String> {
val modifiers = Counter<String>()
@ -226,14 +227,14 @@ object BattleDamage {
}
private fun getHealthDependantDamageRatio(combatant: ICombatant): Float {
return if (combatant !is MapUnitCombatant // is city
|| (combatant.getCivInfo().hasUnique(UniqueType.UnitsFightFullStrengthWhenDamaged)
&& !combatant.unit.baseUnit.movesLikeAirUnits()
)
return if (combatant !is MapUnitCombatant
|| combatant.unit.hasUnique(UniqueType.NoDamagePenalty, checkCivInfoUniques = true)
|| combatant.getCivInfo().hasUnique(UniqueType.UnitsFightFullStrengthWhenDamaged)
) {
1f
}
else 1 - (100 - combatant.getHealth()) / 300f// Each 3 points of health reduces damage dealt by 1% like original game
// Each 3 points of health reduces damage dealt by 1%
else 1 - (100 - combatant.getHealth()) / 300f
}

View File

@ -119,7 +119,7 @@ class ReligionManager {
if (getGreatProphetEquivalent() == null) return false
if (storedFaith < faithForNextGreatProphet()) return false
if (!civInfo.isMajorCiv()) return false
if (civInfo.hasUnique(UniqueType.MAyNotGenerateGreatProphet)) return false
if (civInfo.hasUnique(UniqueType.MayNotGenerateGreatProphet)) return false
return true
}

View File

@ -466,13 +466,12 @@ open class TileInfo {
improvement.techRequired != null && !civInfo.tech.isResearched(improvement.techRequired!!) -> false
getOwner() != civInfo && !(
improvement.hasUnique(UniqueType.CanBuildOutsideBorders)
|| ( // citadel can be built only next to or within own borders
improvement.hasUnique(UniqueType.CanBuildJustOutsideBorders)
&& neighbors.any { it.getOwner() == civInfo } && civInfo.cities.isNotEmpty()
)
|| ( // citadel can be built only next to or within own borders
improvement.hasUnique(UniqueType.CanBuildJustOutsideBorders)
&& neighbors.any { it.getOwner() == civInfo }
)
) -> false
improvement.uniqueObjects.filter { it.type == UniqueType.OnlyAvailableWhen }
.any { !it.conditionalsApply(StateForConditionals(civInfo)) } -> false
improvement.hasUnique(UniqueType.OnlyAvailableWhen, StateForConditionals(civInfo=civInfo, tile=this)) -> false
improvement.getMatchingUniques(UniqueType.ObsoleteWith).any {
civInfo.tech.isResearched(it.params[0])
} -> return false

View File

@ -11,6 +11,7 @@ import com.unciv.models.ruleset.Ruleset
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.random.Random
class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val sourceObjectName: String? = null) {
@ -131,12 +132,16 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
if (state.ourCombatant != null && state.ourCombatant is MapUnitCombatant) state.ourCombatant.unit
else state.unit
}
val stateBasedRandom by lazy { Random(state.hashCode()) }
return when (condition.type) {
// These are 'what to do' and not 'when to do' conditionals
UniqueType.ConditionalTimedUnique -> true
UniqueType.ConditionalConsumeUnit -> true
UniqueType.ConditionalChance -> stateBasedRandom.nextFloat() < condition.params[0].toFloat() / 100f
UniqueType.ConditionalWar -> state.civInfo?.isAtWar() == true
UniqueType.ConditionalNotWar -> state.civInfo?.isAtWar() == false
UniqueType.ConditionalWithResource -> state.civInfo?.hasResource(condition.params[0]) == true
@ -200,8 +205,13 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
UniqueType.ConditionalFightingInTiles ->
state.attackedTile?.matchesFilter(condition.params[0], state.civInfo) == true
UniqueType.ConditionalInTilesAnd ->
relevantTile!=null && relevantTile!!.matchesFilter(condition.params[0], state.civInfo)
relevantTile != null && relevantTile!!.matchesFilter(condition.params[0], state.civInfo)
&& relevantTile!!.matchesFilter(condition.params[1], state.civInfo)
UniqueType.ConditionalNearTiles ->
relevantTile != null && relevantTile!!.getTilesInDistance(condition.params[0].toInt()).any {
it.matchesFilter(condition.params[1])
}
UniqueType.ConditionalVsLargerCiv -> {
val yourCities = state.civInfo?.cities?.size ?: 1
val theirCities = state.theirCombatant?.getCivInfo()?.cities?.size ?: 0

View File

@ -223,14 +223,19 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
// Misc national uniques
NotifiedOfBarbarianEncampments("Notified of new Barbarian encampments", UniqueTarget.Global),
BorrowsCityNames("\"Borrows\" city names from other civilizations in the game", UniqueTarget.Global),
@Deprecated("as of 4.0.3", ReplaceWith("Damage is ignored when determining unit Strength <for [All] units>"))
UnitsFightFullStrengthWhenDamaged("Units fight as though they were at full strength even when damaged", UniqueTarget.Global),
GoldWhenDiscoveringNaturalWonder("100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it)", UniqueTarget.Global),
UnhappinessFromCitiesDoubled("Unhappiness from number of Cities doubled", UniqueTarget.Global),
GreatGeneralProvidesDoubleCombatBonus("Great General provides double combat bonus", UniqueTarget.Global),
TechBoostWhenScientificBuildingsBuiltInCapital("Receive a tech boost when scientific buildings/wonders are built in capital", UniqueTarget.Global),
MAyNotGenerateGreatProphet("May not generate great prophet equivalents naturally", UniqueTarget.Global),
MayNotGenerateGreatProphet("May not generate great prophet equivalents naturally", UniqueTarget.Global),
@Deprecated("as of 4.0.3", ReplaceWith("When conquering an encampment, earn [25] Gold and recruit a Barbarian unit <with [67]% chance>"))
ChanceToRecruitBarbarianFromEncampment("67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment", UniqueTarget.Global),
GainFromEncampment("When conquering an encampment, earn [amount] Gold and recruit a Barbarian unit", UniqueTarget.Global),
@Deprecated("as of 4.0.3", ReplaceWith("When defeating a [{Barbarian} {Water}] unit, earn [25] Gold and recruit it <with [50]% chance>"))
ChanceToRecruitNavalBarbarian("50% chance of capturing defeated Barbarian naval units and earning 25 Gold", UniqueTarget.Global),
GainFromDefeatingUnit("When defeating a [mapUnitFilter] unit, earn [amount] Gold and recruit it", UniqueTarget.Global),
TripleGoldFromEncampmentsAndCities("Receive triple Gold from Barbarian encampments and pillaging Cities", UniqueTarget.Global),
CitiesAreRazedXTimesFaster("Cities are razed [amount] times as fast", UniqueTarget.Global),
GreatPersonBoostWithFriendship("When declaring friendship, both parties gain a [amount]% boost to great person generation", UniqueTarget.Global),
@ -240,8 +245,8 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
GainInfluenceWithUnitGiftToCityState("Gain [amount] Influence with a [baseUnitFilter] gift to a City-State", UniqueTarget.Global),
FaithCostOfGreatProphetChange("[amount]% Faith cost of generating Great Prophet equivalents", UniqueTarget.Global),
RestingPointOfCityStatesFollowingReligionChange("Resting point for Influence with City-States following this religion [amount]", UniqueTarget.Global),
// Todo can be replaced with a <within [amount] tiles of a [tileFilter] tile> conditional
StrengthWithinTilesOfTile("+[amount]% Strength if within [amount] tiles of a [tileFilter]", UniqueTarget.Global),
@Deprecated("as of 4.0.3", ReplaceWith("[+amount]% Strength <within [amount2] tiles of a [tileFilter]>"))
StrengthWithinTilesOfTile("+[amount]% Strength if within [amount2] tiles of a [tileFilter]", UniqueTarget.Global),
StatBonusPercentFromCityStates("[amount]% [stat] from City-States", UniqueTarget.Global),
ProvidesGoldWheneverGreatPersonExpended("Provides a sum of gold each time you spend a Great Person", UniqueTarget.Global),
@ -420,6 +425,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
NoDefensiveTerrainBonus("No defensive terrain bonus", UniqueTarget.Unit, UniqueTarget.Global),
NoDefensiveTerrainPenalty("No defensive terrain penalty", UniqueTarget.Unit, UniqueTarget.Global),
NoDamagePenalty("Damage is ignored when determining unit Strength", UniqueTarget.Unit, UniqueTarget.Global),
Uncapturable("Uncapturable", UniqueTarget.Unit),
MayWithdraw("May withdraw before melee ([amount]%)", UniqueTarget.Unit),
CannotCaptureCities("Unable to capture cities", UniqueTarget.Unit),
@ -437,6 +443,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
NormalVisionWhenEmbarked("Normal vision when embarked", UniqueTarget.Unit, UniqueTarget.Global),
DefenceBonusWhenEmbarked("Defense bonus when embarked", UniqueTarget.Unit, UniqueTarget.Global),
@Deprecated("as of 4.0.3", ReplaceWith("Defense bonus when embarked <for [All] units>"))
DefenceBonusWhenEmbarkedCivwide("Embarked units can defend themselves", UniqueTarget.Global),
@Deprecated("as of 3.19.8", ReplaceWith("Eliminates combat penalty for attacking across a coast"))
AttackFromSea("Eliminates combat penalty for attacking from the sea", UniqueTarget.Unit),
@ -586,6 +593,11 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
///////////////////////////////////////// region CONDITIONALS /////////////////////////////////////////
/////// general conditionals
ConditionalTimedUnique("for [amount] turns", UniqueTarget.Conditional),
ConditionalConsumeUnit("by consuming this unit", UniqueTarget.Conditional),
ConditionalChance("with [amount]% chance", UniqueTarget.Conditional),
/////// civ conditionals
ConditionalWar("when at war", UniqueTarget.Conditional),
ConditionalNotWar("when not at war", UniqueTarget.Conditional),
@ -608,9 +620,6 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
ConditionalNoPolicy("before adopting [policy]", UniqueTarget.Conditional),
ConditionalBuildingBuilt("if [buildingName] is constructed", UniqueTarget.Conditional),
ConditionalTimedUnique("for [amount] turns", UniqueTarget.Conditional),
ConditionalConsumeUnit("by consuming this unit", UniqueTarget.Conditional),
/////// city conditionals
ConditionalCityWithBuilding("in cities with a [buildingFilter]", UniqueTarget.Conditional),
ConditionalCityWithoutBuilding("in cities without a [buildingFilter]", UniqueTarget.Conditional),
@ -642,6 +651,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
ConditionalInTiles("in [tileFilter] tiles", UniqueTarget.Conditional),
ConditionalInTilesAnd("in [tileFilter] [tileFilter] tiles", UniqueTarget.Conditional),
ConditionalInTilesNot("in tiles without [tileFilter]", UniqueTarget.Conditional),
ConditionalNearTiles("within [amount] tiles of a [tileFilter]", UniqueTarget.Conditional),
/////// area conditionals
ConditionalOnWaterMaps("on water maps", UniqueTarget.Conditional),
@ -682,7 +692,6 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
OneTimeUnitGainPromotion("This Unit gains the [promotion] promotion", UniqueTarget.Triggerable), // Not used in Vanilla
UnitsGainPromotion("[mapUnitFilter] units gain the [promotion] promotion", UniqueTarget.Triggerable), // Not used in Vanilla
// todo: remove forced sign
@Deprecated("as of 3.19.8", ReplaceWith("[+amount]% Strength <when attacking> <for [mapUnitFilter] units> <for [amount2] turns>"))
TimedAttackStrength("+[amount]% attack strength to all [mapUnitFilter] units for [amount2] turns", UniqueTarget.Global), // used in Policy
FreeStatBuildings("Provides the cheapest [stat] building in your first [amount] cities for free", UniqueTarget.Triggerable), // used in Policy

View File

@ -441,9 +441,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example ""Borrows" city names from other civilizations in the game"
Applicable to: Global
??? example "Units fight as though they were at full strength even when damaged"
Applicable to: Global
??? example "100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it)"
Applicable to: Global
@ -459,10 +456,14 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "May not generate great prophet equivalents naturally"
Applicable to: Global
??? example "67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment"
??? example "When conquering an encampment, earn [amount] Gold and recruit a Barbarian unit"
Example: "When conquering an encampment, earn [20] Gold and recruit a Barbarian unit"
Applicable to: Global
??? example "50% chance of capturing defeated Barbarian naval units and earning 25 Gold"
??? example "When defeating a [mapUnitFilter] unit, earn [amount] Gold and recruit it"
Example: "When defeating a [Wounded] unit, earn [20] Gold and recruit it"
Applicable to: Global
??? example "Receive triple Gold from Barbarian encampments and pillaging Cities"
@ -508,11 +509,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Global
??? example "+[amount]% Strength if within [amount] tiles of a [tileFilter]"
Example: "+[20]% Strength if within [20] tiles of a [Farm]"
Applicable to: Global
??? example "[amount]% [stat] from City-States"
Example: "[20]% [Culture] from City-States"
@ -689,6 +685,9 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "No defensive terrain penalty"
Applicable to: Global, Unit
??? example "Damage is ignored when determining unit Strength"
Applicable to: Global, Unit
??? example "No movement cost to pillage"
Applicable to: Global, Unit
@ -712,9 +711,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "Defense bonus when embarked"
Applicable to: Global, Unit
??? example "Embarked units can defend themselves"
Applicable to: Global
??? example "[amount]% maintenance costs"
Example: "[20]% maintenance costs"
@ -1448,6 +1444,19 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: CityState
## Conditional uniques
??? example "&lt;for [amount] turns&gt;"
Example: "&lt;for [20] turns&gt;"
Applicable to: Conditional
??? example "&lt;by consuming this unit&gt;"
Applicable to: Conditional
??? example "&lt;with [amount]% chance&gt;"
Example: "&lt;with [20]% chance&gt;"
Applicable to: Conditional
??? example "&lt;when at war&gt;"
Applicable to: Conditional
@ -1523,14 +1532,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Conditional
??? example "&lt;for [amount] turns&gt;"
Example: "&lt;for [20] turns&gt;"
Applicable to: Conditional
??? example "&lt;by consuming this unit&gt;"
Applicable to: Conditional
??? example "&lt;in cities with a [buildingFilter]&gt;"
Example: "&lt;in cities with a [Culture]&gt;"
@ -1629,6 +1630,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Conditional
??? example "&lt;within [amount] tiles of a [tileFilter]&gt;"
Example: "&lt;within [20] tiles of a [Farm]&gt;"
Applicable to: Conditional
??? example "&lt;on water maps&gt;"
Applicable to: Conditional

2
gradlew.bat vendored
View File

@ -33,7 +33,7 @@ set APP_HOME=%DIRNAME%
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
set DEFAULT_JVM_OPTS="-Xmx4G" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome