mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-22 19:08:48 -04:00
chore(purity)
This commit is contained in:
parent
8e5b36984c
commit
b006673e1c
@ -38,7 +38,7 @@ plugins {
|
||||
// This is *with* gradle 8.2 downloaded according the project specs, no idea what that's about
|
||||
kotlin("multiplatform") version "1.9.24"
|
||||
kotlin("plugin.serialization") version "1.9.24"
|
||||
id("io.github.yairm210.purity-plugin") version "1.1.1" apply(false)
|
||||
id("io.github.yairm210.purity-plugin") version "1.2.2" apply(false)
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
@ -11,6 +11,7 @@ import com.unciv.logic.map.tile.Tile
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.utils.randomWeighted
|
||||
import yairm210.purity.annotations.Readonly
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
@ -241,20 +242,26 @@ class Encampment() : IsPartOfGameInfoSerialization {
|
||||
|
||||
/** Attempts to spawn a barbarian on [position], returns true if successful and false if unsuccessful. */
|
||||
private fun spawnUnit(naval: Boolean): Boolean {
|
||||
updateBarbarianTech()
|
||||
val unitToSpawn = chooseBarbarianUnit(naval) ?: return false // return false if we didn't find a unit
|
||||
val spawnedUnit = gameInfo.tileMap.placeUnitNearTile(position, unitToSpawn, gameInfo.getBarbarianCivilization())
|
||||
return (spawnedUnit != null)
|
||||
}
|
||||
|
||||
private fun chooseBarbarianUnit(naval: Boolean): BaseUnit? {
|
||||
// if we don't make this into a separate list then the retain() will happen on the Tech keys,
|
||||
// which effectively removes those techs from the game and causes all sorts of problems
|
||||
|
||||
private fun updateBarbarianTech(){
|
||||
val barbarianCiv = gameInfo.getBarbarianCivilization()
|
||||
val allResearchedTechs = gameInfo.ruleset.technologies.keys.toMutableList()
|
||||
for (civ in gameInfo.civilizations.filter { !it.isBarbarian && !it.isDefeated() }) {
|
||||
allResearchedTechs.retainAll(civ.tech.techsResearched)
|
||||
}
|
||||
val barbarianCiv = gameInfo.getBarbarianCivilization()
|
||||
barbarianCiv.tech.techsResearched = allResearchedTechs.toHashSet()
|
||||
}
|
||||
|
||||
@Readonly
|
||||
private fun chooseBarbarianUnit(naval: Boolean): BaseUnit? {
|
||||
// if we don't make this into a separate list then the retain() will happen on the Tech keys,
|
||||
// which effectively removes those techs from the game and causes all sorts of problems
|
||||
val barbarianCiv = gameInfo.getBarbarianCivilization()
|
||||
val unitList = gameInfo.ruleset.units.values
|
||||
.filter { it.isMilitary &&
|
||||
!(it.hasUnique(UniqueType.CannotAttack) ||
|
||||
|
@ -97,7 +97,7 @@ class CityStats(val city: City) {
|
||||
//endregion
|
||||
//region Pure Functions
|
||||
|
||||
|
||||
@Readonly
|
||||
private fun getStatsFromTradeRoute(): Stats {
|
||||
val stats = Stats()
|
||||
val capitalForTradeRoutePurposes = city.civ.getCapital()!!
|
||||
@ -201,14 +201,14 @@ class CityStats(val city: City) {
|
||||
}
|
||||
|
||||
|
||||
@Readonly @Suppress("purity") // stats[] *= fails
|
||||
@Readonly
|
||||
private fun getStatsFromUniquesBySource(): StatTreeNode {
|
||||
val sourceToStats = StatTreeNode()
|
||||
|
||||
val cityStateStatsMultipliers = city.civ.getMatchingUniques(UniqueType.BonusStatsFromCityStates).toList()
|
||||
|
||||
fun addUniqueStats(unique: Unique) {
|
||||
val stats = unique.stats.clone()
|
||||
@LocalState val stats = unique.stats.clone()
|
||||
if (unique.sourceObjectType==UniqueTarget.CityState)
|
||||
for (multiplierUnique in cityStateStatsMultipliers)
|
||||
stats[Stat.valueOf(multiplierUnique.params[1])] *= multiplierUnique.params[0].toPercent()
|
||||
|
@ -131,7 +131,7 @@ class TileImprovement : RulesetStatsObject() {
|
||||
}
|
||||
}.filter { it !in cannotFilters }.toMutableSet()
|
||||
|
||||
@LocalState val terrainsCanBeBuiltOnTypes = sequence {
|
||||
val terrainsCanBeBuiltOnTypes = sequence {
|
||||
yieldAll(expandedTerrainsCanBeBuiltOn.asSequence()
|
||||
.mapNotNull { ruleset.terrains[it]?.type })
|
||||
yieldAll(
|
||||
|
@ -2,12 +2,14 @@ package com.unciv.utils
|
||||
|
||||
import com.badlogic.gdx.utils.Array
|
||||
import yairm210.purity.annotations.Pure
|
||||
import yairm210.purity.annotations.Readonly
|
||||
import kotlin.random.Random
|
||||
|
||||
/** Get one random element of a given List.
|
||||
*
|
||||
* The probability for each element is proportional to the value of its corresponding element in the [weights] List.
|
||||
*/
|
||||
@Readonly
|
||||
fun <T> List<T>.randomWeighted(weights: List<Float>, random: Random = Random): T {
|
||||
if (this.isEmpty()) throw NoSuchElementException("Empty list.")
|
||||
if (this.size != weights.size) throw UnsupportedOperationException("Weights size does not match this list size.")
|
||||
@ -28,6 +30,7 @@ fun <T> List<T>.randomWeighted(weights: List<Float>, random: Random = Random): T
|
||||
*
|
||||
* The probability for each element is proportional to the result of [getWeight] (evaluated only once).
|
||||
*/
|
||||
@Readonly
|
||||
fun <T> List<T>.randomWeighted(random: Random = Random, getWeight: (T) -> Float): T =
|
||||
randomWeighted(map(getWeight), random)
|
||||
|
||||
@ -35,6 +38,7 @@ fun <T> List<T>.randomWeighted(random: Random = Random, getWeight: (T) -> Float)
|
||||
*
|
||||
* Solves concurrent modification problems - everyone who had a reference to the previous arrayList can keep using it because it hasn't changed
|
||||
*/
|
||||
@Readonly
|
||||
fun <T> ArrayList<T>.withItem(item: T): ArrayList<T> {
|
||||
val newArrayList = ArrayList(this)
|
||||
newArrayList.add(item)
|
||||
@ -45,6 +49,7 @@ fun <T> ArrayList<T>.withItem(item: T): ArrayList<T> {
|
||||
*
|
||||
* Solves concurrent modification problems - everyone who had a reference to the previous hashSet can keep using it because it hasn't changed
|
||||
*/
|
||||
@Readonly
|
||||
fun <T> HashSet<T>.withItem(item: T): HashSet<T> {
|
||||
val newHashSet = HashSet(this)
|
||||
newHashSet.add(item)
|
||||
@ -55,6 +60,7 @@ fun <T> HashSet<T>.withItem(item: T): HashSet<T> {
|
||||
*
|
||||
* Solves concurrent modification problems - everyone who had a reference to the previous arrayList can keep using it because it hasn't changed
|
||||
*/
|
||||
@Readonly
|
||||
fun <T> ArrayList<T>.withoutItem(item: T): ArrayList<T> {
|
||||
val newArrayList = ArrayList(this)
|
||||
newArrayList.remove(item)
|
||||
@ -65,6 +71,7 @@ fun <T> ArrayList<T>.withoutItem(item: T): ArrayList<T> {
|
||||
*
|
||||
* Solves concurrent modification problems - everyone who had a reference to the previous hashSet can keep using it because it hasn't changed
|
||||
*/
|
||||
@Readonly
|
||||
fun <T> HashSet<T>.withoutItem(item: T): HashSet<T> {
|
||||
val newHashSet = HashSet(this)
|
||||
newHashSet.remove(item)
|
||||
@ -105,6 +112,7 @@ fun <KT, ET> HashMap<KT, HashSet<ET>>.addToMapOfSets(key: KT, element: ET) =
|
||||
getOrPut(key) { hashSetOf() }.add(element)
|
||||
|
||||
/** Simplifies testing whether in a sparse map of sets the [element] exists for [key]. */
|
||||
@Readonly
|
||||
fun <KT, ET> HashMap<KT, HashSet<ET>>.contains(key: KT, element: ET) =
|
||||
get(key)?.contains(element) == true
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user