Performance improvements in both getCivUnits and canPassThrough of tile

Fixed no embarkation & policy pick bug
This commit is contained in:
Yair Morgenstern 2018-11-24 22:48:42 +02:00
parent 6c9297abc2
commit 556c10109d
11 changed files with 48 additions and 19 deletions

View File

@ -21,8 +21,8 @@ android {
applicationId "com.unciv.game"
minSdkVersion 14
targetSdkVersion 26
versionCode 165
versionName "2.10.4"
versionCode 166
versionName "2.10.5"
}
buildTypes {
release {

View File

@ -173,7 +173,7 @@ class Battle(val gameInfo:GameInfo) {
capturedUnit.civInfo.addNotification("An enemy ["+attacker.getName()+"] has captured our ["+defender.getName()+"]",
defender.getTile().position, Color.RED)
capturedUnit.civInfo.units.remove(capturedUnit)
capturedUnit.civInfo.removeUnit(capturedUnit)
capturedUnit.assignOwner(attacker.getCivilization())
}
}

View File

@ -17,6 +17,7 @@ import com.unciv.models.stats.Stats
import com.unciv.ui.utils.getRandom
import com.unciv.ui.utils.tr
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.math.max
import kotlin.math.pow
@ -25,7 +26,12 @@ import kotlin.math.roundToInt
class CivilizationInfo {
@Transient lateinit var gameInfo: GameInfo
@Transient var units=ArrayList<MapUnit>()
/**
* never add or remove from here directly, could cause comodification problems.
* Instead, create a copy list with the change, and replace this list.
* The other solution, casting toList() every "get", has a performance cost
*/
@Transient private var units=ArrayList<MapUnit>()
@Transient var viewableTiles = HashSet<TileInfo>()
var gold = 0
@ -200,8 +206,18 @@ class CivilizationInfo {
fun getBuildingUniques(): List<String> = cities.flatMap { it.getBuildingUniques()}.distinct()
fun getCivUnits(): List<MapUnit> {
return units.toList() // to avoid comodification problems (ie concurrency again...)
fun getCivUnits(): List<MapUnit> = units
fun addUnit(mapUnit: MapUnit){
val newList = ArrayList(units)
newList.add(mapUnit)
units=newList
}
fun removeUnit(mapUnit: MapUnit){
val newList = ArrayList(units)
newList.remove(mapUnit)
units=newList
}
@ -241,6 +257,7 @@ class CivilizationInfo {
fun isDefeated()= cities.isEmpty() && !getCivUnits().any{it.name=="Settler"}
fun getEra(): TechEra {
val maxEraOfTech = tech.researchedTechnologies
.asSequence()
.map { it.era() }
.max()
if(maxEraOfTech!=null) return maxEraOfTech
@ -265,6 +282,7 @@ class CivilizationInfo {
policies.numberOfAdoptedPolicies = policies.adoptedPolicies.count { !it.endsWith("Complete") }
tech.civInfo = this
tech.setTransients()
diplomacy.values.forEach { it.civInfo=this}

View File

@ -33,9 +33,10 @@ class PolicyManager {
fun isAdopted(policyName: String): Boolean = adoptedPolicies.contains(policyName)
fun isAdoptable(policy: Policy): Boolean {
return (!policy.name.endsWith("Complete")
&& getAdoptedPolicies().containsAll(policy.requires!!)
&& policy.getBranch().era <= civInfo.getEra())
if (policy.name.endsWith("Complete")) return false
if (!getAdoptedPolicies().containsAll(policy.requires!!)) return false
if (policy.getBranch().era > civInfo.getEra()) return false
return true
}
fun canAdoptPolicy(): Boolean = freePolicies > 0 || storedCulture >= getCultureNeededForNextPolicy()

View File

@ -113,19 +113,20 @@ class MapUnit {
fun canPassThrough(tile: TileInfo):Boolean{
val tileOwner = tile.getOwner()
val isOcean = tile.baseTerrain == "Ocean" // profiling showed that 3.5% of all nextTurn time is taken up by string equals in this function =|
if(tile.isWater() && type.isLandUnit()){
val techUniques = civInfo.tech.getUniques()
if(!techUniques.contains("Enables embarkation for land units"))
return false
if(tile.baseTerrain == "Ocean" && !techUniques.contains("Enables embarked units to enter ocean tiles"))
if(isOcean && !techUniques.contains("Enables embarked units to enter ocean tiles"))
return false
}
if(tile.isLand() && type.isWaterUnit())
return false
if(tile.baseTerrain=="Ocean" && baseUnit.uniques.contains("Cannot enter ocean tiles until Astronomy")
if(isOcean && baseUnit.uniques.contains("Cannot enter ocean tiles until Astronomy")
&& !civInfo.tech.isResearched("Astronomy"))
return false
if(tile.baseTerrain=="Ocean" && baseUnit.uniques.contains("Cannot enter ocean tiles")) return false
if(isOcean && baseUnit.uniques.contains("Cannot enter ocean tiles")) return false
if(tileOwner!=null && tileOwner.civName!=owner
&& (tile.isCityCenter() || !civInfo.canEnterTiles(tileOwner))) return false
return true
@ -299,7 +300,7 @@ class MapUnit {
fun destroy(){
removeFromTile()
civInfo.units.remove(this)
civInfo.removeUnit(this)
}
fun removeFromTile(){
@ -360,7 +361,7 @@ class MapUnit {
fun assignOwner(civInfo:CivilizationInfo){
owner=civInfo.civName
this.civInfo=civInfo
civInfo.units.add(this)
civInfo.addUnit(this)
}
//endregion
}

View File

@ -21,8 +21,10 @@ class PerlinNoiseRandomMapGenerator:SeedRandomMapGenerator(){
divideIntoAreas(6, 0f, map)
val mapToReturn = HashMap<String, TileInfo>()
for(tile in map)
for(tile in map) {
tile.value.setTransients()
mapToReturn[tile.key.toString()] = tile.value
}
setWaterTiles(mapToReturn)
for(tile in mapToReturn.values) randomizeTile(tile)

View File

@ -82,7 +82,7 @@ class TileMap {
unit.putInTile(unitToPlaceTile)
unit.currentMovement = unit.getMaxMovement().toFloat()
}
else civInfo.units.remove(unit) // since we added it to the civ units in the previous assignOwner
else civInfo.removeUnit(unit) // since we added it to the civ units in the previous assignOwner
return unit
}

View File

@ -111,12 +111,13 @@ class Building : NamedStats(), IConstruction{
return stringBuilder.toString().trim()
}
val cultureBuildings = hashSetOf("Monument", "Temple", "Monastery")
fun getStats(adoptedPolicies: HashSet<String>): Stats {
val stats = this.clone()
if (adoptedPolicies.contains("Organized Religion") && hashSetOf("Monument", "Temple", "Monastery").contains(name))
if (adoptedPolicies.contains("Organized Religion") && cultureBuildings.contains(name))
stats.happiness += 1
if (adoptedPolicies.contains("Free Religion") && hashSetOf("Monument", "Temple", "Monastery").contains(name))
if (adoptedPolicies.contains("Free Religion") && cultureBuildings.contains(name))
stats.culture += 1f
if (adoptedPolicies.contains("Entrepreneurship") && hashSetOf("Mint", "Market", "Bank", "Stock Market").contains(name))

View File

@ -13,5 +13,9 @@ open class Policy : INamed {
fun getBranch():PolicyBranch{
return GameBasics.PolicyBranches[branch]!!
}
override fun toString(): String {
return name
}
}

View File

@ -110,6 +110,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
val happinessTable = Table(skin)
happinessTable.defaults().pad(5f)
happinessTable.add(Label("Happiness".tr(), skin).setFontSize(24)).colspan(2).row()
happinessTable.addSeparator()
for (entry in civInfo.getHappinessForNextTurn()) {
happinessTable.add(entry.key.tr())
happinessTable.add(entry.value.toString()).row()
@ -124,6 +125,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){
val goldTable = Table(skin)
goldTable.defaults().pad(5f)
goldTable.add(Label("Gold".tr(), skin).setFontSize(24)).colspan(2).row()
goldTable.addSeparator()
var total=0f
for (entry in civInfo.getStatMapForNextTurn()) {
if(entry.value.gold==0f) continue

View File

@ -39,7 +39,7 @@ class PolicyPickerScreen(internal val civInfo: CivilizationInfo) : PickerScreen(
topTable.row().pad(30f)
for (branch in GameBasics.PolicyBranches.values) {
if (branch.name == "Commerce") topTable.row()
if (branch.name == "Commerce") topTable.addSeparator()
val branchGroup = Table()
branchGroup.row().pad(20f)
branchGroup.add(getPolicyButton(branch, false)).row()