Added new type-based uniqueMap, which will be the base of the "cached uniques revolution", and added a relatively benign use in unit uniques (#5619)

This commit is contained in:
Yair Morgenstern
2021-10-31 21:56:41 +02:00
committed by GitHub
parent 53a0c9b248
commit 52933ca58b
3 changed files with 44 additions and 6 deletions

View File

@ -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<Unique>()
@Transient
private var tempUniquesMap = UniqueMapTyped()
fun getUniques(): ArrayList<Unique> = tempUniques
fun getMatchingUniques(placeholderText: String): Sequence<Unique> =
@ -212,8 +217,10 @@ 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)
@ -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() }
}

View File

@ -1,6 +1,8 @@
package com.unciv.models
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.LinkedHashMap
open class Counter<K> : LinkedHashMap<K, Int>() {
@ -40,3 +42,13 @@ open class Counter<K> : LinkedHashMap<K, Int>() {
}
}
class MultiHashMap<K, V> : LinkedHashMap<K, ArrayList<V>>() {
fun add(key: K, value: V) {
var existingList = get(key)
if (existingList == null) {
existingList = ArrayList()
this[key] = existingList
}
existingList.add(value)
}
}

View File

@ -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<String, ArrayList<Unique>>() {
//todo Once all untyped Uniques are converted, this should be HashMap<UniqueType, *>
// 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<String, ArrayList<Unique>>() {
fun getAllUniques() = this.asSequence().flatMap { it.value.asSequence() }
}
class UniqueMapTyped: EnumMap<UniqueType, ArrayList<Unique>>(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<Unique> =
this[uniqueType]?.asSequence() ?: sequenceOf()
}