Converted the max turns drop down to a slider, idea courtesy of SomeTroglodyte (#5843)

* Converted the time victory drop down to a slider, idea courtesy of SomeTroglodyte

* Added a score breakdown to stat overview screen

* Removed score factors with value 0 & applied SomeTroglodyte's patch

* Removed 2000 max turns, should never be reached anyways
This commit is contained in:
Xander Lenstra 2021-12-25 16:57:02 +01:00 committed by GitHub
parent ecadfb53fa
commit f3a2edf390
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 40 deletions

View File

@ -3,10 +3,8 @@ package com.unciv.logic
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.BackwardCompatibility.removeMissingModReferences
import com.unciv.logic.BackwardCompatibility.replaceDiplomacyFlag
import com.unciv.logic.automation.NextTurnAutomation
import com.unciv.logic.civilization.*
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
import com.unciv.logic.city.CityInfo
import com.unciv.logic.map.TileInfo
import com.unciv.logic.map.TileMap
@ -290,7 +288,7 @@ class GameInfo {
val winningCiv = civilizations
.filter { it.isMajorCiv() && !it.isSpectator() && !it.isBarbarian() }
.maxByOrNull { it.calculateScore() }
.maxByOrNull { it.calculateScoreBreakdown().values.sum() }
?: return // Are there no civs left?
winningCiv.victoryManager.hasWonTimeVictory = true

View File

@ -613,7 +613,7 @@ class CivilizationInfo {
fun getStatForRanking(category: RankingType): Int {
return when (category) {
RankingType.Score -> calculateScore()
RankingType.Score -> calculateScoreBreakdown().values.sum().toInt()
RankingType.Population -> cities.sumOf { it.population.population }
RankingType.Crop_Yield -> statsForNextTurn.food.roundToInt()
RankingType.Production -> statsForNextTurn.production.roundToInt()
@ -668,25 +668,25 @@ class CivilizationInfo {
}
fun isLongCountDisplay() = hasLongCountDisplayUnique && isLongCountActive()
fun calculateScore(): Int {
fun calculateScoreBreakdown(): HashMap<String,Double> {
val scoreBreakdown = hashMapOf<String,Double>();
// 1276 is the number of tiles in a medium sized map. The original uses 4160 for this,
// but they have bigger maps
var mapSizeModifier = 1276.0 / gameInfo.tileMap.mapParameters.numberOfTiles()
var mapSizeModifier = 1276 / gameInfo.tileMap.mapParameters.numberOfTiles().toDouble()
if (mapSizeModifier > 1)
mapSizeModifier = (mapSizeModifier - 1) / 3 + 1
var score = 0.0
score += cities.count() * 10 * mapSizeModifier
score += cities.sumOf { it.population.population } * 3 * mapSizeModifier
score += cities.sumOf { city -> city.getTiles().filter { !it.isWater}.count() } * 1 * mapSizeModifier
score += 40 * cities
scoreBreakdown["Cities"] = cities.count() * 10 * mapSizeModifier
scoreBreakdown["Population"] = cities.sumOf { it.population.population } * 3 * mapSizeModifier
scoreBreakdown["Tiles"] = cities.sumOf { city -> city.getTiles().filter { !it.isWater}.count() } * 1 * mapSizeModifier
scoreBreakdown["Wonders"] = 40 * cities
.sumOf { city -> city.cityConstructions.builtBuildings
.filter { gameInfo.ruleSet.buildings[it]!!.isWonder }.count()
}
score += tech.getNumberOfTechsResearched() * 4
score += tech.repeatingTechsResearched * 10
}.toDouble()
scoreBreakdown["Techs"] = tech.getNumberOfTechsResearched() * 4.toDouble()
scoreBreakdown["Future Tech"] = tech.repeatingTechsResearched * 10.toDouble()
return score.toInt()
return scoreBreakdown
}
//endregion

View File

@ -53,6 +53,7 @@ class GameParameters { // Default values are the default new game
parameters.isOnlineMultiplayer = isOnlineMultiplayer
parameters.baseRuleset = baseRuleset
parameters.mods = LinkedHashSet(mods)
parameters.maxTurns = maxTurns
return parameters
}

View File

@ -49,9 +49,11 @@ class GameOptionsTable(
addDifficultySelectBox()
addGameSpeedSelectBox()
addEraSelectBox()
addMaxTurnsSelectBox()
// align left and right edges with other SelectBoxes but allow independent dropdown width
add(Table().apply {
val turnSlider = addMaxTurnsSlider()
if (turnSlider != null)
add(turnSlider).padTop(10f).row()
cityStateSlider = addCityStatesSlider()
}).colspan(2).fillX().row()
}).row()
@ -130,6 +132,21 @@ class GameOptionsTable(
return slider
}
private fun Table.addMaxTurnsSlider(): UncivSlider? {
if (!gameParameters.victoryTypes.contains(VictoryType.Time)) return null
add("{Max Turns}:".toLabel()).left().expandX()
val slider = UncivSlider(250f, 1500f, 50f) {
gameParameters.maxTurns = it.toInt()
}
slider.permanentTip = true
slider.isDisabled = locked
val snapValues = floatArrayOf(250f,300f,350f,400f,450f,500f,550f,600f,650f,700f,750f,800f,900f,1000f,1250f,1500f)
slider.setSnapToValues(snapValues, 250f)
slider.value = gameParameters.maxTurns.toFloat()
return slider
}
private fun Table.addSelectBox(text: String, values: Collection<String>, initialState: String, onChange: (newValue: String) -> String?) {
add(text.toLabel()).left()
val selectBox = TranslatedSelectBox(values, initialState, BaseScreen.skin)
@ -205,15 +222,7 @@ class GameOptionsTable(
addSelectBox("{Starting Era}:", eras, gameParameters.startingEra)
{ gameParameters.startingEra = it; null }
}
private fun Table.addMaxTurnsSelectBox() {
if (!gameParameters.victoryTypes.contains(VictoryType.Time)) return
val maxTurns = listOf(250,300,350,400,450,500,550,600,650,700,750,800,900,1000,1250,1500,2000).map { it.toString() }
addSelectBox( "{Max Turns}:", maxTurns, gameParameters.maxTurns.toString())
{ gameParameters.maxTurns = it.toInt(); null }
}
private fun addVictoryTypeCheckboxes() {
add("{Victory Conditions}:".toLabel()).colspan(2).row()

View File

@ -37,7 +37,7 @@ class DiplomacyOverviewTable (
titleTable.add("Our Civilization:".toLabel()).colspan(2).row()
titleTable.add(ImageGetter.getNationIndicator(viewingPlayer.nation, 25f)).pad(5f)
titleTable.add(viewingPlayer.civName.toLabel()).left().padRight(10f)
titleTable.add(viewingPlayer.calculateScore().toLabel()).row()
titleTable.add(viewingPlayer.calculateScoreBreakdown().values.sum().toInt().toLabel()).row()
val civTableScrollPane = getCivTableScroll(relevantCivs, titleTable, playerKnowsAndUndefeatedCivs, playerKnowsAndDefeatedCivs)
@ -87,7 +87,7 @@ class DiplomacyOverviewTable (
if (it.isCityState()) {
cityStatesParsed++
} else {
civTable.add(it.calculateScore().toLabel()).left()
civTable.add(it.calculateScoreBreakdown().values.sum().toInt().toLabel()).left()
}
if (!it.isCityState() || cityStatesParsed % 2 == 0)
civTable.row()
@ -104,7 +104,7 @@ class DiplomacyOverviewTable (
if (it.isCityState()) {
cityStatesParsed++
} else {
civTable.add(it.calculateScore().toLabel()).left()
civTable.add(it.calculateScoreBreakdown().values.sum().toInt().toLabel()).left()
}
if (!it.isCityState() || cityStatesParsed % 2 == 0)
civTable.row()

View File

@ -5,7 +5,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.Slider
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.ruleset.ModOptionsConstants
import com.unciv.models.translations.tr
import com.unciv.ui.utils.*
import kotlin.math.roundToInt
@ -13,7 +12,6 @@ class StatsOverviewTable (
private val viewingPlayer: CivilizationInfo,
private val overviewScreen: EmpireOverviewScreen
) : Table() {
//val game = overviewScreen.game
init {
defaults().pad(40f)
@ -21,6 +19,7 @@ class StatsOverviewTable (
add(getGoldTable()).top()
add(getScienceTable()).top()
add(getGreatPeopleTable()).top()
add(getScoreTable()).top()
}
private fun getHappinessTable(): Table {
@ -35,10 +34,10 @@ class StatsOverviewTable (
val happinessBreakdown = viewingPlayer.stats().getHappinessBreakdown()
for (entry in happinessBreakdown.filterNot { it.value.roundToInt()==0 }) {
happinessTable.add(entry.key.tr())
happinessTable.add(entry.key.toLabel())
happinessTable.add(entry.value.roundToInt().toString()).right().row()
}
happinessTable.add("Total".tr())
happinessTable.add("Total".toLabel())
happinessTable.add(happinessBreakdown.values.sum().roundToInt().toString()).right()
happinessTable.pack()
return happinessTable
@ -55,11 +54,11 @@ class StatsOverviewTable (
var total = 0f
for (entry in viewingPlayer.stats().getStatMapForNextTurn()) {
if (entry.value.gold == 0f) continue
goldTable.add(entry.key.tr())
goldTable.add(entry.key.toLabel())
goldTable.add(entry.value.gold.roundToInt().toString()).right().row()
total += entry.value.gold
}
goldTable.add("Total".tr())
goldTable.add("Total".toLabel())
goldTable.add(total.roundToInt().toString()).right()
if (viewingPlayer.gameInfo.ruleSet.modOptions.uniques.contains(ModOptionsConstants.convertGoldToScience)) {
@ -93,10 +92,10 @@ class StatsOverviewTable (
val scienceStats = viewingPlayer.stats().getStatMapForNextTurn()
.filter { it.value.science != 0f }
for (entry in scienceStats) {
scienceTable.add(entry.key.tr())
scienceTable.add(entry.key.toLabel())
scienceTable.add(entry.value.science.roundToInt().toString()).right().row()
}
scienceTable.add("Total".tr())
scienceTable.add("Total".toLabel())
scienceTable.add(scienceStats.map { it.value.science }.sum().roundToInt().toString()).right()
scienceTable.pack()
return scienceTable
@ -114,23 +113,43 @@ class StatsOverviewTable (
greatPeopleTable.add(greatPeopleHeader).colspan(3).row()
greatPeopleTable.addSeparator()
greatPeopleTable.add()
greatPeopleTable.add("Current points".tr())
greatPeopleTable.add("Points per turn".tr()).row()
greatPeopleTable.add("Current points".toLabel())
greatPeopleTable.add("Points per turn".toLabel()).row()
val greatPersonPoints = viewingPlayer.greatPeople.greatPersonPointsCounter
val greatPersonPointsPerTurn = viewingPlayer.getGreatPersonPointsForNextTurn()
val pointsToGreatPerson = viewingPlayer.greatPeople.pointsForNextGreatPerson
for((greatPerson, points) in greatPersonPoints) {
greatPeopleTable.add(greatPerson.tr())
greatPeopleTable.add(greatPerson.toLabel())
greatPeopleTable.add("$points/$pointsToGreatPerson")
greatPeopleTable.add(greatPersonPointsPerTurn[greatPerson].toString()).row()
}
val pointsForGreatGeneral = viewingPlayer.greatPeople.greatGeneralPoints
val pointsForNextGreatGeneral = viewingPlayer.greatPeople.pointsForNextGreatGeneral
greatPeopleTable.add("Great General".tr())
greatPeopleTable.add("Great General".toLabel())
greatPeopleTable.add("$pointsForGreatGeneral/$pointsForNextGreatGeneral").row()
greatPeopleTable.pack()
return greatPeopleTable
}
private fun getScoreTable(): Table {
val scoreTableHeader = Table(BaseScreen.skin)
scoreTableHeader.add("Score".toLabel(fontSize = 24)).padBottom(6f)
val scoreTable = Table(BaseScreen.skin)
scoreTable.defaults().pad(5f)
scoreTable.add(scoreTableHeader).colspan(2).row()
scoreTable.addSeparator()
val scoreBreakdown = viewingPlayer.calculateScoreBreakdown().filter { it.value != 0.0 }
for ((label, value) in scoreBreakdown) {
scoreTable.add(label.toLabel())
scoreTable.add(value.toInt().toLabel()).row()
}
scoreTable.add("Total".toLabel())
scoreTable.add(scoreBreakdown.values.sum().toInt().toLabel())
return scoreTable
}
}

View File

@ -73,15 +73,21 @@ class UncivSlider (
slider.stepSize = value
stepChanged()
}
/** Returns true if the slider is being dragged. */
val isDragging: Boolean
get() = slider.isDragging
var isDisabled: Boolean
get() = slider.isDisabled
set(value) { slider.isDisabled = value }
/** Sets the range of this progress bar. The progress bar's current value is clamped to the range. */
fun setRange(min: Float, max: Float) {
slider.setRange(min, max)
setPlusMinusEnabled()
}
/** Will make this progress bar snap to the specified values, if the knob is within the threshold. */
fun setSnapToValues(values: FloatArray?, threshold: Float) {
slider.setSnapToValues(values, threshold)
}
// Value tip format
var tipFormat = "%.1f"