Added ConditionalWhenBetweenStatResource unique (#11212)

* Added ConditionalWhenBetweenStatResource unique

* Currently the ConditionalBetweenHappiness function only applies to Happiness. Wouldn't it be more better if it could also be extended to other stats and resources. 😊

* Resolved the issue with ConditionalWhenAboveStatResource, ConditionalWhenBelowStatResource, and their modified speed versions not functioning properly on city-level stats (food & production).

This new unique has been tested using the following examples:
    1. In GlobalUniques.json:
        - "[+12]% [Gold] [in all cities] <when between [1] to [100] [Gold]>",
        - "[+24]% [Gold] [in all cities] <when between [1] to [100] [Gold] (modified by game speed)>",
    2. In Buildings.json:
        - "[+12]% [Production] [in this city] <when between [1] to [5] [Production]>",
        - "[+12]% [Food] [in this city] <when between [1] to [5] [Food]>",

* Update uniques.md

* Correct english mistake of the new unique

* Refactor checkResourceOrStatAmount function

* Unified all related functions into one
This commit is contained in:
Jeremy Woo 2024-03-06 04:40:27 +08:00 committed by GitHub
parent 03a30ea7c9
commit 31931d3849
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 39 additions and 23 deletions

1
.gitignore vendored
View File

@ -39,6 +39,7 @@ com_crashlytics_export_strings.xml
.classpath
.project
.metadata/
/tests/bin/
/android/bin/
/core/bin/
/desktop/bin/

View File

@ -79,31 +79,24 @@ object Conditionals {
}
/** Helper for ConditionalWhenAboveAmountStatResource and its below counterpart */
fun checkResourceOrStatAmount(compare: (current: Int, limit: Int) -> Boolean): Boolean {
fun checkResourceOrStatAmount(
resourceOrStatName: String,
lowerLimit: Float,
upperLimit: Float,
modifyByGameSpeed: Boolean = false,
compare: (current: Int, lowerLimit: Float, upperLimit: Float) -> Boolean
): Boolean {
if (gameInfo == null) return false
val limit = condition.params[0].toInt()
val resourceOrStatName = condition.params[1]
if (gameInfo!!.ruleset.tileResources.containsKey(resourceOrStatName))
return compare(getResourceAmount(resourceOrStatName), limit)
val stat = Stat.safeValueOf(resourceOrStatName)
?: return false
return compare(relevantCiv!!.getStatReserve(stat), limit)
}
/** Helper for ConditionalWhenAboveAmountStatSpeed and its below counterpart */
fun checkResourceOrStatAmountWithSpeed(compare: (current: Int, limit: Float) -> Boolean): Boolean {
if (gameInfo == null) return false
val limit = condition.params[0].toInt()
val resourceOrStatName = condition.params[1]
var gameSpeedModifier = gameInfo!!.speed.modifier
var gameSpeedModifier = if (modifyByGameSpeed) gameInfo!!.speed.modifier else 1f
if (gameInfo!!.ruleset.tileResources.containsKey(resourceOrStatName))
return compare(getResourceAmount(resourceOrStatName), limit * gameSpeedModifier)
return compare(getResourceAmount(resourceOrStatName), lowerLimit * gameSpeedModifier, upperLimit * gameSpeedModifier)
val stat = Stat.safeValueOf(resourceOrStatName)
?: return false
val statReserve = if (relevantCity != null) relevantCity!!.getStatReserve(stat) else relevantCiv!!.getStatReserve(stat)
gameSpeedModifier = gameInfo!!.speed.statCostModifiers[stat]!!
return compare(relevantCiv!!.getStatReserve(stat), limit * gameSpeedModifier)
gameSpeedModifier = if (modifyByGameSpeed) gameInfo!!.speed.statCostModifiers[stat]!! else 1f
return compare(statReserve, lowerLimit * gameSpeedModifier, upperLimit * gameSpeedModifier)
}
return when (condition.type) {
@ -122,13 +115,23 @@ object Conditionals {
UniqueType.ConditionalWithoutResource -> getResourceAmount(condition.params[0]) <= 0
UniqueType.ConditionalWhenAboveAmountStatResource ->
checkResourceOrStatAmount { current, limit -> current > limit }
checkResourceOrStatAmount(condition.params[1], condition.params[0].toFloat(), Float.MAX_VALUE)
{ current, lowerLimit, _ -> current > lowerLimit }
UniqueType.ConditionalWhenBelowAmountStatResource ->
checkResourceOrStatAmount { current, limit -> current < limit }
checkResourceOrStatAmount(condition.params[1], Float.MIN_VALUE, condition.params[0].toFloat())
{ current, _, upperLimit -> current < upperLimit }
UniqueType.ConditionalWhenBetweenStatResource ->
checkResourceOrStatAmount(condition.params[2], condition.params[0].toFloat(), condition.params[1].toFloat())
{ current, lowerLimit, upperLimit -> current >= lowerLimit && current <= upperLimit }
UniqueType.ConditionalWhenAboveAmountStatResourceSpeed ->
checkResourceOrStatAmountWithSpeed { current, limit -> current > limit } // Note: Int.compareTo(Float)!
checkResourceOrStatAmount(condition.params[1], condition.params[0].toFloat(), Float.MAX_VALUE, true)
{ current, lowerLimit, _ -> current > lowerLimit }
UniqueType.ConditionalWhenBelowAmountStatResourceSpeed ->
checkResourceOrStatAmountWithSpeed { current, limit -> current < limit } // Note: Int.compareTo(Float)!
checkResourceOrStatAmount(condition.params[1], Float.MIN_VALUE, condition.params[0].toFloat(), true)
{ current, _, upperLimit -> current < upperLimit }
UniqueType.ConditionalWhenBetweenStatResourceSpeed ->
checkResourceOrStatAmount(condition.params[2], condition.params[0].toFloat(), condition.params[1].toFloat(), true)
{ current, lowerLimit, upperLimit -> current >= lowerLimit && current <= upperLimit }
UniqueType.ConditionalHappy -> checkOnCiv { stats.happiness >= 0 }
UniqueType.ConditionalBetweenHappiness ->

View File

@ -663,10 +663,12 @@ enum class UniqueType(
// Supports also stockpileable resources (Gold, Faith, Culture, Science)
ConditionalWhenAboveAmountStatResource("when above [amount] [stat/resource]", UniqueTarget.Conditional),
ConditionalWhenBelowAmountStatResource("when below [amount] [stat/resource]", UniqueTarget.Conditional),
ConditionalWhenBetweenStatResource("when between [amount] and [amount] [stat/resource]", UniqueTarget.Conditional),
// The game speed-adjusted versions of above
ConditionalWhenAboveAmountStatResourceSpeed("when above [amount] [stat/resource] (modified by game speed)", UniqueTarget.Conditional),
ConditionalWhenBelowAmountStatResourceSpeed("when below [amount] [stat/resource] (modified by game speed)", UniqueTarget.Conditional),
ConditionalWhenBetweenStatResourceSpeed("when between [amount] and [amount] [stat/resource] (modified by game speed)", UniqueTarget.Conditional),
/////// city conditionals
ConditionalInThisCity("in this city", UniqueTarget.Conditional),

View File

@ -2048,6 +2048,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Conditional
??? example "&lt;when between [amount] and [amount] [stat/resource]&gt;"
Example: "&lt;when between [3] and [3] [Culture]&gt;"
Applicable to: Conditional
??? example "&lt;when above [amount] [stat/resource] (modified by game speed)&gt;"
Example: "&lt;when above [3] [Culture] (modified by game speed)&gt;"
@ -2058,6 +2063,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Conditional
??? example "&lt;when between [amount] and [amount] [stat/resource] (modified by game speed)&gt;"
Example: "&lt;when between [3] and [3] [Culture] (modified by game speed)&gt;"
Applicable to: Conditional
??? example "&lt;in this city&gt;"
Applicable to: Conditional