Add statusMap as lookup-performant alternative to status list - not yet source of truth

This commit is contained in:
yairm210 2024-11-28 21:29:32 +02:00
parent 306907568d
commit df2a56a0e5
5 changed files with 26 additions and 9 deletions

View File

@ -11,8 +11,6 @@ Mods:
Added lake-land edge tiles - by legacymtgsalvationuser69544
Move Capital building function from city to civ - By SeventhM
## 4.14.10
Fixed Flood Plains generation

View File

@ -109,7 +109,13 @@ class MapUnit : IsPartOfGameInfoSerialization {
}
}
@Deprecated("As of 4.14.12 - use statusMap instead (for lookup performance)")
/** This is still the source of truth, currently replicating all statuses to use both the map and the list
so that ongoing games retain their statuses until we're ready to switch over */
var statuses = ArrayList<UnitStatus>()
/** New status container - should NOT serve as source of truth since MP games going
* back and forth between older versions will lose this data! */
var statusMap = HashMap<String, UnitStatus>()
//endregion
//region Transient fields
@ -217,7 +223,8 @@ class MapUnit : IsPartOfGameInfoSerialization {
toReturn.religion = religion
toReturn.religiousStrengthLost = religiousStrengthLost
toReturn.movementMemories = movementMemories.copy()
toReturn.statuses = ArrayList(statuses)
toReturn.statuses = ArrayList(statuses)
toReturn.statusMap = HashMap(statusMap)
toReturn.mostRecentMoveType = mostRecentMoveType
toReturn.attacksSinceTurnStart = ArrayList(attacksSinceTurnStart.map { Vector2(it) })
return toReturn
@ -583,6 +590,9 @@ class MapUnit : IsPartOfGameInfoSerialization {
if (civ.matchesFilter(filter, cache.state, false)) return true
if (nonUnitUniquesMap.hasUnique(filter, cache.state))
if (promotions.promotions.contains(filter)) return true
// Badly optimized, but it's rare that statuses is even non-empty
// Statuses really should be converted to a hashmap
if (getStatus(name) != null) return true
return false
}
}
@ -648,7 +658,11 @@ class MapUnit : IsPartOfGameInfoSerialization {
promotions.setTransients(this)
baseUnit = ruleset.units[name]
?: throw java.lang.Exception("Unit $name is not found!")
for (status in statuses) status.setTransients(this)
for (status in statuses){
status.setTransients(this)
statusMap[status.name] = status
}
updateUniques()
if (action == UnitActionType.Automate.value){
@ -1033,8 +1047,11 @@ class MapUnit : IsPartOfGameInfoSerialization {
}
}
fun getStatus(name:String): UnitStatus? = statuses.firstOrNull { it.name == name }
fun hasStatus(name:String): Boolean = getStatus(name) != null
fun setStatus(name:String, turns:Int){
val existingStatus = statuses.firstOrNull { it.name == name }
val existingStatus = getStatus(name)
if (existingStatus != null){
if (turns > existingStatus.turnsLeft) existingStatus.turnsLeft = turns
return
@ -1045,6 +1062,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
status.turnsLeft = turns
status.setTransients(this)
statuses.add(status)
statusMap[status.name] = status
updateUniques()
for (unique in getTriggeredUniques(UniqueType.TriggerUponStatusGain){ it.params[0] == name })
@ -1053,6 +1071,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
fun removeStatus(name:String){
val wereRemoved = statuses.removeAll { it.name == name }
statusMap.remove(name)
if (!wereRemoved) return
updateUniques()

View File

@ -213,10 +213,10 @@ object Conditionals {
state.relevantUnit?.matchesFilter(conditional.params[0]) == true
UniqueType.ConditionalUnitWithPromotion -> state.relevantUnit != null &&
(state.relevantUnit!!.promotions.promotions.contains(conditional.params[0])
|| state.relevantUnit!!.statuses.any { it.name == conditional.params[0] } )
|| state.relevantUnit!!.hasStatus(conditional.params[0]) )
UniqueType.ConditionalUnitWithoutPromotion -> state.relevantUnit != null &&
!(state.relevantUnit!!.promotions.promotions.contains(conditional.params[0])
|| state.relevantUnit!!.statuses.any { it.name == conditional.params[0] } )
|| state.relevantUnit!!.hasStatus(conditional.params[0]) )
UniqueType.ConditionalAttacking -> state.combatAction == CombatAction.Attack
UniqueType.ConditionalDefending -> state.combatAction == CombatAction.Defend
UniqueType.ConditionalAboveHP -> state.relevantUnit != null && state.relevantUnit!!.health > conditional.params[0].toInt()

View File

@ -982,7 +982,7 @@ object UniqueTriggerActivation {
}
UniqueType.OneTimeUnitLoseStatus -> {
if (unit == null) return null
if (unit.statuses.none { it.name == unique.params[1] }) return null
if (!unit.hasStatus(unique.params[1])) return null
return {
unit.removeStatus(unique.params[1])
true

View File

@ -121,7 +121,7 @@ object UnitActionModifiers {
UniqueType.UnitActionRemovingPromotion -> {
val promotionName = conditional.params[0]
// if has a status, remove that instead - the promotion is 'safe'
if (unit.statuses.any { it.name == promotionName }) {
if (unit.hasStatus(promotionName)) {
unit.removeStatus(promotionName)
} else { // check for real promotion
unit.promotions.removePromotion(promotionName)