mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-26 13:27:22 -04:00
Arbitrary conditionals can become timed conditionals! (#6134)
* Arbitrary conditionals can become timed conditionals! triggerCivwideUniques is activated in 3 situations: - Tech complete - Policy adopted - Building complete So for each of the unique containers for these I added a catch saying 'if this unique is a temporary unique then don't save it yourself This has been lying around in todos for a while and generalizes one of the nasty hardcoded messes that I hate about Civ V. Why would you introduce ONE timed effect in the whole game?! You can use them all the time like Humankind or never use them like Civ IV, but why have just one whyyy One more thing in this PR, that needed to be solved by the by, is allowing parameters to have a '2' on the end so we can autoreplace multiple parameters of the same type. Using a regex is slightly more inefficient, but since this is A. only used once per UniqueType.kt, and B. allows us to have as many 'amount's as we want which is important if we have a lot of conditionals, I feel this is justified. * Fixed comments from PR
This commit is contained in:
parent
55d92b9735
commit
4fb4722e3a
@ -407,7 +407,8 @@
|
||||
},
|
||||
{
|
||||
"name": "Autocracy Complete",
|
||||
"uniques": ["+[25]% attack strength to all [Military] units for [50] turns",
|
||||
"uniques": [
|
||||
"[+25]% Strength <when attacking> <for [Military] units> <for [50] turns>",
|
||||
"May buy [Great General] units for [1000] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([500]) <starting from the [Industrial era]>",
|
||||
"May buy [Great Admiral] units for [1000] [Faith] [in all cities in which the majority religion is a major religion] at an increasing price ([500]) <starting from the [Industrial era]>"
|
||||
]
|
||||
|
@ -400,7 +400,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Autocracy Complete",
|
||||
"uniques": ["+[25]% attack strength to all [Military] units for [30] turns"]
|
||||
"uniques": ["[+25]% Strength <when attacking> <for [Military] units> <for [30] turns>"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -462,7 +462,8 @@ class CityConstructions {
|
||||
builtBuildingUniqueMap.clear()
|
||||
for (building in getBuiltBuildings())
|
||||
for (unique in building.uniqueObjects)
|
||||
builtBuildingUniqueMap.addUnique(unique)
|
||||
if (unique.conditionals.none { it.type == UniqueType.ConditionalTimedUnique })
|
||||
builtBuildingUniqueMap.addUnique(unique)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,6 @@ import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.tile.TileResource
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.TemporaryUnique
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.stats.Stat
|
||||
@ -150,6 +149,7 @@ class CivilizationInfo {
|
||||
|
||||
/** Arraylist instead of HashMap as the same unique might appear multiple times
|
||||
* We don't use pairs, as these cannot be serialized due to having no no-arg constructor
|
||||
* This can also contain NON-temporary uniques but I can't be bothered to do the deprecation dance with this one
|
||||
*/
|
||||
val temporaryUniques = ArrayList<TemporaryUnique>()
|
||||
|
||||
@ -864,9 +864,10 @@ class CivilizationInfo {
|
||||
|
||||
// Update turn counter for temporary uniques
|
||||
for (unique in temporaryUniques) {
|
||||
unique.turnsLeft -= 1
|
||||
if (unique.turnsLeft >= 0)
|
||||
unique.turnsLeft -= 1
|
||||
}
|
||||
temporaryUniques.removeAll { it.turnsLeft <= 0 }
|
||||
temporaryUniques.removeAll { it.turnsLeft == 0 }
|
||||
|
||||
goldenAges.endTurn(getHappiness())
|
||||
getCivUnits().forEach { it.endTurn() } // This is the most expensive part of endTurn
|
||||
|
@ -54,8 +54,9 @@ class PolicyManager {
|
||||
|
||||
fun addPolicyToTransients(policy: Policy) {
|
||||
for (unique in policy.uniqueObjects) {
|
||||
// Should be replaced with a conditional of the same form later
|
||||
if (!unique.text.contains(turnCountRegex))
|
||||
// Should be deprecated together with TimedAttackStrength so I'm putting this here so the compiler will complain if we don't
|
||||
val rememberToDeprecate = UniqueType.TimedAttackStrength
|
||||
if (!unique.text.contains(turnCountRegex) && unique.conditionals.none { it.type == UniqueType.ConditionalTimedUnique })
|
||||
policyUniques.addUnique(unique)
|
||||
}
|
||||
}
|
||||
|
@ -365,7 +365,8 @@ class TechManager {
|
||||
|
||||
fun addTechToTransients(tech: Technology) {
|
||||
for (unique in tech.uniqueObjects)
|
||||
techUniques.addUnique(unique)
|
||||
if (unique.conditionals.none { it.type == UniqueType.ConditionalTimedUnique })
|
||||
techUniques.addUnique(unique)
|
||||
}
|
||||
|
||||
fun setTransients() {
|
||||
|
@ -85,6 +85,7 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
|
||||
}
|
||||
|
||||
return when (condition.type) {
|
||||
UniqueType.ConditionalTimedUnique -> true
|
||||
UniqueType.ConditionalWar -> state.civInfo?.isAtWar() == true
|
||||
UniqueType.ConditionalNotWar -> state.civInfo?.isAtWar() == false
|
||||
UniqueType.ConditionalWithResource -> state.civInfo?.hasResource(condition.params[0]) == true
|
||||
@ -224,7 +225,6 @@ class UniqueMapTyped: EnumMap<UniqueType, ArrayList<Unique>>(UniqueType::class.j
|
||||
}
|
||||
|
||||
|
||||
// Will probably be allowed to be used as a conditional when I get the motivation to work on that -xlenstra
|
||||
class TemporaryUnique() {
|
||||
|
||||
constructor(uniqueObject: Unique, turns: Int) : this() {
|
||||
|
@ -31,6 +31,12 @@ object UniqueTriggerActivation {
|
||||
|
||||
if (!unique.conditionalsApply(StateForConditionals(civInfo, cityInfo))) return false
|
||||
|
||||
val timingConditional = unique.conditionals.firstOrNull{it.type == ConditionalTimedUnique}
|
||||
if (timingConditional!=null) {
|
||||
civInfo.temporaryUniques.add(TemporaryUnique(unique, timingConditional.params[0].toInt()))
|
||||
return true
|
||||
}
|
||||
|
||||
@Suppress("NON_EXHAUSTIVE_WHEN") // Yes we're not treating all types here
|
||||
when (unique.type) {
|
||||
OneTimeFreeUnit -> {
|
||||
|
@ -548,6 +548,8 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
ConditionalPolicy("after adopting [policy]", UniqueTarget.Conditional),
|
||||
ConditionalNoPolicy("before adopting [policy]", UniqueTarget.Conditional),
|
||||
|
||||
ConditionalTimedUnique("for [amount] turns", UniqueTarget.Conditional),
|
||||
|
||||
/////// city conditionals
|
||||
ConditionalSpecialistCount("if this city has at least [amount] specialists", UniqueTarget.Conditional),
|
||||
ConditionalFollowerCount("in cities where this religion has at least [amount] followers", UniqueTarget.Conditional),
|
||||
@ -614,9 +616,9 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
UnitsGainPromotion("[mapUnitFilter] units gain the [promotion] promotion", UniqueTarget.Global), // Not used in Vanilla
|
||||
// todo: remove forced sign
|
||||
StrategicResourcesIncrease("Quantity of strategic resources produced by the empire +[amount]%", UniqueTarget.Global), // used in Policy
|
||||
// todo: remove forced sign
|
||||
// todo: convert to "[amount]% Strength <when attacking> <for [baseUnitFilter] units> <for [amount] turns>"
|
||||
TimedAttackStrength("+[amount]% attack strength to all [mapUnitFilter] units for [amount] turns", UniqueTarget.Global), // used in Policy
|
||||
|
||||
@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.Global), // used in Policy
|
||||
FreeSpecificBuildings("Provides a [buildingName] in your first [amount] cities for free", UniqueTarget.Global), // used in Policy
|
||||
|
||||
@ -811,7 +813,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
for (placeholder in text.getPlaceholderParameters()) {
|
||||
val matchingParameterTypes = placeholder
|
||||
.split('/')
|
||||
.map { UniqueParameterType.safeValueOf(it) }
|
||||
.map { UniqueParameterType.safeValueOf(it.replace(numberRegex, "")) }
|
||||
parameterTypeMap.add(matchingParameterTypes)
|
||||
}
|
||||
targetTypes.addAll(targets)
|
||||
@ -854,5 +856,9 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
|
||||
fun getDeprecationAnnotation(): Deprecated? = declaringClass.getField(name)
|
||||
.getAnnotation(Deprecated::class.java)
|
||||
|
||||
}
|
||||
|
||||
// I didn't put this is a companion object because APPARENTLY doing that means you can't use it in the init function.
|
||||
val numberRegex = Regex("\\d") // I really doubt we'll get to double-digit numbers of parameters in a single unique.
|
||||
|
||||
|
@ -624,11 +624,6 @@ Example: "Quantity of strategic resources produced by the empire +[20]%"
|
||||
|
||||
Applicable to: Global
|
||||
|
||||
#### +[amount]% attack strength to all [mapUnitFilter] units for [amount] turns
|
||||
Example: "+[20]% attack strength to all [Wounded] units for [20] turns"
|
||||
|
||||
Applicable to: Global
|
||||
|
||||
#### Provides the cheapest [stat] building in your first [amount] cities for free
|
||||
Example: "Provides the cheapest [Culture] building in your first [20] cities for free"
|
||||
|
||||
@ -1351,6 +1346,11 @@ Example: "<before adopting [Oligarchy]>"
|
||||
|
||||
Applicable to: Conditional
|
||||
|
||||
#### <for [amount turns>
|
||||
Example: "<for [amount turns>"
|
||||
|
||||
Applicable to: Conditional
|
||||
|
||||
#### <if this city has at least [amount] specialists>
|
||||
Example: "<if this city has at least [20] specialists>"
|
||||
|
||||
@ -1481,6 +1481,7 @@ Applicable to: Conditional
|
||||
- "[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>"
|
||||
- "Heal adjacent units for an additional 15 HP per turn" - Deprecated as of 3.19.3, replace with "All adjacent units heal [+15] HP when healing"
|
||||
- "+[amount]% attack strength to all [mapUnitFilter] units for [amount2] turns" - Deprecated as of 3.19.8, replace with "[+amount]% Strength <when attacking> <for [mapUnitFilter] units> <for [amount2] turns>"
|
||||
- "[stats] per turn from cities before [tech/policy]" - Deprecated as of 3.18.14, replace with "[stats] [in all cities] <before discovering [tech]> OR [stats] [in all cities] <before adopting [policy]>"
|
||||
- "[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>"
|
||||
|
Loading…
x
Reference in New Issue
Block a user