mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-18 03:38:55 +07:00
Performance: Added transient builtBuildingObjects list in cittyConstructions, so we won't have to get the list every time we want to calculate, well, loads of stuff
This commit is contained in:
@ -143,14 +143,14 @@ class Battle(val gameInfo:GameInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(city.cityConstructions.isBuilt("Palace")){
|
if(city.cityConstructions.isBuilt("Palace")){
|
||||||
city.cityConstructions.builtBuildings.remove("Palace")
|
city.cityConstructions.removeBuilding("Palace")
|
||||||
if(enemyCiv.isDefeated()) {
|
if(enemyCiv.isDefeated()) {
|
||||||
gameInfo.getPlayerCivilization()
|
gameInfo.getPlayerCivilization()
|
||||||
.addNotification("The civilization of [${enemyCiv.civName}] has been destroyed!", null, Color.RED)
|
.addNotification("The civilization of [${enemyCiv.civName}] has been destroyed!", null, Color.RED)
|
||||||
enemyCiv.getCivUnits().forEach { it.destroy() }
|
enemyCiv.getCivUnits().forEach { it.destroy() }
|
||||||
}
|
}
|
||||||
else if(enemyCiv.cities.isNotEmpty()){
|
else if(enemyCiv.cities.isNotEmpty()){
|
||||||
enemyCiv.cities.first().cityConstructions.builtBuildings.add("Palace") // relocate palace
|
enemyCiv.cities.first().cityConstructions.addBuilding("Palace") // relocate palace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,15 @@ import com.unciv.models.gamebasics.Building
|
|||||||
import com.unciv.models.gamebasics.GameBasics
|
import com.unciv.models.gamebasics.GameBasics
|
||||||
import com.unciv.models.stats.Stats
|
import com.unciv.models.stats.Stats
|
||||||
import com.unciv.ui.utils.tr
|
import com.unciv.ui.utils.tr
|
||||||
|
import com.unciv.ui.utils.withItem
|
||||||
|
import com.unciv.ui.utils.withoutItem
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
|
||||||
class CityConstructions {
|
class CityConstructions {
|
||||||
@Transient
|
@Transient lateinit var cityInfo: CityInfo
|
||||||
lateinit var cityInfo: CityInfo
|
@Transient private var builtBuildingObjects=ArrayList<Building>()
|
||||||
|
|
||||||
var builtBuildings = ArrayList<String>()
|
var builtBuildings = ArrayList<String>()
|
||||||
private val inProgressConstructions = HashMap<String, Int>()
|
private val inProgressConstructions = HashMap<String, Int>()
|
||||||
@ -89,7 +92,7 @@ class CityConstructions {
|
|||||||
throw NotBuildingOrUnitException("$constructionName is not a building or a unit!")
|
throw NotBuildingOrUnitException("$constructionName is not a building or a unit!")
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getBuiltBuildings(): List<Building> = builtBuildings.toList().map { GameBasics.Buildings[it]!! } // toList os to avoid concurrency problems
|
internal fun getBuiltBuildings(): List<Building> = builtBuildingObjects // toList os to avoid concurrency problems
|
||||||
|
|
||||||
fun containsBuildingOrEquivalent(building: String): Boolean =
|
fun containsBuildingOrEquivalent(building: String): Boolean =
|
||||||
isBuilt(building) || getBuiltBuildings().any{it.replaces==building}
|
isBuilt(building) || getBuiltBuildings().any{it.replaces==building}
|
||||||
@ -113,9 +116,13 @@ class CityConstructions {
|
|||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
//region state changing functions
|
//region state changing functions
|
||||||
fun addConstruction(constructionToAdd: Int) {
|
fun setTransients(){
|
||||||
|
builtBuildingObjects = ArrayList(builtBuildings.map { GameBasics.Buildings[it]!! })
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addProduction(productionToAdd: Int) {
|
||||||
if (!inProgressConstructions.containsKey(currentConstruction)) inProgressConstructions[currentConstruction] = 0
|
if (!inProgressConstructions.containsKey(currentConstruction)) inProgressConstructions[currentConstruction] = 0
|
||||||
inProgressConstructions[currentConstruction] = inProgressConstructions[currentConstruction]!! + constructionToAdd
|
inProgressConstructions[currentConstruction] = inProgressConstructions[currentConstruction]!! + productionToAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
fun nextTurn(cityStats: Stats) {
|
fun nextTurn(cityStats: Stats) {
|
||||||
@ -136,26 +143,41 @@ class CityConstructions {
|
|||||||
var productionToAdd = cityStats.production
|
var productionToAdd = cityStats.production
|
||||||
if(!cityInfo.civInfo.isPlayerCivilization())
|
if(!cityInfo.civInfo.isPlayerCivilization())
|
||||||
productionToAdd *= cityInfo.civInfo.gameInfo.getPlayerCivilization().getDifficulty().aiConstructionModifier
|
productionToAdd *= cityInfo.civInfo.gameInfo.getPlayerCivilization().getDifficulty().aiConstructionModifier
|
||||||
addConstruction(Math.round(cityStats.production))
|
addProduction(Math.round(cityStats.production))
|
||||||
val productionCost = construction.getProductionCost(cityInfo.civInfo.policies.adoptedPolicies)
|
val productionCost = construction.getProductionCost(cityInfo.civInfo.policies.adoptedPolicies)
|
||||||
if (inProgressConstructions[currentConstruction]!! >= productionCost) {
|
if (inProgressConstructions[currentConstruction]!! >= productionCost) {
|
||||||
construction.postBuildEvent(this)
|
constructionComplete(construction)
|
||||||
inProgressConstructions.remove(currentConstruction)
|
|
||||||
|
|
||||||
if(construction is Building && construction.isWonder && construction.requiredBuildingInAllCities==null) {
|
|
||||||
val playerCiv = cityInfo.civInfo.gameInfo.getPlayerCivilization()
|
|
||||||
val builtLocation = if(playerCiv.exploredTiles.contains(cityInfo.location)) cityInfo.name else "a faraway land"
|
|
||||||
playerCiv.addNotification("[$currentConstruction] has been built in [$builtLocation]", cityInfo.location, Color.BROWN)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cityInfo.civInfo.addNotification("[$currentConstruction] has been built in [" + cityInfo.name+"]", cityInfo.location, Color.BROWN)
|
|
||||||
|
|
||||||
currentConstruction=""
|
|
||||||
Automation().chooseNextConstruction(this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun constructionComplete(construction: IConstruction) {
|
||||||
|
construction.postBuildEvent(this)
|
||||||
|
inProgressConstructions.remove(currentConstruction)
|
||||||
|
|
||||||
|
if (construction is Building && construction.isWonder && construction.requiredBuildingInAllCities == null) {
|
||||||
|
val playerCiv = cityInfo.civInfo.gameInfo.getPlayerCivilization()
|
||||||
|
val builtLocation = if (playerCiv.exploredTiles.contains(cityInfo.location)) cityInfo.name else "a faraway land"
|
||||||
|
playerCiv.addNotification("[$currentConstruction] has been built in [$builtLocation]", cityInfo.location, Color.BROWN)
|
||||||
|
} else
|
||||||
|
cityInfo.civInfo.addNotification("[$currentConstruction] has been built in [" + cityInfo.name + "]", cityInfo.location, Color.BROWN)
|
||||||
|
|
||||||
|
currentConstruction = ""
|
||||||
|
Automation().chooseNextConstruction(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addBuilding(buildingName:String){
|
||||||
|
val buildingObject = GameBasics.Buildings[buildingName]!!
|
||||||
|
builtBuildingObjects = builtBuildingObjects.withItem(buildingObject)
|
||||||
|
builtBuildings.add(buildingName)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeBuilding(buildingName:String){
|
||||||
|
val buildingObject = GameBasics.Buildings[buildingName]!!
|
||||||
|
builtBuildingObjects = builtBuildingObjects.withoutItem(buildingObject)
|
||||||
|
builtBuildings.remove(buildingName)
|
||||||
|
}
|
||||||
|
|
||||||
fun purchaseBuilding(buildingName: String) {
|
fun purchaseBuilding(buildingName: String) {
|
||||||
cityInfo.civInfo.gold -= getConstruction(buildingName).getGoldCost(cityInfo.civInfo.policies.adoptedPolicies)
|
cityInfo.civInfo.gold -= getConstruction(buildingName).getGoldCost(cityInfo.civInfo.policies.adoptedPolicies)
|
||||||
getConstruction(buildingName).postBuildEvent(this)
|
getConstruction(buildingName).postBuildEvent(this)
|
||||||
|
@ -54,7 +54,7 @@ class CityInfo {
|
|||||||
civInfo.addNotification("[$name] has been founded!", cityLocation, Color.PURPLE)
|
civInfo.addNotification("[$name] has been founded!", cityLocation, Color.PURPLE)
|
||||||
if (civInfo.policies.isAdopted("Legalism") && civInfo.cities.size <= 4) cityConstructions.addCultureBuilding()
|
if (civInfo.policies.isAdopted("Legalism") && civInfo.cities.size <= 4) cityConstructions.addCultureBuilding()
|
||||||
if (civInfo.cities.size == 1) {
|
if (civInfo.cities.size == 1) {
|
||||||
cityConstructions.builtBuildings.add("Palace")
|
cityConstructions.addBuilding("Palace")
|
||||||
cityConstructions.currentConstruction = "Worker" // Default for first city only!
|
cityConstructions.currentConstruction = "Worker" // Default for first city only!
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ class CityInfo {
|
|||||||
expansion.setTransients()
|
expansion.setTransients()
|
||||||
cityStats.cityInfo = this
|
cityStats.cityInfo = this
|
||||||
cityConstructions.cityInfo = this
|
cityConstructions.cityInfo = this
|
||||||
|
cityConstructions.setTransients()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun endTurn() {
|
fun endTurn() {
|
||||||
@ -178,7 +178,7 @@ class CityInfo {
|
|||||||
civInfo.addNotification("[$name] has been razed to the ground!",location, Color.RED)
|
civInfo.addNotification("[$name] has been razed to the ground!",location, Color.RED)
|
||||||
destroyCity()
|
destroyCity()
|
||||||
if(isCapital() && civInfo.cities.isNotEmpty()) // Yes, we actually razed the capital. Some people do this.
|
if(isCapital() && civInfo.cities.isNotEmpty()) // Yes, we actually razed the capital. Some people do this.
|
||||||
civInfo.cities.first().cityConstructions.builtBuildings.add("Palace")
|
civInfo.cities.first().cityConstructions.addBuilding("Palace")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else population.nextTurn(stats.food)
|
else population.nextTurn(stats.food)
|
||||||
@ -206,7 +206,7 @@ class CityInfo {
|
|||||||
|
|
||||||
// Remove all national wonders
|
// Remove all national wonders
|
||||||
for(building in cityConstructions.getBuiltBuildings().filter { it.requiredBuildingInAllCities!=null })
|
for(building in cityConstructions.getBuiltBuildings().filter { it.requiredBuildingInAllCities!=null })
|
||||||
cityConstructions.builtBuildings.remove(building.name)
|
cityConstructions.removeBuilding(building.name)
|
||||||
isBeingRazed=false
|
isBeingRazed=false
|
||||||
}
|
}
|
||||||
//endregion
|
//endregion
|
||||||
|
@ -210,7 +210,7 @@ class CityStats {
|
|||||||
stats.production += 5f
|
stats.production += 5f
|
||||||
if(policies.contains("Warrior Code") && currentConstruction is BaseUnit && currentConstruction.unitType.isMelee())
|
if(policies.contains("Warrior Code") && currentConstruction is BaseUnit && currentConstruction.unitType.isMelee())
|
||||||
stats.production += 20
|
stats.production += 20
|
||||||
if (policies.contains("Reformation") && cityConstructions.builtBuildings.any { GameBasics.Buildings[it]!!.isWonder })
|
if (policies.contains("Reformation") && cityConstructions.getBuiltBuildings().any { it.isWonder })
|
||||||
stats.culture += 33f
|
stats.culture += 33f
|
||||||
if (policies.contains("Commerce") && cityInfo.isCapital())
|
if (policies.contains("Commerce") && cityInfo.isCapital())
|
||||||
stats.gold += 25f
|
stats.gold += 25f
|
||||||
|
@ -6,6 +6,7 @@ import com.unciv.models.gamebasics.GameBasics
|
|||||||
import com.unciv.models.gamebasics.tech.Technology
|
import com.unciv.models.gamebasics.tech.Technology
|
||||||
import com.unciv.models.gamebasics.unit.BaseUnit
|
import com.unciv.models.gamebasics.unit.BaseUnit
|
||||||
import com.unciv.ui.utils.tr
|
import com.unciv.ui.utils.tr
|
||||||
|
import com.unciv.ui.utils.withItem
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class TechManager {
|
class TechManager {
|
||||||
@ -77,9 +78,7 @@ class TechManager {
|
|||||||
techsResearched.add(currentTechnology)
|
techsResearched.add(currentTechnology)
|
||||||
|
|
||||||
// this is to avoid concurrent modification problems
|
// this is to avoid concurrent modification problems
|
||||||
val newResearchedTechnologies = ArrayList(researchedTechnologies)
|
researchedTechnologies = researchedTechnologies.withItem(GameBasics.Technologies[currentTechnology]!!)
|
||||||
newResearchedTechnologies.add(GameBasics.Technologies[currentTechnology]!!)
|
|
||||||
researchedTechnologies = newResearchedTechnologies
|
|
||||||
|
|
||||||
civInfo.addNotification("Research of [$currentTechnology] has completed!", null, Color.BLUE)
|
civInfo.addNotification("Research of [$currentTechnology] has completed!", null, Color.BLUE)
|
||||||
|
|
||||||
|
@ -214,10 +214,10 @@ class Building : NamedStats(), IConstruction{
|
|||||||
civInfo.scienceVictory.currentParts.add(name, 1)
|
civInfo.scienceVictory.currentParts.add(name, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
construction.builtBuildings.add(name)
|
construction.addBuilding(name)
|
||||||
|
|
||||||
if (providesFreeBuilding != null && !construction.builtBuildings.contains(providesFreeBuilding!!))
|
if (providesFreeBuilding != null && !construction.builtBuildings.contains(providesFreeBuilding!!))
|
||||||
construction.builtBuildings.add(providesFreeBuilding!!)
|
construction.addBuilding(providesFreeBuilding!!)
|
||||||
when {
|
when {
|
||||||
"Empire enters golden age" in uniques-> civInfo.goldenAges.enterGoldenAge()
|
"Empire enters golden age" in uniques-> civInfo.goldenAges.enterGoldenAge()
|
||||||
"Free Great Artist Appears" in uniques-> civInfo.addGreatPerson("Great Artist")
|
"Free Great Artist Appears" in uniques-> civInfo.addGreatPerson("Great Artist")
|
||||||
|
@ -203,4 +203,22 @@ fun Table.addSeparator(): Cell<Image> {
|
|||||||
val cell = add(image).colspan(columns).fill()
|
val cell = add(image).colspan(columns).fill()
|
||||||
row()
|
row()
|
||||||
return cell
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves concurrent modification problems - everyone who had a reference to the previous arrayList can keep using it because it hasn't changed
|
||||||
|
*/
|
||||||
|
fun <T> ArrayList<T>.withItem(item:T): ArrayList<T> {
|
||||||
|
val newArrayList = ArrayList(this)
|
||||||
|
newArrayList.add(item)
|
||||||
|
return newArrayList
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves concurrent modification problems - everyone who had a reference to the previous arrayList can keep using it because it hasn't changed
|
||||||
|
*/
|
||||||
|
fun <T> ArrayList<T>.withoutItem(item:T): ArrayList<T> {
|
||||||
|
val newArrayList = ArrayList(this)
|
||||||
|
newArrayList.remove(item)
|
||||||
|
return newArrayList
|
||||||
}
|
}
|
@ -168,7 +168,7 @@ class UnitActions {
|
|||||||
if (unit.name == "Great Engineer" && !unit.isEmbarked()) {
|
if (unit.name == "Great Engineer" && !unit.isEmbarked()) {
|
||||||
actionList += UnitAction( "Hurry Wonder",
|
actionList += UnitAction( "Hurry Wonder",
|
||||||
{
|
{
|
||||||
tile.getCity()!!.cityConstructions.addConstruction(300 + 30 * tile.getCity()!!.population.population) //http://civilization.wikia.com/wiki/Great_engineer_(Civ5)
|
tile.getCity()!!.cityConstructions.addProduction(300 + 30 * tile.getCity()!!.population.population) //http://civilization.wikia.com/wiki/Great_engineer_(Civ5)
|
||||||
unit.destroy()
|
unit.destroy()
|
||||||
},
|
},
|
||||||
unit.currentMovement != 0f &&
|
unit.currentMovement != 0f &&
|
||||||
|
Reference in New Issue
Block a user