Added empire overview screen!

This commit is contained in:
Yair Morgenstern 2018-06-26 23:08:21 +03:00
parent fe1b74c197
commit 15b602da1f
5 changed files with 159 additions and 129 deletions

View File

@ -10,20 +10,22 @@ import com.unciv.models.stats.Stats
class CityStats { class CityStats {
@Transient var baseStatList = LinkedHashMap<String,Stats>() @Transient
@Transient var happinessList = LinkedHashMap<String,Float>() var baseStatList = LinkedHashMap<String, Stats>()
@Transient var currentCityStats: Stats = Stats() // This is so we won't have to calculate this multiple times - takes a lot of time, especially on phones @Transient
@Transient lateinit var cityInfo: CityInfo var happinessList = LinkedHashMap<String, Float>()
@Transient
var currentCityStats: Stats = Stats() // This is so we won't have to calculate this multiple times - takes a lot of time, especially on phones
@Transient
lateinit var cityInfo: CityInfo
private fun getStatsFromTiles(): Stats { private fun getStatsFromTiles(): Stats {
val stats = Stats() val stats = Stats()
for (cell in cityInfo.getTilesInRange().filter { cityInfo.workedTiles.contains(it.position) || cityInfo.location==it.position}) for (cell in cityInfo.getTilesInRange().filter { cityInfo.workedTiles.contains(it.position) || cityInfo.location == it.position })
stats.add(cell.getTileStats(cityInfo, cityInfo.civInfo)) stats.add(cell.getTileStats(cityInfo, cityInfo.civInfo))
return stats return stats
} }
private
fun getStatsFromTradeRoute(): Stats { fun getStatsFromTradeRoute(): Stats {
val stats = Stats() val stats = Stats()
if (!cityInfo.isCapital() && isConnectedToCapital(RoadStatus.Road)) { if (!cityInfo.isCapital() && isConnectedToCapital(RoadStatus.Road)) {
@ -37,10 +39,10 @@ class CityStats {
} }
private fun getStatsFromProduction(production:Float): Stats { private fun getStatsFromProduction(production: Float): Stats {
val stats = Stats() val stats = Stats()
when(cityInfo.cityConstructions.currentConstruction) { when (cityInfo.cityConstructions.currentConstruction) {
"Gold" -> stats.gold += production / 4 "Gold" -> stats.gold += production / 4
"Science" -> { "Science" -> {
var scienceProduced = production / 4 var scienceProduced = production / 4
@ -107,7 +109,7 @@ class CityStats {
if (civInfo.policies.isAdopted("Meritocracy")) if (civInfo.policies.isAdopted("Meritocracy"))
unhappinessFromCitizens *= 0.95f unhappinessFromCitizens *= 0.95f
happinessList["Population"]=-unhappinessFromCitizens happinessList["Population"] = -unhappinessFromCitizens
var happinessFromPolicies = 0f var happinessFromPolicies = 0f
if (civInfo.policies.isAdopted("Aristocracy")) if (civInfo.policies.isAdopted("Aristocracy"))
@ -120,7 +122,7 @@ class CityStats {
happinessList["Policies"] = happinessFromPolicies happinessList["Policies"] = happinessFromPolicies
val happinessFromBuildings = cityInfo.cityConstructions.getStats().happiness.toInt().toFloat() val happinessFromBuildings = cityInfo.cityConstructions.getStats().happiness.toInt().toFloat()
happinessList["Buildings"] =happinessFromBuildings happinessList["Buildings"] = happinessFromBuildings
return happinessList return happinessList
} }
@ -164,7 +166,7 @@ class CityStats {
private fun getStatPercentBonusesFromGoldenAge(isGoldenAge: Boolean): Stats { private fun getStatPercentBonusesFromGoldenAge(isGoldenAge: Boolean): Stats {
val stats = Stats() val stats = Stats()
if (isGoldenAge){ if (isGoldenAge) {
stats.production += 20f stats.production += 20f
stats.culture += 20f stats.culture += 20f
} }
@ -205,8 +207,8 @@ class CityStats {
baseStatList = LinkedHashMap<String, Stats>() baseStatList = LinkedHashMap<String, Stats>()
val civInfo = cityInfo.civInfo val civInfo = cityInfo.civInfo
baseStatList["Population"] = Stats().add(Stat.Science,cityInfo.population.population.toFloat()) baseStatList["Population"] = Stats().add(Stat.Science, cityInfo.population.population.toFloat())
.add(Stat.Production,cityInfo.population.getFreePopulation().toFloat()) .add(Stat.Production, cityInfo.population.getFreePopulation().toFloat())
baseStatList["Tile yields"] = getStatsFromTiles() baseStatList["Tile yields"] = getStatsFromTiles()
baseStatList["Specialists"] = getStatsFromSpecialists(cityInfo.population.getSpecialists(), civInfo.policies.adoptedPolicies) baseStatList["Specialists"] = getStatsFromSpecialists(cityInfo.population.getSpecialists(), civInfo.policies.adoptedPolicies)
baseStatList["Trade route"] = getStatsFromTradeRoute() baseStatList["Trade route"] = getStatsFromTradeRoute()
@ -222,47 +224,59 @@ class CityStats {
statPercentBonuses.add(getStatPercentBonusesFromMarble()) statPercentBonuses.add(getStatPercentBonusesFromMarble())
statPercentBonuses.add(getStatPercentBonusesFromComputers()) statPercentBonuses.add(getStatPercentBonusesFromComputers())
val stats = Stats()
for (stat in baseStatList.values) stats.add(stat)
stats.production *= 1 + statPercentBonuses.production / 100 // So they get bonuses for production and gold/science
val statsFromProduction = getStatsFromProduction(stats.production) //val stats = Stats()
stats.add(statsFromProduction) for (stat in baseStatList.values) stat.production *= 1 + statPercentBonuses.production / 100
//stats.production *= 1 + statPercentBonuses.production / 100 // So they get bonuses for production and gold/science
val statsFromProduction = getStatsFromProduction(baseStatList.values.map { it.production }.sum())
baseStatList["Construction"] = statsFromProduction baseStatList["Construction"] = statsFromProduction
for (stat in baseStatList.values) {
stat.gold *= 1 + statPercentBonuses.gold / 100
stat.science *= 1 + statPercentBonuses.science / 100
stat.culture *= 1 + statPercentBonuses.culture / 100
}
stats.gold *= 1 + statPercentBonuses.gold / 100
stats.science *= 1 + statPercentBonuses.science / 100
stats.culture *= 1 + statPercentBonuses.culture / 100
val isUnhappy = civInfo.happiness < 0 val isUnhappy = civInfo.happiness < 0
if (!isUnhappy) stats.food *= 1 + statPercentBonuses.food / 100 // Regular food bonus revoked when unhappy per https://forums.civfanatics.com/resources/complete-guide-to-happiness-vanilla.25584/ if (!isUnhappy) // Regular food bonus revoked when unhappy per https://forums.civfanatics.com/resources/complete-guide-to-happiness-vanilla.25584/
val foodEaten = (cityInfo.population.population * 2).toFloat() for (stat in baseStatList.values) stat.food *= 1 + statPercentBonuses.food / 100
baseStatList["Population"]!!.food -= foodEaten // to display it to the user
stats.food -= foodEaten // Food reduced after the bonus
if (civInfo.policies.isAdopted("Civil Society"))
stats.food += cityInfo.population.getNumberOfSpecialists().toFloat()
if (isUnhappy) stats.food /= 4f // Reduce excess food to 1/4 per the same var foodEaten = (cityInfo.population.population * 2).toFloat()
stats.food *= 1 + getGrowthBonusFromPolicies() if (civInfo.policies.isAdopted("Civil Society"))
foodEaten -= cityInfo.population.getNumberOfSpecialists()
baseStatList["Population"]!!.food -= foodEaten // to display it to the user
val excessFood = baseStatList.values.sumByDouble { it.food.toDouble() }.toFloat()
if (isUnhappy && excessFood > 0) // Reduce excess food to 1/4 per the same
baseStatList["Unhappiness"] = Stats().apply { food = -excessFood * (3 / 4f) }
if (!baseStatList.containsKey("Policies")) baseStatList["Policies"] = Stats()
baseStatList["Policies"]!!.food += getGrowthBonusFromPolicies() * excessFood
val buildingsMaintainance = cityInfo.cityConstructions.getMaintenanceCosts().toFloat() // this is AFTER the bonus calculation! val buildingsMaintainance = cityInfo.cityConstructions.getMaintenanceCosts().toFloat() // this is AFTER the bonus calculation!
baseStatList["Buildings"]!!.gold -= buildingsMaintainance baseStatList["Maintainance"] = Stats().apply { gold = -buildingsMaintainance }
stats.gold -= buildingsMaintainance
this.currentCityStats = stats currentCityStats = Stats()
for (stat in baseStatList.values) currentCityStats.add(stat)
} }
fun isConnectedToCapital(roadType: RoadStatus): Boolean { fun isConnectedToCapital(roadType: RoadStatus): Boolean {
if(cityInfo.civInfo.cities.count()<2) return false// first city! if (cityInfo.civInfo.cities.count() < 2) return false// first city!
val capitalTile = cityInfo.civInfo.getCapital().getCenterTile() val capitalTile = cityInfo.civInfo.getCapital().getCenterTile()
val tilesReached = HashSet<TileInfo>() val tilesReached = HashSet<TileInfo>()
var tilesToCheck : List<TileInfo> = listOf(cityInfo.getCenterTile()) var tilesToCheck: List<TileInfo> = listOf(cityInfo.getCenterTile())
while (tilesToCheck.isNotEmpty()) { while (tilesToCheck.isNotEmpty()) {
val newTiles = tilesToCheck val newTiles = tilesToCheck
.flatMap { it.neighbors }.distinct() .flatMap { it.neighbors }.distinct()
.filter{ !tilesReached.contains(it) && !tilesToCheck.contains(it) .filter {
&& (roadType !== RoadStatus.Road || it.roadStatus !== RoadStatus.None) !tilesReached.contains(it) && !tilesToCheck.contains(it)
&& (roadType !== RoadStatus.Railroad || it.roadStatus === roadType) } && (roadType !== RoadStatus.Road || it.roadStatus !== RoadStatus.None)
&& (roadType !== RoadStatus.Railroad || it.roadStatus === roadType)
}
if (newTiles.contains(capitalTile)) return true if (newTiles.contains(capitalTile)) return true
tilesReached.addAll(tilesToCheck) tilesReached.addAll(tilesToCheck)
@ -270,5 +284,4 @@ class CityStats {
} }
return false return false
} }
} }

View File

@ -0,0 +1,98 @@
package com.unciv.ui
import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.unciv.UnCivGame
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.ui.utils.*
import kotlin.math.roundToInt
class EmpireOverviewScreen : CameraStageBaseScreen(){
init {
val civInfo = UnCivGame.Current.gameInfo.getPlayerCivilization()
val closeButton = TextButton("Close".tr(), skin)
closeButton.addClickListener { UnCivGame.Current.setWorldScreen() }
closeButton.y = stage.height - closeButton.height - 5
stage.addActor(closeButton)
val table=Table()
table.defaults().pad(20f)
table.add(getCityInfoTable(civInfo))
table.add(getHappinessTable(civInfo))
table.add(getGoldTable(civInfo))
table.center(stage)
stage.addActor(table)
}
private fun getHappinessTable(civInfo: CivilizationInfo): Table {
val happinessTable = Table(skin)
happinessTable.defaults().pad(5f)
happinessTable.add(Label("Happiness", skin).setFont(24)).colspan(2).row()
for (entry in civInfo.getHappinessForNextTurn()) {
happinessTable.add(entry.key)
happinessTable.add(entry.value.toString()).row()
}
happinessTable.add("Total")
happinessTable.add(civInfo.getHappinessForNextTurn().values.sum().toString())
happinessTable.pack()
return happinessTable
}
private fun getGoldTable(civInfo: CivilizationInfo): Table {
val goldTable = Table(skin)
goldTable.defaults().pad(5f)
goldTable.add(Label("Gold", skin).setFont(24)).colspan(2).row()
var total=0f
for (entry in civInfo.getStatsForNextTurn()) {
if(entry.value.gold==0f) continue
goldTable.add(entry.key)
goldTable.add(entry.value.gold.toString()).row()
total += entry.value.gold
}
goldTable.add("Total")
goldTable.add(total.toString())
goldTable.pack()
return goldTable
}
private fun getCityInfoTable(civInfo: CivilizationInfo): Table {
val cityInfotable = Table()
cityInfotable.skin = skin
cityInfotable.defaults().pad(5f)
cityInfotable.add(Label("Cities", skin).setFont(24)).colspan(8).row()
cityInfotable.add()
cityInfotable.add(ImageGetter.getStatIcon("Population")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Food")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Gold")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Science")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Production")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Culture")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Happiness")).size(20f).row()
for (city in civInfo.cities) {
cityInfotable.add(city.name)
cityInfotable.add(city.population.population.toString())
cityInfotable.add(city.cityStats.currentCityStats.food.roundToInt().toString())
cityInfotable.add(city.cityStats.currentCityStats.gold.roundToInt().toString())
cityInfotable.add(city.cityStats.currentCityStats.science.roundToInt().toString())
cityInfotable.add(city.cityStats.currentCityStats.production.roundToInt().toString())
cityInfotable.add(city.cityStats.currentCityStats.culture.roundToInt().toString())
cityInfotable.add(city.cityStats.currentCityStats.happiness.roundToInt().toString()).row()
}
cityInfotable.add("Total")
cityInfotable.add(civInfo.cities.sumBy { it.population.population }.toString())
cityInfotable.add("")
cityInfotable.add(civInfo.cities.sumBy { it.cityStats.currentCityStats.gold.toInt() }.toString())
cityInfotable.add(civInfo.cities.sumBy { it.cityStats.currentCityStats.science.toInt() }.toString())
cityInfotable.add("")
cityInfotable.add(civInfo.cities.sumBy { it.cityStats.currentCityStats.culture.toInt() }.toString())
cityInfotable.add(civInfo.cities.sumBy { it.cityStats.currentCityStats.happiness.toInt() }.toString())
cityInfotable.pack()
return cityInfotable
}
}

View File

@ -9,12 +9,10 @@ import com.badlogic.gdx.utils.Json
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.logic.GameInfo import com.unciv.logic.GameInfo
import com.unciv.logic.GameSaver import com.unciv.logic.GameSaver
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.ui.pickerscreens.PickerScreen import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.utils.* import com.unciv.ui.utils.*
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import kotlin.math.roundToInt
class LoadScreen : PickerScreen() { class LoadScreen : PickerScreen() {
lateinit var selectedSave:String lateinit var selectedSave:String
@ -86,87 +84,3 @@ class LoadScreen : PickerScreen() {
} }
class EmpireOverviewScreen : CameraStageBaseScreen(){
init {
val civInfo = UnCivGame.Current.gameInfo.getPlayerCivilization()
val closeButton =TextButton("Close".tr(),skin)
closeButton.addClickListener { UnCivGame.Current.setWorldScreen() }
closeButton.y = stage.height - closeButton.height - 5
stage.addActor(closeButton)
addCityInfoTable(civInfo)
addHappinessTable(civInfo)
addGoldTable(civInfo)
}
private fun addHappinessTable(civInfo: CivilizationInfo) {
val happinessTable = Table(skin)
happinessTable.defaults().pad(5f)
happinessTable.add(Label("Happiness", skin).setFont(24)).colspan(2).row()
for (entry in civInfo.getHappinessForNextTurn()) {
happinessTable.add(entry.key)
happinessTable.add(entry.value.toString()).row()
}
happinessTable.add("Total")
happinessTable.add(civInfo.getHappinessForNextTurn().values.sum().toString())
happinessTable.pack()
stage.addActor(happinessTable)
}
private fun addGoldTable(civInfo: CivilizationInfo) {
val goldTable = Table(skin)
goldTable.defaults().pad(5f)
goldTable.add(Label("Gold", skin).setFont(24)).colspan(2).row()
var total=0f
for (entry in civInfo.getStatsForNextTurn()) {
if(entry.value.gold==0f) continue
goldTable.add(entry.key)
goldTable.add(entry.value.gold.toString()).row()
total += entry.value.gold
}
goldTable.add("Total")
goldTable.add(total.toString())
goldTable.pack()
goldTable.y = stage.height/2
stage.addActor(goldTable)
}
private fun addCityInfoTable(civInfo: CivilizationInfo) {
val cityInfotable = Table()
cityInfotable.skin = skin
cityInfotable.defaults().pad(5f)
cityInfotable.add(Label("Cities", skin).setFont(24)).colspan(8).row()
cityInfotable.add()
cityInfotable.add(ImageGetter.getStatIcon("Population")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Food")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Gold")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Science")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Production")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Culture")).size(20f)
cityInfotable.add(ImageGetter.getStatIcon("Happiness")).size(20f).row()
for (city in civInfo.cities) {
cityInfotable.add(city.name)
cityInfotable.add(city.population.population.toString())
cityInfotable.add(city.cityStats.currentCityStats.food.roundToInt().toString())
cityInfotable.add(city.cityStats.currentCityStats.gold.roundToInt().toString())
cityInfotable.add(city.cityStats.currentCityStats.science.roundToInt().toString())
cityInfotable.add(city.cityStats.currentCityStats.production.roundToInt().toString())
cityInfotable.add(city.cityStats.currentCityStats.culture.roundToInt().toString())
cityInfotable.add(city.cityStats.currentCityStats.happiness.roundToInt().toString()).row()
}
cityInfotable.add("Total")
cityInfotable.add(civInfo.cities.sumBy { it.population.population }.toString())
cityInfotable.add("")
cityInfotable.add(civInfo.cities.sumBy { it.cityStats.currentCityStats.gold.toInt() }.toString())
cityInfotable.add(civInfo.cities.sumBy { it.cityStats.currentCityStats.science.toInt() }.toString())
cityInfotable.add("")
cityInfotable.add(civInfo.cities.sumBy { it.cityStats.currentCityStats.culture.toInt() }.toString())
cityInfotable.add(civInfo.cities.sumBy { it.cityStats.currentCityStats.happiness.toInt() }.toString())
cityInfotable.pack()
cityInfotable.setPosition(stage.width / 2, stage.height / 3)
stage.addActor(cityInfotable)
}
}

View File

@ -40,6 +40,11 @@ class WorldScreenTopBar(val screen: WorldScreen) : Table() {
pad(5f) pad(5f)
pack() pack()
addActor(getMenuButton()) // needs to be after pack addActor(getMenuButton()) // needs to be after pack
// val button = TextButton("Overview",CameraStageBaseScreen.skin)
// button.center(this)
// button.x = screen.stage.width-button.width-10
// addActor(button)
} }
private fun getResourceTable(): Table { private fun getResourceTable(): Table {

View File

@ -14,10 +14,10 @@ class WorldScreenOptionsTable internal constructor() : OptionsTable() {
remove() remove()
} }
addButton("Overview".tr()){ // addButton("Overview".tr()){
UnCivGame.Current.screen = EmpireOverviewScreen() // UnCivGame.Current.screen = EmpireOverviewScreen()
remove() // remove()
} // }
addButton("Load game".tr()){ addButton("Load game".tr()){
UnCivGame.Current.screen = LoadScreen() UnCivGame.Current.screen = LoadScreen()