From 31931d3849e6a569f45f92fe404651e759a3563c Mon Sep 17 00:00:00 2001 From: Jeremy Woo <71725118+woo1127@users.noreply.github.com> Date: Wed, 6 Mar 2024 04:40:27 +0800 Subject: [PATCH] Added ConditionalWhenBetweenStatResource unique (#11212) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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] ", - "[+24]% [Gold] [in all cities] ", 2. In Buildings.json: - "[+12]% [Production] [in this city] ", - "[+12]% [Food] [in this city] ", * Update uniques.md * Correct english mistake of the new unique * Refactor checkResourceOrStatAmount function * Unified all related functions into one --- .gitignore | 1 + .../models/ruleset/unique/Conditionals.kt | 49 ++++++++++--------- .../unciv/models/ruleset/unique/UniqueType.kt | 2 + docs/Modders/uniques.md | 10 ++++ 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 7f7565210a..da05014f5a 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ com_crashlytics_export_strings.xml .classpath .project .metadata/ +/tests/bin/ /android/bin/ /core/bin/ /desktop/bin/ diff --git a/core/src/com/unciv/models/ruleset/unique/Conditionals.kt b/core/src/com/unciv/models/ruleset/unique/Conditionals.kt index 4b3573e09b..2005b7d307 100644 --- a/core/src/com/unciv/models/ruleset/unique/Conditionals.kt +++ b/core/src/com/unciv/models/ruleset/unique/Conditionals.kt @@ -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 -> diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index 81f3f5bb35..39bbfbc353 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -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), diff --git a/docs/Modders/uniques.md b/docs/Modders/uniques.md index 7c5ca714a7..a7205c3919 100644 --- a/docs/Modders/uniques.md +++ b/docs/Modders/uniques.md @@ -2048,6 +2048,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl Applicable to: Conditional +??? example "<when between [amount] and [amount] [stat/resource]>" + Example: "<when between [3] and [3] [Culture]>" + + Applicable to: Conditional + ??? example "<when above [amount] [stat/resource] (modified by game speed)>" Example: "<when above [3] [Culture] (modified by game speed)>" @@ -2058,6 +2063,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl Applicable to: Conditional +??? example "<when between [amount] and [amount] [stat/resource] (modified by game speed)>" + Example: "<when between [3] and [3] [Culture] (modified by game speed)>" + + Applicable to: Conditional + ??? example "<in this city>" Applicable to: Conditional