diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index a6d1d9b43e..961fa09493 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -9,12 +9,14 @@ import com.unciv.logic.city.CityInfo import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.LocationAction import com.unciv.logic.civilization.NotificationIcon +import com.unciv.models.MultiHashMap import com.unciv.models.UnitActionType import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.tile.TerrainType import com.unciv.models.ruleset.unique.Unique import com.unciv.models.ruleset.tile.TileImprovement import com.unciv.models.ruleset.unique.StateForConditionals +import com.unciv.models.ruleset.unique.UniqueMapTyped import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.ruleset.unit.UnitType @@ -202,6 +204,9 @@ class MapUnit { @Transient private var tempUniques = ArrayList() + @Transient + private var tempUniquesMap = UniqueMapTyped() + fun getUniques(): ArrayList = tempUniques fun getMatchingUniques(placeholderText: String): Sequence = @@ -212,9 +217,11 @@ class MapUnit { stateForConditionals: StateForConditionals = StateForConditionals(civInfo, unit=this), checkCivInfoUniques:Boolean = false ) = sequence { - yieldAll(tempUniques.asSequence() - .filter { it.type == uniqueType && it.conditionalsApply(stateForConditionals) } - ) + val tempUniques = tempUniquesMap[uniqueType] + if (tempUniques != null) + yieldAll( + tempUniques.filter { it.conditionalsApply(stateForConditionals) } + ) if (checkCivInfoUniques) yieldAll(civInfo.getMatchingUniques(uniqueType, stateForConditionals)) } @@ -225,7 +232,7 @@ class MapUnit { fun hasUnique(uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(civInfo, unit=this)): Boolean { - return tempUniques.any { it.type == uniqueType && it.conditionalsApply(stateForConditionals) } + return getMatchingUniques(uniqueType, stateForConditionals).any() } fun updateUniques(ruleset: Ruleset) { @@ -239,6 +246,11 @@ class MapUnit { } tempUniques = uniques + val newUniquesMap = UniqueMapTyped() + for (unique in uniques) + if (unique.type != null) + newUniquesMap.addUnique(unique) + tempUniquesMap = newUniquesMap allTilesCosts1 = hasUnique(UniqueType.AllTilesCost1Move) canPassThroughImpassableTiles = hasUnique(UniqueType.CanPassImpassable) @@ -274,7 +286,7 @@ class MapUnit { } // Init shortcut flags noTerrainMovementUniques = doubleMovementInTerrain.isEmpty() && - !roughTerrainPenalty && !civInfo.nation.ignoreHillMovementCost + !roughTerrainPenalty && !civInfo.nation.ignoreHillMovementCost noBaseTerrainOrHillDoubleMovementUniques = doubleMovementInTerrain .none { it.value != DoubleMovementTerrainTarget.Feature } noFilteredDoubleMovementUniques = doubleMovementInTerrain @@ -967,7 +979,7 @@ class MapUnit { } fun interceptDamagePercentBonus(): Int { - return getUniques().filter { it.placeholderText == "[]% Damage when intercepting"} + return getMatchingUniques("[]% Damage when intercepting") .sumOf { it.params[0].toInt() } } diff --git a/core/src/com/unciv/models/Counter.kt b/core/src/com/unciv/models/Counter.kt index 18345ada26..716dad4054 100644 --- a/core/src/com/unciv/models/Counter.kt +++ b/core/src/com/unciv/models/Counter.kt @@ -1,6 +1,8 @@ package com.unciv.models import java.util.* +import kotlin.collections.ArrayList +import kotlin.collections.LinkedHashMap open class Counter : LinkedHashMap() { @@ -40,3 +42,13 @@ open class Counter : LinkedHashMap() { } } +class MultiHashMap : LinkedHashMap>() { + fun add(key: K, value: V) { + var existingList = get(key) + if (existingList == null) { + existingList = ArrayList() + this[key] = existingList + } + existingList.add(value) + } +} \ No newline at end of file diff --git a/core/src/com/unciv/models/ruleset/unique/Unique.kt b/core/src/com/unciv/models/ruleset/unique/Unique.kt index 783437d6cd..191b6eda51 100644 --- a/core/src/com/unciv/models/ruleset/unique/Unique.kt +++ b/core/src/com/unciv/models/ruleset/unique/Unique.kt @@ -5,6 +5,9 @@ import com.unciv.logic.city.CityInfo import com.unciv.models.stats.Stats import com.unciv.models.translations.* import com.unciv.logic.civilization.CivilizationInfo +import java.util.* +import kotlin.collections.ArrayList +import kotlin.collections.HashMap class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val sourceObjectName: String? = null) { @@ -107,6 +110,8 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s class UniqueMap: HashMap>() { //todo Once all untyped Uniques are converted, this should be HashMap + // For now, we can have both map types "side by side" each serving their own purpose, + // and gradually this one will be deprecated in favor of the other fun addUnique(unique: Unique) { if (!containsKey(unique.placeholderText)) this[unique.placeholderText] = ArrayList() this[unique.placeholderText]!!.add(unique) @@ -121,3 +126,12 @@ class UniqueMap: HashMap>() { fun getAllUniques() = this.asSequence().flatMap { it.value.asSequence() } } +class UniqueMapTyped: EnumMap>(UniqueType::class.java) { + fun addUnique(unique: Unique) { + if (!containsKey(unique.type)) this[unique.type] = ArrayList() + this[unique.type]!!.add(unique) + } + + fun getUniques(uniqueType: UniqueType): Sequence = + this[uniqueType]?.asSequence() ?: sequenceOf() +} \ No newline at end of file