Multiple performance improvements, especially for memory - should mitigate OutOfMemory exceptions on older phones

This commit is contained in:
Yair Morgenstern
2019-07-23 00:20:00 +03:00
parent 78b9908479
commit db0543468b
23 changed files with 71 additions and 53 deletions

View File

@ -185,7 +185,7 @@ class BattleDamage{
private fun getTileSpecificModifiers(unit: MapUnitCombatant, tile: TileInfo): HashMap<String,Float> { private fun getTileSpecificModifiers(unit: MapUnitCombatant, tile: TileInfo): HashMap<String,Float> {
val modifiers = HashMap<String,Float>() val modifiers = HashMap<String,Float>()
val isFriendlyTerritory = tile.getOwner()!=null && !unit.getCivInfo().isAtWarWith(tile.getOwner()!!) val isFriendlyTerritory = tile.getOwner()!=null && !unit.getCivInfo().isAtWarWith(tile.getOwner()!!)
if(isFriendlyTerritory && unit.getCivInfo().getBuildingUniques().contains("+15% combat strength for units fighting in friendly territory")) if(isFriendlyTerritory && unit.getCivInfo().containsBuildingUnique("+15% combat strength for units fighting in friendly territory"))
modifiers["Himeji Castle"] = 0.15f modifiers["Himeji Castle"] = 0.15f
if(!isFriendlyTerritory && unit.unit.hasUnique("+20% bonus outside friendly territory")) if(!isFriendlyTerritory && unit.unit.hasUnique("+20% bonus outside friendly territory"))
modifiers["Foreign Land"] = 0.2f modifiers["Foreign Land"] = 0.2f

View File

@ -53,7 +53,7 @@ class CityCombatant(val city: CityInfo) : ICombatant {
strength += cityTile.militaryUnit!!.baseUnit().strength * cityTile.militaryUnit!!.health/100f strength += cityTile.militaryUnit!!.baseUnit().strength * cityTile.militaryUnit!!.health/100f
var buildingsStrength = city.cityConstructions.getBuiltBuildings().sumBy{ it.cityStrength }.toFloat() var buildingsStrength = city.cityConstructions.getBuiltBuildings().sumBy{ it.cityStrength }.toFloat()
if(getCivInfo().getBuildingUniques().contains("Defensive buildings in all cities are 25% more effective")) if(getCivInfo().containsBuildingUnique("Defensive buildings in all cities are 25% more effective"))
buildingsStrength*=1.25f buildingsStrength*=1.25f
strength += buildingsStrength strength += buildingsStrength

View File

@ -102,7 +102,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> = builtBuildingObjects // toList os to avoid concurrency problems internal fun getBuiltBuildings(): List<Building> = builtBuildingObjects
fun containsBuildingOrEquivalent(building: String): Boolean = fun containsBuildingOrEquivalent(building: String): Boolean =
isBuilt(building) || getBuiltBuildings().any{it.replaces==building} isBuilt(building) || getBuiltBuildings().any{it.replaces==building}

View File

@ -27,9 +27,9 @@ class CityExpansionManager {
fun getCultureToNextTile(): Int { fun getCultureToNextTile(): Int {
val numTilesClaimed = cityInfo.tiles.size - 7 val numTilesClaimed = cityInfo.tiles.size - 7
var cultureToNextTile = 6 * Math.pow(numTilesClaimed + 1.4813, 1.3) var cultureToNextTile = 6 * Math.pow(numTilesClaimed + 1.4813, 1.3)
if (cityInfo.civInfo.getBuildingUniques().contains("Cost of acquiring new tiles reduced by 25%")) if (cityInfo.civInfo.containsBuildingUnique("Cost of acquiring new tiles reduced by 25%"))
cultureToNextTile *= 0.75 //Speciality of Angkor Wat cultureToNextTile *= 0.75 //Speciality of Angkor Wat
if(cityInfo.getBuildingUniques().contains("Culture and Gold costs of acquiring new tiles reduced by 25% in this city")) if(cityInfo.containsBuildingUnique("Culture and Gold costs of acquiring new tiles reduced by 25% in this city"))
cultureToNextTile *= 0.75 // Specialty of Krepost cultureToNextTile *= 0.75 // Specialty of Krepost
if (cityInfo.civInfo.policies.isAdopted("Tradition")) cultureToNextTile *= 0.75 if (cityInfo.civInfo.policies.isAdopted("Tradition")) cultureToNextTile *= 0.75
return Math.round(cultureToNextTile).toInt() return Math.round(cultureToNextTile).toInt()
@ -49,9 +49,9 @@ class CityExpansionManager {
val distanceFromCenter = tileInfo.arialDistanceTo(cityInfo.getCenterTile()) val distanceFromCenter = tileInfo.arialDistanceTo(cityInfo.getCenterTile())
var cost = baseCost * (distanceFromCenter-1) + numTilesClaimed*5.0 var cost = baseCost * (distanceFromCenter-1) + numTilesClaimed*5.0
if (cityInfo.civInfo.getBuildingUniques().contains("Cost of acquiring new tiles reduced by 25%")) if (cityInfo.civInfo.containsBuildingUnique("Cost of acquiring new tiles reduced by 25%"))
cost *= 0.75 //Speciality of Angkor Wat cost *= 0.75 //Speciality of Angkor Wat
if(cityInfo.getBuildingUniques().contains("Culture and Gold costs of acquiring new tiles reduced by 25% in this city")) if(cityInfo.containsBuildingUnique("Culture and Gold costs of acquiring new tiles reduced by 25% in this city"))
cost *= 0.75 // Specialty of Krepost cost *= 0.75 // Specialty of Krepost
if(cityInfo.civInfo.getNation().unique=="All land military units have +1 sight, 50% discount when purchasing tiles") if(cityInfo.civInfo.getNation().unique=="All land military units have +1 sight, 50% discount when purchasing tiles")

View File

@ -123,7 +123,7 @@ class CityInfo {
amountToAdd *= 2 amountToAdd *= 2
} }
if(resource.resourceType == ResourceType.Luxury if(resource.resourceType == ResourceType.Luxury
&& getBuildingUniques().contains("Provides 1 extra copy of each improved luxury resource near this City")) && containsBuildingUnique("Provides 1 extra copy of each improved luxury resource near this City"))
amountToAdd*=2 amountToAdd*=2
cityResources.add(resource, amountToAdd, "Tiles") cityResources.add(resource, amountToAdd, "Tiles")
@ -140,6 +140,7 @@ class CityInfo {
} }
fun getBuildingUniques(): List<String> = cityConstructions.getBuiltBuildings().flatMap { it.uniques } fun getBuildingUniques(): List<String> = cityConstructions.getBuiltBuildings().flatMap { it.uniques }
fun containsBuildingUnique(unique:String) = cityConstructions.getBuiltBuildings().any { it.uniques.contains(unique) }
fun getGreatPersonMap():HashMap<String,Stats>{ fun getGreatPersonMap():HashMap<String,Stats>{
val stats = HashMap<String,Stats>() val stats = HashMap<String,Stats>()
@ -159,7 +160,7 @@ class CityInfo {
if (civInfo.policies.isAdopted("Entrepreneurship")) if (civInfo.policies.isAdopted("Entrepreneurship"))
entry.value.gold *= 1.25f entry.value.gold *= 1.25f
if (civInfo.getBuildingUniques().contains("+33% great person generation in all cities")) if (civInfo.containsBuildingUnique("+33% great person generation in all cities"))
stats[entry.key] = stats[entry.key]!!.times(1.33f) stats[entry.key] = stats[entry.key]!!.times(1.33f)
if (civInfo.policies.isAdopted("Freedom")) if (civInfo.policies.isAdopted("Freedom"))
stats[entry.key] = stats[entry.key]!!.times(1.25f) stats[entry.key] = stats[entry.key]!!.times(1.25f)

View File

@ -39,7 +39,7 @@ class CityStats {
var goldFromTradeRoute = civInfo.getCapital().population.population * 0.15 + cityInfo.population.population * 1.1 - 1 // Calculated by http://civilization.wikia.com/wiki/Trade_route_(Civ5) var goldFromTradeRoute = civInfo.getCapital().population.population * 0.15 + cityInfo.population.population * 1.1 - 1 // Calculated by http://civilization.wikia.com/wiki/Trade_route_(Civ5)
if(civInfo.getNation().unique=="+1 Gold from each Trade Route, Oil resources provide double quantity") goldFromTradeRoute += 1 if(civInfo.getNation().unique=="+1 Gold from each Trade Route, Oil resources provide double quantity") goldFromTradeRoute += 1
if (civInfo.policies.isAdopted("Trade Unions")) goldFromTradeRoute += 2 if (civInfo.policies.isAdopted("Trade Unions")) goldFromTradeRoute += 2
if (civInfo.getBuildingUniques().contains("Gold from all trade routes +25%")) goldFromTradeRoute *= 1.25 // Machu Pichu speciality if (civInfo.containsBuildingUnique("Gold from all trade routes +25%")) goldFromTradeRoute *= 1.25 // Machu Pichu speciality
stats.gold += goldFromTradeRoute.toFloat() stats.gold += goldFromTradeRoute.toFloat()
} }
return stats return stats
@ -52,7 +52,7 @@ class CityStats {
"Gold" -> stats.gold += production / 4 "Gold" -> stats.gold += production / 4
"Science" -> { "Science" -> {
var scienceProduced = production / 4 var scienceProduced = production / 4
if (cityInfo.civInfo.getBuildingUniques().contains("Production to science conversion in cities increased by 33%")) if (cityInfo.civInfo.containsBuildingUnique("Production to science conversion in cities increased by 33%"))
scienceProduced *= 1.33f scienceProduced *= 1.33f
if (cityInfo.civInfo.policies.isAdopted("Rationalism")) scienceProduced *= 1.33f if (cityInfo.civInfo.policies.isAdopted("Rationalism")) scienceProduced *= 1.33f
stats.science += scienceProduced stats.science += scienceProduced
@ -182,7 +182,7 @@ class CityStats {
var unhappinessFromCitizens = cityInfo.population.population.toFloat() var unhappinessFromCitizens = cityInfo.population.population.toFloat()
if (civInfo.policies.isAdopted("Democracy")) if (civInfo.policies.isAdopted("Democracy"))
unhappinessFromCitizens -= cityInfo.population.getNumberOfSpecialists() * 0.5f unhappinessFromCitizens -= cityInfo.population.getNumberOfSpecialists() * 0.5f
if (civInfo.getBuildingUniques().contains("Unhappiness from population decreased by 10%")) if (civInfo.containsBuildingUnique("Unhappiness from population decreased by 10%"))
unhappinessFromCitizens *= 0.9f unhappinessFromCitizens *= 0.9f
if (civInfo.policies.isAdopted("Meritocracy")) if (civInfo.policies.isAdopted("Meritocracy"))
unhappinessFromCitizens *= 0.95f unhappinessFromCitizens *= 0.95f
@ -206,7 +206,7 @@ class CityStats {
val happinessFromBuildings = cityInfo.cityConstructions.getStats().happiness.toInt().toFloat() val happinessFromBuildings = cityInfo.cityConstructions.getStats().happiness.toInt().toFloat()
newHappinessList ["Buildings"] = happinessFromBuildings newHappinessList ["Buildings"] = happinessFromBuildings
if(civInfo.getBuildingUniques().contains("+1 happiness in each city")) if(civInfo.containsBuildingUnique("+1 happiness in each city"))
newHappinessList["Wonders"] = 1f newHappinessList["Wonders"] = 1f
// we don't want to modify the existing happiness list because that leads // we don't want to modify the existing happiness list because that leads
@ -221,7 +221,7 @@ class CityStats {
if (policies.contains("Commerce Complete")) stats.gold += 1 if (policies.contains("Commerce Complete")) stats.gold += 1
if (policies.contains("Secularism")) stats.science += 2 if (policies.contains("Secularism")) stats.science += 2
if(cityInfo.getBuildingUniques().contains("+1 Production from specialists")) if(cityInfo.containsBuildingUnique("+1 Production from specialists"))
stats.production += 1 stats.production += 1
return stats return stats
} }
@ -268,19 +268,18 @@ class CityStats {
private fun getStatPercentBonusesFromBuildings(): Stats { private fun getStatPercentBonusesFromBuildings(): Stats {
val stats = cityInfo.cityConstructions.getStatPercentBonuses() val stats = cityInfo.cityConstructions.getStatPercentBonuses()
val civUniques = cityInfo.civInfo.getBuildingUniques() if (cityInfo.civInfo.containsBuildingUnique("Culture in all cities increased by 25%")) stats.culture += 25f
if (civUniques.contains("Culture in all cities increased by 25%")) stats.culture += 25f
val currentConstruction = cityInfo.cityConstructions.getCurrentConstruction() val currentConstruction = cityInfo.cityConstructions.getCurrentConstruction()
if(currentConstruction is Building && currentConstruction.uniques.contains("Spaceship part")){ if(currentConstruction is Building && currentConstruction.uniques.contains("Spaceship part")){
if(civUniques.contains("Increases production of spaceship parts by 25%")) if(cityInfo.civInfo.containsBuildingUnique("Increases production of spaceship parts by 25%"))
stats.production += 25 stats.production += 25
if(cityInfo.getBuildingUniques().contains("Increases production of spaceship parts by 50%")) if(cityInfo.containsBuildingUnique("Increases production of spaceship parts by 50%"))
stats.production += 50 stats.production += 50
} }
if(currentConstruction is BaseUnit && currentConstruction.unitType==UnitType.Mounted if(currentConstruction is BaseUnit && currentConstruction.unitType==UnitType.Mounted
&& cityInfo.getBuildingUniques().contains("+15% Production when building Mounted Units in this city")) && cityInfo.containsBuildingUnique("+15% Production when building Mounted Units in this city"))
stats.production += 15 stats.production += 15
return stats return stats

View File

@ -62,8 +62,8 @@ class PopulationManager {
// growth! // growth!
{ {
foodStored -= getFoodToNextPopulation() foodStored -= getFoodToNextPopulation()
if (cityInfo.getBuildingUniques().contains("40% of food is carried over after a new citizen is born")) foodStored += (0.4f * getFoodToNextPopulation()).toInt() // Aqueduct special if (cityInfo.containsBuildingUnique("40% of food is carried over after a new citizen is born")) foodStored += (0.4f * getFoodToNextPopulation()).toInt() // Aqueduct special
if (cityInfo.getBuildingUniques().contains("25% of food is carried over after a new citizen is born")) foodStored += (0.25f * getFoodToNextPopulation()).toInt() // Medical Lab special if (cityInfo.containsBuildingUnique("25% of food is carried over after a new citizen is born")) foodStored += (0.25f * getFoodToNextPopulation()).toInt() // Medical Lab special
population++ population++
autoAssignPopulation() autoAssignPopulation()
cityInfo.civInfo.addNotification("["+cityInfo.name + "] has grown!", cityInfo.location, Color.GREEN) cityInfo.civInfo.addNotification("["+cityInfo.name + "] has grown!", cityInfo.location, Color.GREEN)

View File

@ -37,10 +37,15 @@ class CivInfoStats(val civInfo: CivilizationInfo){
private fun getTransportationUpkeep(): Int { private fun getTransportationUpkeep(): Int {
var transportationUpkeep = 0 var transportationUpkeep = 0
for (it in civInfo.cities.flatMap { it.getTiles() }.filter{ !it.isCityCenter() }) { // we no longer use .flatMap, because there are a lot of tiles and keeping them all in a list
when(it.roadStatus) { // just to go over them once is a waste of memory - there are low-end phones who don't have much ram
RoadStatus.Road -> transportationUpkeep += 1 for (city in civInfo.cities) {
RoadStatus.Railroad -> transportationUpkeep += 2 for (tile in city.getTiles()) {
if (tile.isCityCenter()) continue
when (tile.roadStatus) {
RoadStatus.Road -> transportationUpkeep += 1
RoadStatus.Railroad -> transportationUpkeep += 2
}
} }
} }
if (civInfo.policies.isAdopted("Trade Unions")) transportationUpkeep *= (2 / 3f).toInt() if (civInfo.policies.isAdopted("Trade Unions")) transportationUpkeep *= (2 / 3f).toInt()
@ -108,7 +113,7 @@ class CivInfoStats(val civInfo: CivilizationInfo){
} }
} }
if (civInfo.getBuildingUniques().contains("Provides 1 happiness per social policy")) { if (civInfo.containsBuildingUnique("Provides 1 happiness per social policy")) {
if(!statMap.containsKey("Policies")) statMap["Policies"]=0f if(!statMap.containsKey("Policies")) statMap["Policies"]=0f
statMap["Policies"] = statMap["Policies"]!! + statMap["Policies"] = statMap["Policies"]!! +
civInfo.policies.getAdoptedPolicies().count { !it.endsWith("Complete") }.toFloat() civInfo.policies.getAdoptedPolicies().count { !it.endsWith("Complete") }.toFloat()

View File

@ -67,7 +67,7 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo){
fun updateHasActiveGreatWall(){ fun updateHasActiveGreatWall(){
civInfo.hasActiveGreatWall = !civInfo.tech.isResearched("Dynamite") && civInfo.hasActiveGreatWall = !civInfo.tech.isResearched("Dynamite") &&
civInfo.getBuildingUniques().contains("Enemy land units must spend 1 extra movement point when inside your territory (obsolete upon Dynamite)") civInfo.containsBuildingUnique("Enemy land units must spend 1 extra movement point when inside your territory (obsolete upon Dynamite)")
} }
fun setCitiesConnectedToCapitalTransients(){ fun setCitiesConnectedToCapitalTransients(){

View File

@ -161,7 +161,7 @@ class CivilizationInfo {
fun hasResource(resourceName:String): Boolean = getCivResourcesByName()[resourceName]!!>0 fun hasResource(resourceName:String): Boolean = getCivResourcesByName()[resourceName]!!>0
fun getBuildingUniques(): List<String> = cities.flatMap { it.getBuildingUniques()}.distinct() fun containsBuildingUnique(unique:String) = cities.any { it.containsBuildingUnique(unique) }
fun getCivUnits(): List<MapUnit> = units fun getCivUnits(): List<MapUnit> = units

View File

@ -26,7 +26,7 @@ class GoldenAgeManager{
fun enterGoldenAge() { fun enterGoldenAge() {
var turnsToGoldenAge = 10.0 var turnsToGoldenAge = 10.0
if (civInfo.getBuildingUniques().contains("Golden Age length increases +50%")) turnsToGoldenAge *= 1.5 if (civInfo.containsBuildingUnique("Golden Age length increases +50%")) turnsToGoldenAge *= 1.5
if (civInfo.policies.isAdopted("Freedom Complete")) turnsToGoldenAge *= 1.5 if (civInfo.policies.isAdopted("Freedom Complete")) turnsToGoldenAge *= 1.5
turnsLeftForCurrentGoldenAge += turnsToGoldenAge.toInt() turnsLeftForCurrentGoldenAge += turnsToGoldenAge.toInt()
civInfo.addNotification("You have entered a golden age!", null, Color.GOLD) civInfo.addNotification("You have entered a golden age!", null, Color.GOLD)

View File

@ -25,7 +25,7 @@ class PolicyManager {
var cityModifier = 0.3 * (civInfo.cities.size - 1) var cityModifier = 0.3 * (civInfo.cities.size - 1)
if (isAdopted("Representation")) cityModifier *= (2 / 3f).toDouble() if (isAdopted("Representation")) cityModifier *= (2 / 3f).toDouble()
if (isAdopted("Piety Complete")) baseCost *= 0.9 if (isAdopted("Piety Complete")) baseCost *= 0.9
if (civInfo.getBuildingUniques().contains("Culture cost of adopting new Policies reduced by 10%")) baseCost *= 0.9 if (civInfo.containsBuildingUnique("Culture cost of adopting new Policies reduced by 10%")) baseCost *= 0.9
val cost: Int = Math.round(baseCost * (1 + cityModifier)).toInt() val cost: Int = Math.round(baseCost * (1 + cityModifier)).toInt()
return cost - (cost % 5) return cost - (cost % 5)
} }

View File

@ -88,7 +88,7 @@ class MapUnit {
movement += getUniques().count{it=="+1 Movement"} movement += getUniques().count{it=="+1 Movement"}
if(type.isWaterUnit() && !type.isCivilian() if(type.isWaterUnit() && !type.isCivilian()
&& civInfo.getBuildingUniques().contains("All military naval units receive +1 movement and +1 sight")) && civInfo.containsBuildingUnique("All military naval units receive +1 movement and +1 sight"))
movement += 1 movement += 1
if(type.isWaterUnit() && civInfo.getNation().unique=="+2 movement for all naval units") if(type.isWaterUnit() && civInfo.getNation().unique=="+2 movement for all naval units")
@ -136,7 +136,7 @@ class MapUnit {
if (civInfo.getNation().unique == "All land military units have +1 sight, 50% discount when purchasing tiles") if (civInfo.getNation().unique == "All land military units have +1 sight, 50% discount when purchasing tiles")
visibilityRange += 1 visibilityRange += 1
if (type.isWaterUnit() && !type.isCivilian() if (type.isWaterUnit() && !type.isCivilian()
&& civInfo.getBuildingUniques().contains("All military naval units receive +1 movement and +1 sight")) && civInfo.containsBuildingUnique("All military naval units receive +1 movement and +1 sight"))
visibilityRange += 1 visibilityRange += 1
val tile = getTile() val tile = getTile()
if (tile.baseTerrain == Constants.hill && type.isLandUnit()) visibilityRange += 1 if (tile.baseTerrain == Constants.hill && type.isLandUnit()) visibilityRange += 1
@ -230,7 +230,7 @@ class MapUnit {
var goldCostOfUpgrade = (unitToUpgradeTo.cost - baseUnit().cost) * 2 + 10 var goldCostOfUpgrade = (unitToUpgradeTo.cost - baseUnit().cost) * 2 + 10
if (civInfo.policies.isAdopted("Professional Army")) if (civInfo.policies.isAdopted("Professional Army"))
goldCostOfUpgrade = (goldCostOfUpgrade * 0.66f).toInt() goldCostOfUpgrade = (goldCostOfUpgrade * 0.66f).toInt()
if(civInfo.getBuildingUniques().contains("Gold cost of upgrading military units reduced by 33%")) if(civInfo.containsBuildingUnique("Gold cost of upgrading military units reduced by 33%"))
goldCostOfUpgrade = (goldCostOfUpgrade * 0.66f).toInt() goldCostOfUpgrade = (goldCostOfUpgrade * 0.66f).toInt()
return goldCostOfUpgrade return goldCostOfUpgrade
} }

View File

@ -128,7 +128,7 @@ open class TileInfo {
var stats = getBaseTerrain().clone() var stats = getBaseTerrain().clone()
if((baseTerrain== Constants.ocean||baseTerrain==Constants.coast) && city!=null if((baseTerrain== Constants.ocean||baseTerrain==Constants.coast) && city!=null
&& city.getBuildingUniques().contains("+1 food from Ocean and Coast tiles")) && city.containsBuildingUnique("+1 food from Ocean and Coast tiles"))
stats.food += 1 stats.food += 1
if (terrainFeature != null) { if (terrainFeature != null) {
@ -139,10 +139,10 @@ open class TileInfo {
stats.add(terrainFeatureBase) stats.add(terrainFeatureBase)
if (terrainFeature == Constants.jungle && city != null if (terrainFeature == Constants.jungle && city != null
&& city.getBuildingUniques().contains("Jungles provide +2 science")) && city.containsBuildingUnique("Jungles provide +2 science"))
stats.science += 2f stats.science += 2f
if(terrainFeature=="Oasis" && city!=null if(terrainFeature=="Oasis" && city!=null
&& city.getBuildingUniques().contains("+2 Gold for each source of Oil and oasis")) && city.containsBuildingUnique("+2 Gold for each source of Oil and oasis"))
stats.gold += 2 stats.gold += 2
} }
@ -156,12 +156,12 @@ open class TileInfo {
&& observingCiv.getNation().unique=="Strategic Resources provide +1 Production, and Horses, Iron and Uranium Resources provide double quantity") && observingCiv.getNation().unique=="Strategic Resources provide +1 Production, and Horses, Iron and Uranium Resources provide double quantity")
stats.production+=1 stats.production+=1
if(resource.name=="Oil" && city!=null if(resource.name=="Oil" && city!=null
&& city.getBuildingUniques().contains("+2 Gold for each source of Oil and oasis")) && city.containsBuildingUnique("+2 Gold for each source of Oil and oasis"))
stats.gold += 2 stats.gold += 2
if(city!=null && isWater){ if(city!=null && isWater){
if(city.getBuildingUniques().contains("+1 production from all sea resources worked by the city")) if(city.containsBuildingUnique("+1 production from all sea resources worked by the city"))
stats.production+=1 stats.production+=1
if(city.getBuildingUniques().contains("+1 production and gold from all sea resources worked by the city")){ if(city.containsBuildingUnique("+1 production and gold from all sea resources worked by the city")){
stats.production+=1 stats.production+=1
stats.gold+=1 stats.gold+=1
} }
@ -182,7 +182,7 @@ open class TileInfo {
stats.add(improvement) // again, for the double effect stats.add(improvement) // again, for the double effect
} }
if(city!=null && isWater && city.getBuildingUniques().contains("+1 gold from worked water tiles in city")) if(city!=null && isWater && city.containsBuildingUnique("+1 gold from worked water tiles in city"))
stats.gold += 1 stats.gold += 1
if (isCityCenter()) { if (isCityCenter()) {

View File

@ -153,7 +153,7 @@ class Building : NamedStats(), IConstruction{
stats.happiness += 1 stats.happiness += 1
if (baseBuildingName == "Castle" if (baseBuildingName == "Castle"
&& civInfo.getBuildingUniques().contains("+1 happiness, +2 culture and +3 gold from every Castle")){ && civInfo.containsBuildingUnique("+1 happiness, +2 culture and +3 gold from every Castle")){
stats.happiness+=1 stats.happiness+=1
stats.culture+=2 stats.culture+=2
stats.gold+=3 stats.gold+=3
@ -199,7 +199,7 @@ class Building : NamedStats(), IConstruction{
} else { } else {
cost = Math.pow((30 * getProductionCost(civInfo.policies.adoptedPolicies)).toDouble(), 0.75) * (1 + hurryCostModifier / 100) cost = Math.pow((30 * getProductionCost(civInfo.policies.adoptedPolicies)).toDouble(), 0.75) * (1 + hurryCostModifier / 100)
if (civInfo.policies.adoptedPolicies.contains("Mercantilism")) cost *= 0.75 if (civInfo.policies.adoptedPolicies.contains("Mercantilism")) cost *= 0.75
if (civInfo.getBuildingUniques().contains("-15% to purchasing items in cities")) cost *= 0.85 if (civInfo.containsBuildingUnique("-15% to purchasing items in cities")) cost *= 0.85
if (civInfo.policies.adoptedPolicies.contains("Patronage") if (civInfo.policies.adoptedPolicies.contains("Patronage")
&& listOf("Monument", "Temple", "Opera House", "Museum", "Broadcast Tower") && listOf("Monument", "Temple", "Opera House", "Museum", "Broadcast Tower")
.map{civInfo.getEquivalentBuilding(it).name}.contains(name)) .map{civInfo.getEquivalentBuilding(it).name}.contains(name))
@ -293,7 +293,7 @@ class Building : NamedStats(), IConstruction{
} }
if ("Spaceship part" in uniques) { if ("Spaceship part" in uniques) {
if (!civInfo.getBuildingUniques().contains("Enables construction of Spaceship parts")) return "Apollo project not built!" if (!civInfo.containsBuildingUnique("Enables construction of Spaceship parts")) return "Apollo project not built!"
if (civInfo.victoryManager.unconstructedSpaceshipParts()[name] == 0) return "Don't need to build any more of these!" if (civInfo.victoryManager.unconstructedSpaceshipParts()[name] == 0) return "Don't need to build any more of these!"
} }
return "" return ""

View File

@ -19,7 +19,7 @@ class TileImprovement : NamedStats(), ICivilopedia {
private val turnsToBuild: Int = 0 // This is the base cost. private val turnsToBuild: Int = 0 // This is the base cost.
fun getTurnsToBuild(civInfo: CivilizationInfo): Int { fun getTurnsToBuild(civInfo: CivilizationInfo): Int {
var realTurnsToBuild = turnsToBuild.toFloat() var realTurnsToBuild = turnsToBuild.toFloat()
if (civInfo.getBuildingUniques().contains("Worker construction increased 25%")) if (civInfo.containsBuildingUnique("Worker construction increased 25%"))
realTurnsToBuild *= 0.75f realTurnsToBuild *= 0.75f
if (civInfo.policies.isAdopted("Citizenship")) if (civInfo.policies.isAdopted("Citizenship"))
realTurnsToBuild *= 0.75f realTurnsToBuild *= 0.75f

View File

@ -106,7 +106,7 @@ class BaseUnit : INamed, IConstruction, ICivilopedia {
if (!baseCost) { if (!baseCost) {
if(civInfo.policies.adoptedPolicies.contains("Mercantilism")) cost *= 0.75 if(civInfo.policies.adoptedPolicies.contains("Mercantilism")) cost *= 0.75
if(civInfo.policies.adoptedPolicies.contains("Militarism")) cost *= 0.66f if(civInfo.policies.adoptedPolicies.contains("Militarism")) cost *= 0.66f
if (civInfo.getBuildingUniques().contains("-15% to purchasing items in cities")) cost *= 0.85 if (civInfo.containsBuildingUnique("-15% to purchasing items in cities")) cost *= 0.85
} }
return (cost / 10).toInt() * 10 // rounded down o nearest ten return (cost / 10).toInt() * 10 // rounded down o nearest ten
} }
@ -151,8 +151,7 @@ class BaseUnit : INamed, IConstruction, ICivilopedia {
unit.promotions.XP += 15 unit.promotions.XP += 15
if(unit.type in listOf(UnitType.Melee,UnitType.Mounted,UnitType.Armor) if(unit.type in listOf(UnitType.Melee,UnitType.Mounted,UnitType.Armor)
&& construction.cityInfo.getBuildingUniques() && construction.cityInfo.containsBuildingUnique("All newly-trained melee, mounted, and armored units in this city receive the Drill I promotion"))
.contains("All newly-trained melee, mounted, and armored units in this city receive the Drill I promotion"))
unit.promotions.addPromotion("Drill I", isFree = true) unit.promotions.addPromotion("Drill I", isFree = true)
} }

View File

@ -86,6 +86,15 @@ open class Stats() {
happiness=hashMap[Stat.Happiness]!! happiness=hashMap[Stat.Happiness]!!
science=hashMap[Stat.Science]!! science=hashMap[Stat.Science]!!
} }
fun equals(otherStats: Stats):Boolean{
return culture==otherStats.culture
&& gold==otherStats.gold
&& production==otherStats.production
&& food==otherStats.food
&& happiness==otherStats.happiness
&& science==otherStats.science
}
} }
class StatMap:LinkedHashMap<String,Stats>(){ class StatMap:LinkedHashMap<String,Stats>(){

View File

@ -109,7 +109,7 @@ class VictoryScreen : PickerScreen() {
fun scienceVictoryColumn():Table{ fun scienceVictoryColumn():Table{
val t = Table() val t = Table()
t.defaults().pad(5f) t.defaults().pad(5f)
t.add(getMilestone("Built Apollo Program".tr(),playerCivInfo.getBuildingUniques().contains("Enables construction of Spaceship parts"))).row() t.add(getMilestone("Built Apollo Program".tr(),playerCivInfo.containsBuildingUnique("Enables construction of Spaceship parts"))).row()
val victoryManager= playerCivInfo.victoryManager val victoryManager= playerCivInfo.victoryManager

View File

@ -12,7 +12,11 @@ class YieldGroup : HorizontalGroup() {
isTransform = false // performance helper - nothing here is rotated or scaled isTransform = false // performance helper - nothing here is rotated or scaled
} }
var currentStats=Stats()
fun setStats(stats: Stats) { fun setStats(stats: Stats) {
if(currentStats.equals(stats)) return // don't need to update - this is a memory and time saver!
currentStats = stats
clearChildren() clearChildren()
for (entry in stats.toHashMap().filter { it.value > 0 }) { for (entry in stats.toHashMap().filter { it.value > 0 }) {
addActor(getStatIconsTable(entry.key.toString(), entry.value.toInt())) addActor(getStatIconsTable(entry.key.toString(), entry.value.toInt()))

View File

@ -128,8 +128,9 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
if(ImageGetter.imageExists(tileSetLocation+"City")) if(ImageGetter.imageExists(tileSetLocation+"City"))
return tileSetLocation+"City" return tileSetLocation+"City"
} }
val baseTerrainTileLocation = tileSetLocation+tileInfo.baseTerrain // these are templates because apparently chain appending is faster or something?
val baseTerrainAndFeatureTileLocation = baseTerrainTileLocation+"+"+tileInfo.terrainFeature val baseTerrainTileLocation = "$tileSetLocation${tileInfo.baseTerrain}"
val baseTerrainAndFeatureTileLocation = "$baseTerrainTileLocation+${tileInfo.terrainFeature}"
if(tileInfo.terrainFeature!=null && ImageGetter.imageExists(baseTerrainAndFeatureTileLocation)) if(tileInfo.terrainFeature!=null && ImageGetter.imageExists(baseTerrainAndFeatureTileLocation))
return baseTerrainAndFeatureTileLocation return baseTerrainAndFeatureTileLocation
if(ImageGetter.imageExists(baseTerrainTileLocation)) return baseTerrainTileLocation if(ImageGetter.imageExists(baseTerrainTileLocation)) return baseTerrainTileLocation
@ -221,7 +222,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
baseTerrainOverlayImage=null baseTerrainOverlayImage=null
} }
val imagePath = tileSetLocation + tileInfo.baseTerrain + "Overlay" val imagePath = "$tileSetLocation${tileInfo.baseTerrain}Overlay"
if (!ImageGetter.imageExists(imagePath)) return if (!ImageGetter.imageExists(imagePath)) return
baseTerrainOverlayImage = ImageGetter.getImage(imagePath) baseTerrainOverlayImage = ImageGetter.getImage(imagePath)
baseTerrainOverlayImage!!.run { baseTerrainOverlayImage!!.run {

View File

@ -34,7 +34,7 @@ class WorldTileGroup(internal val worldScreen: WorldScreen, tileInfo: TileInfo)
&& city!!.civInfo.isPlayerCivilization()) && city!!.civInfo.isPlayerCivilization())
addPopulationIcon() addPopulationIcon()
val currentPlayerCiv = UnCivGame.Current.gameInfo.getCurrentPlayerCivilization() val currentPlayerCiv = worldScreen.currentPlayerCiv
if (UnCivGame.Current.viewEntireMapForDebug if (UnCivGame.Current.viewEntireMapForDebug
|| currentPlayerCiv.exploredTiles.contains(tileInfo.position)) || currentPlayerCiv.exploredTiles.contains(tileInfo.position))
updateCityButton(city, isViewable || UnCivGame.Current.viewEntireMapForDebug) // needs to be before the update so the units will be above the city button updateCityButton(city, isViewable || UnCivGame.Current.viewEntireMapForDebug) // needs to be before the update so the units will be above the city button

View File

@ -367,7 +367,7 @@ class WorldScreen : CameraStageBaseScreen() {
&& currentPlayerCiv.exploredTiles.asSequence().map { gameInfo.tileMap[it] } && currentPlayerCiv.exploredTiles.asSequence().map { gameInfo.tileMap[it] }
.any { it.isCityCenter() && it.getOwner()!=currentPlayerCiv }) .any { it.isCityCenter() && it.getOwner()!=currentPlayerCiv })
displayTutorials("EnemyCity") displayTutorials("EnemyCity")
if("Enables construction of Spaceship parts" in currentPlayerCiv.getBuildingUniques()) if(currentPlayerCiv.containsBuildingUnique("Enables construction of Spaceship parts"))
displayTutorials("ApolloProgram") displayTutorials("ApolloProgram")
if(currentPlayerCiv.getCivUnits().any { it.type == UnitType.Siege }) if(currentPlayerCiv.getCivUnits().any { it.type == UnitType.Siege })
displayTutorials("SiegeUnitTrained") displayTutorials("SiegeUnitTrained")