From d3c084f89f5c31ff2a4928d85f2ac4c5e9e904bf Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Sun, 5 Mar 2023 20:03:54 +0200 Subject: [PATCH] Added 'additional times' to limited actions --- .../jsons/Civ V - Gods & Kings/Units.json | 3 ++- .../unciv/models/ruleset/unique/UniqueType.kt | 1 + .../worldscreen/unit/actions/UnitActions.kt | 26 ++++++++++++++----- docs/Modders/uniques.md | 5 ++++ 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/android/assets/jsons/Civ V - Gods & Kings/Units.json b/android/assets/jsons/Civ V - Gods & Kings/Units.json index 14cc7539d8..321ddafc60 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/Units.json +++ b/android/assets/jsons/Civ V - Gods & Kings/Units.json @@ -1610,7 +1610,8 @@ "unitType": "Civilian", "uniques": [ "Can hurry technology research", - "Can instantly construct a [Academy] improvement ", + "Can instantly construct a [Academy] improvement ", + "Can instantly construct a [Academy] improvement <[1] additional time(s)>", "Great Person - [Science]", "Unbuildable", "Uncapturable"], "movement": 2 }, diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index 363d6ad2b3..fc0297bcd6 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -511,6 +511,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: UnitActionMovementCost("for [amount] movement", UniqueTarget.UnitActionModifier), UnitActionOnce("once", UniqueTarget.UnitActionModifier), UnitActionLimitedTimes("[amount] times", UniqueTarget.UnitActionModifier), + UnitActionExtraLimitedTimes("[amount] additional time(s)", UniqueTarget.UnitActionModifier), UnitActionAfterWhichConsumed("after which this unit is consumed", UniqueTarget.UnitActionModifier), // endregion diff --git a/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActions.kt b/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActions.kt index 15101a260a..27c76ba3a7 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActions.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActions.kt @@ -180,7 +180,9 @@ object UnitActions { * (no movement left, too close to another city). */ fun getFoundCityAction(unit: MapUnit, tile: Tile): UnitAction? { - val unique = unit.getMatchingUniques(UniqueType.FoundCity).firstOrNull() + val unique = unit.getMatchingUniques(UniqueType.FoundCity) + .filter { it.conditionals.none { it.type == UniqueType.UnitActionExtraLimitedTimes } } + .firstOrNull() if (unique == null || tile.isWater || tile.isImpassible()) return null // Spain should still be able to build Conquistadors in a one city challenge - but can't settle them if (unit.civ.isOneCityChallenger() && unit.civ.hasEverOwnedOriginalCapital == true) return null @@ -471,6 +473,8 @@ object UnitActions { val civResources = unit.civ.getCivResourcesByName() for (unique in uniquesToCheck) { + if (unique.conditionals.any { it.type == UniqueType.UnitActionExtraLimitedTimes }) continue + val improvementName = unique.params[0] val improvement = tile.ruleset.tileImprovements[improvementName] ?: continue @@ -659,6 +663,7 @@ object UnitActions { val triggerableTypes = setOf(UniqueTarget.Triggerable, UniqueTarget.UnitTriggerable) for (unique in unit.getUniques()) { if (unique.conditionals.none { it.type?.targetTypes?.contains(UniqueTarget.UnitActionModifier) == true }) continue + if (unique.conditionals.any { it.type == UniqueType.UnitActionExtraLimitedTimes }) continue if (unique.type?.targetTypes?.any { it in triggerableTypes }!=true && unique.conditionals.none { it.type == UniqueType.ConditionalTimedUnique }) continue if (usagesLeft(unit, unique)==0) continue @@ -709,7 +714,7 @@ object UnitActions { for (conditional in actionUnique.conditionals){ when (conditional.type){ UniqueType.UnitActionConsumeUnit -> unit.consume() - UniqueType.UnitActionLimitedTimes -> { + UniqueType.UnitActionLimitedTimes, UniqueType.UnitActionOnce -> { if (usagesLeft(unit, actionUnique) == 1 && actionUnique.conditionals.any { it.type==UniqueType.UnitActionAfterWhichConsumed }) { unit.consume() @@ -725,17 +730,24 @@ object UnitActions { /** Returns 'null' if usages are not limited */ fun usagesLeft(unit:MapUnit, actionUnique: Unique): Int?{ - val usagesTotal = getMaxUsages(actionUnique) ?: return null + val usagesTotal = getMaxUsages(unit, actionUnique) ?: return null val usagesSoFar = unit.abilityToTimesUsed[actionUnique.placeholderText] ?: 0 return usagesTotal - usagesSoFar } - fun getMaxUsages(actionUnique: Unique): Int? { + fun getMaxUsages(unit: MapUnit, actionUnique: Unique): Int? { + val extraTimes = unit.getMatchingUniques(actionUnique.type!!) + .filter { it.text.removeConditionals() == actionUnique.text.removeConditionals() } + .flatMap { it.conditionals.filter { it.type == UniqueType.UnitActionExtraLimitedTimes } } + .map { it.params[0].toInt() } + .sum() + val times = actionUnique.conditionals .filter { it.type == UniqueType.UnitActionLimitedTimes } .maxOfOrNull { it.params[0].toInt() } - if (times != null) return times - if (actionUnique.conditionals.any { it.type == UniqueType.UnitActionOnce }) return 1 + if (times != null) return times + extraTimes + if (actionUnique.conditionals.any { it.type == UniqueType.UnitActionOnce }) return 1 + extraTimes + return null } @@ -748,7 +760,7 @@ object UnitActions { fun getSideEffectString(unit:MapUnit, actionUnique: Unique): String { val effects = ArrayList() - val maxUsages = getMaxUsages(actionUnique) + val maxUsages = getMaxUsages(unit, actionUnique) if (maxUsages!=null) effects += "${usagesLeft(unit, actionUnique)}/$maxUsages" if (actionUnique.conditionals.any { it.type == UniqueType.UnitActionConsumeUnit } diff --git a/docs/Modders/uniques.md b/docs/Modders/uniques.md index bb74941cb3..ae7a77ec79 100644 --- a/docs/Modders/uniques.md +++ b/docs/Modders/uniques.md @@ -1990,6 +1990,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl Applicable to: UnitActionModifier +??? example "<[amount] additional time(s)>" + Example: "<[3] additional time(s)>" + + Applicable to: UnitActionModifier + ??? example "<after which this unit is consumed>" Applicable to: UnitActionModifier