mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-30 07:21:34 -04:00
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:
parent
ecadfb53fa
commit
f3a2edf390
@ -3,10 +3,8 @@ package com.unciv.logic
|
|||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.BackwardCompatibility.removeMissingModReferences
|
import com.unciv.logic.BackwardCompatibility.removeMissingModReferences
|
||||||
import com.unciv.logic.BackwardCompatibility.replaceDiplomacyFlag
|
|
||||||
import com.unciv.logic.automation.NextTurnAutomation
|
import com.unciv.logic.automation.NextTurnAutomation
|
||||||
import com.unciv.logic.civilization.*
|
import com.unciv.logic.civilization.*
|
||||||
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
|
|
||||||
import com.unciv.logic.city.CityInfo
|
import com.unciv.logic.city.CityInfo
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.logic.map.TileMap
|
import com.unciv.logic.map.TileMap
|
||||||
@ -290,7 +288,7 @@ class GameInfo {
|
|||||||
|
|
||||||
val winningCiv = civilizations
|
val winningCiv = civilizations
|
||||||
.filter { it.isMajorCiv() && !it.isSpectator() && !it.isBarbarian() }
|
.filter { it.isMajorCiv() && !it.isSpectator() && !it.isBarbarian() }
|
||||||
.maxByOrNull { it.calculateScore() }
|
.maxByOrNull { it.calculateScoreBreakdown().values.sum() }
|
||||||
?: return // Are there no civs left?
|
?: return // Are there no civs left?
|
||||||
|
|
||||||
winningCiv.victoryManager.hasWonTimeVictory = true
|
winningCiv.victoryManager.hasWonTimeVictory = true
|
||||||
|
@ -613,7 +613,7 @@ class CivilizationInfo {
|
|||||||
|
|
||||||
fun getStatForRanking(category: RankingType): Int {
|
fun getStatForRanking(category: RankingType): Int {
|
||||||
return when (category) {
|
return when (category) {
|
||||||
RankingType.Score -> calculateScore()
|
RankingType.Score -> calculateScoreBreakdown().values.sum().toInt()
|
||||||
RankingType.Population -> cities.sumOf { it.population.population }
|
RankingType.Population -> cities.sumOf { it.population.population }
|
||||||
RankingType.Crop_Yield -> statsForNextTurn.food.roundToInt()
|
RankingType.Crop_Yield -> statsForNextTurn.food.roundToInt()
|
||||||
RankingType.Production -> statsForNextTurn.production.roundToInt()
|
RankingType.Production -> statsForNextTurn.production.roundToInt()
|
||||||
@ -668,25 +668,25 @@ class CivilizationInfo {
|
|||||||
}
|
}
|
||||||
fun isLongCountDisplay() = hasLongCountDisplayUnique && isLongCountActive()
|
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,
|
// 1276 is the number of tiles in a medium sized map. The original uses 4160 for this,
|
||||||
// but they have bigger maps
|
// but they have bigger maps
|
||||||
var mapSizeModifier = 1276.0 / gameInfo.tileMap.mapParameters.numberOfTiles()
|
var mapSizeModifier = 1276 / gameInfo.tileMap.mapParameters.numberOfTiles().toDouble()
|
||||||
if (mapSizeModifier > 1)
|
if (mapSizeModifier > 1)
|
||||||
mapSizeModifier = (mapSizeModifier - 1) / 3 + 1
|
mapSizeModifier = (mapSizeModifier - 1) / 3 + 1
|
||||||
|
|
||||||
var score = 0.0
|
scoreBreakdown["Cities"] = cities.count() * 10 * mapSizeModifier
|
||||||
score += cities.count() * 10 * mapSizeModifier
|
scoreBreakdown["Population"] = cities.sumOf { it.population.population } * 3 * mapSizeModifier
|
||||||
score += cities.sumOf { it.population.population } * 3 * mapSizeModifier
|
scoreBreakdown["Tiles"] = cities.sumOf { city -> city.getTiles().filter { !it.isWater}.count() } * 1 * mapSizeModifier
|
||||||
score += cities.sumOf { city -> city.getTiles().filter { !it.isWater}.count() } * 1 * mapSizeModifier
|
scoreBreakdown["Wonders"] = 40 * cities
|
||||||
score += 40 * cities
|
|
||||||
.sumOf { city -> city.cityConstructions.builtBuildings
|
.sumOf { city -> city.cityConstructions.builtBuildings
|
||||||
.filter { gameInfo.ruleSet.buildings[it]!!.isWonder }.count()
|
.filter { gameInfo.ruleSet.buildings[it]!!.isWonder }.count()
|
||||||
}
|
}.toDouble()
|
||||||
score += tech.getNumberOfTechsResearched() * 4
|
scoreBreakdown["Techs"] = tech.getNumberOfTechsResearched() * 4.toDouble()
|
||||||
score += tech.repeatingTechsResearched * 10
|
scoreBreakdown["Future Tech"] = tech.repeatingTechsResearched * 10.toDouble()
|
||||||
|
|
||||||
return score.toInt()
|
return scoreBreakdown
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
@ -53,6 +53,7 @@ class GameParameters { // Default values are the default new game
|
|||||||
parameters.isOnlineMultiplayer = isOnlineMultiplayer
|
parameters.isOnlineMultiplayer = isOnlineMultiplayer
|
||||||
parameters.baseRuleset = baseRuleset
|
parameters.baseRuleset = baseRuleset
|
||||||
parameters.mods = LinkedHashSet(mods)
|
parameters.mods = LinkedHashSet(mods)
|
||||||
|
parameters.maxTurns = maxTurns
|
||||||
return parameters
|
return parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,9 +49,11 @@ class GameOptionsTable(
|
|||||||
addDifficultySelectBox()
|
addDifficultySelectBox()
|
||||||
addGameSpeedSelectBox()
|
addGameSpeedSelectBox()
|
||||||
addEraSelectBox()
|
addEraSelectBox()
|
||||||
addMaxTurnsSelectBox()
|
|
||||||
// align left and right edges with other SelectBoxes but allow independent dropdown width
|
// align left and right edges with other SelectBoxes but allow independent dropdown width
|
||||||
add(Table().apply {
|
add(Table().apply {
|
||||||
|
val turnSlider = addMaxTurnsSlider()
|
||||||
|
if (turnSlider != null)
|
||||||
|
add(turnSlider).padTop(10f).row()
|
||||||
cityStateSlider = addCityStatesSlider()
|
cityStateSlider = addCityStatesSlider()
|
||||||
}).colspan(2).fillX().row()
|
}).colspan(2).fillX().row()
|
||||||
}).row()
|
}).row()
|
||||||
@ -130,6 +132,21 @@ class GameOptionsTable(
|
|||||||
return slider
|
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?) {
|
private fun Table.addSelectBox(text: String, values: Collection<String>, initialState: String, onChange: (newValue: String) -> String?) {
|
||||||
add(text.toLabel()).left()
|
add(text.toLabel()).left()
|
||||||
val selectBox = TranslatedSelectBox(values, initialState, BaseScreen.skin)
|
val selectBox = TranslatedSelectBox(values, initialState, BaseScreen.skin)
|
||||||
@ -206,14 +223,6 @@ class GameOptionsTable(
|
|||||||
{ gameParameters.startingEra = it; null }
|
{ 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() {
|
private fun addVictoryTypeCheckboxes() {
|
||||||
add("{Victory Conditions}:".toLabel()).colspan(2).row()
|
add("{Victory Conditions}:".toLabel()).colspan(2).row()
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class DiplomacyOverviewTable (
|
|||||||
titleTable.add("Our Civilization:".toLabel()).colspan(2).row()
|
titleTable.add("Our Civilization:".toLabel()).colspan(2).row()
|
||||||
titleTable.add(ImageGetter.getNationIndicator(viewingPlayer.nation, 25f)).pad(5f)
|
titleTable.add(ImageGetter.getNationIndicator(viewingPlayer.nation, 25f)).pad(5f)
|
||||||
titleTable.add(viewingPlayer.civName.toLabel()).left().padRight(10f)
|
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)
|
val civTableScrollPane = getCivTableScroll(relevantCivs, titleTable, playerKnowsAndUndefeatedCivs, playerKnowsAndDefeatedCivs)
|
||||||
@ -87,7 +87,7 @@ class DiplomacyOverviewTable (
|
|||||||
if (it.isCityState()) {
|
if (it.isCityState()) {
|
||||||
cityStatesParsed++
|
cityStatesParsed++
|
||||||
} else {
|
} else {
|
||||||
civTable.add(it.calculateScore().toLabel()).left()
|
civTable.add(it.calculateScoreBreakdown().values.sum().toInt().toLabel()).left()
|
||||||
}
|
}
|
||||||
if (!it.isCityState() || cityStatesParsed % 2 == 0)
|
if (!it.isCityState() || cityStatesParsed % 2 == 0)
|
||||||
civTable.row()
|
civTable.row()
|
||||||
@ -104,7 +104,7 @@ class DiplomacyOverviewTable (
|
|||||||
if (it.isCityState()) {
|
if (it.isCityState()) {
|
||||||
cityStatesParsed++
|
cityStatesParsed++
|
||||||
} else {
|
} else {
|
||||||
civTable.add(it.calculateScore().toLabel()).left()
|
civTable.add(it.calculateScoreBreakdown().values.sum().toInt().toLabel()).left()
|
||||||
}
|
}
|
||||||
if (!it.isCityState() || cityStatesParsed % 2 == 0)
|
if (!it.isCityState() || cityStatesParsed % 2 == 0)
|
||||||
civTable.row()
|
civTable.row()
|
||||||
|
@ -5,7 +5,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.Slider
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
import com.unciv.models.ruleset.ModOptionsConstants
|
import com.unciv.models.ruleset.ModOptionsConstants
|
||||||
import com.unciv.models.translations.tr
|
|
||||||
import com.unciv.ui.utils.*
|
import com.unciv.ui.utils.*
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@ -13,7 +12,6 @@ class StatsOverviewTable (
|
|||||||
private val viewingPlayer: CivilizationInfo,
|
private val viewingPlayer: CivilizationInfo,
|
||||||
private val overviewScreen: EmpireOverviewScreen
|
private val overviewScreen: EmpireOverviewScreen
|
||||||
) : Table() {
|
) : Table() {
|
||||||
//val game = overviewScreen.game
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
defaults().pad(40f)
|
defaults().pad(40f)
|
||||||
@ -21,6 +19,7 @@ class StatsOverviewTable (
|
|||||||
add(getGoldTable()).top()
|
add(getGoldTable()).top()
|
||||||
add(getScienceTable()).top()
|
add(getScienceTable()).top()
|
||||||
add(getGreatPeopleTable()).top()
|
add(getGreatPeopleTable()).top()
|
||||||
|
add(getScoreTable()).top()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getHappinessTable(): Table {
|
private fun getHappinessTable(): Table {
|
||||||
@ -35,10 +34,10 @@ class StatsOverviewTable (
|
|||||||
val happinessBreakdown = viewingPlayer.stats().getHappinessBreakdown()
|
val happinessBreakdown = viewingPlayer.stats().getHappinessBreakdown()
|
||||||
|
|
||||||
for (entry in happinessBreakdown.filterNot { it.value.roundToInt()==0 }) {
|
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(entry.value.roundToInt().toString()).right().row()
|
||||||
}
|
}
|
||||||
happinessTable.add("Total".tr())
|
happinessTable.add("Total".toLabel())
|
||||||
happinessTable.add(happinessBreakdown.values.sum().roundToInt().toString()).right()
|
happinessTable.add(happinessBreakdown.values.sum().roundToInt().toString()).right()
|
||||||
happinessTable.pack()
|
happinessTable.pack()
|
||||||
return happinessTable
|
return happinessTable
|
||||||
@ -55,11 +54,11 @@ class StatsOverviewTable (
|
|||||||
var total = 0f
|
var total = 0f
|
||||||
for (entry in viewingPlayer.stats().getStatMapForNextTurn()) {
|
for (entry in viewingPlayer.stats().getStatMapForNextTurn()) {
|
||||||
if (entry.value.gold == 0f) continue
|
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()
|
goldTable.add(entry.value.gold.roundToInt().toString()).right().row()
|
||||||
total += entry.value.gold
|
total += entry.value.gold
|
||||||
}
|
}
|
||||||
goldTable.add("Total".tr())
|
goldTable.add("Total".toLabel())
|
||||||
goldTable.add(total.roundToInt().toString()).right()
|
goldTable.add(total.roundToInt().toString()).right()
|
||||||
|
|
||||||
if (viewingPlayer.gameInfo.ruleSet.modOptions.uniques.contains(ModOptionsConstants.convertGoldToScience)) {
|
if (viewingPlayer.gameInfo.ruleSet.modOptions.uniques.contains(ModOptionsConstants.convertGoldToScience)) {
|
||||||
@ -93,10 +92,10 @@ class StatsOverviewTable (
|
|||||||
val scienceStats = viewingPlayer.stats().getStatMapForNextTurn()
|
val scienceStats = viewingPlayer.stats().getStatMapForNextTurn()
|
||||||
.filter { it.value.science != 0f }
|
.filter { it.value.science != 0f }
|
||||||
for (entry in scienceStats) {
|
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(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.add(scienceStats.map { it.value.science }.sum().roundToInt().toString()).right()
|
||||||
scienceTable.pack()
|
scienceTable.pack()
|
||||||
return scienceTable
|
return scienceTable
|
||||||
@ -114,23 +113,43 @@ class StatsOverviewTable (
|
|||||||
greatPeopleTable.add(greatPeopleHeader).colspan(3).row()
|
greatPeopleTable.add(greatPeopleHeader).colspan(3).row()
|
||||||
greatPeopleTable.addSeparator()
|
greatPeopleTable.addSeparator()
|
||||||
greatPeopleTable.add()
|
greatPeopleTable.add()
|
||||||
greatPeopleTable.add("Current points".tr())
|
greatPeopleTable.add("Current points".toLabel())
|
||||||
greatPeopleTable.add("Points per turn".tr()).row()
|
greatPeopleTable.add("Points per turn".toLabel()).row()
|
||||||
|
|
||||||
val greatPersonPoints = viewingPlayer.greatPeople.greatPersonPointsCounter
|
val greatPersonPoints = viewingPlayer.greatPeople.greatPersonPointsCounter
|
||||||
val greatPersonPointsPerTurn = viewingPlayer.getGreatPersonPointsForNextTurn()
|
val greatPersonPointsPerTurn = viewingPlayer.getGreatPersonPointsForNextTurn()
|
||||||
val pointsToGreatPerson = viewingPlayer.greatPeople.pointsForNextGreatPerson
|
val pointsToGreatPerson = viewingPlayer.greatPeople.pointsForNextGreatPerson
|
||||||
|
|
||||||
for((greatPerson, points) in greatPersonPoints) {
|
for((greatPerson, points) in greatPersonPoints) {
|
||||||
greatPeopleTable.add(greatPerson.tr())
|
greatPeopleTable.add(greatPerson.toLabel())
|
||||||
greatPeopleTable.add("$points/$pointsToGreatPerson")
|
greatPeopleTable.add("$points/$pointsToGreatPerson")
|
||||||
greatPeopleTable.add(greatPersonPointsPerTurn[greatPerson].toString()).row()
|
greatPeopleTable.add(greatPersonPointsPerTurn[greatPerson].toString()).row()
|
||||||
}
|
}
|
||||||
val pointsForGreatGeneral = viewingPlayer.greatPeople.greatGeneralPoints
|
val pointsForGreatGeneral = viewingPlayer.greatPeople.greatGeneralPoints
|
||||||
val pointsForNextGreatGeneral = viewingPlayer.greatPeople.pointsForNextGreatGeneral
|
val pointsForNextGreatGeneral = viewingPlayer.greatPeople.pointsForNextGreatGeneral
|
||||||
greatPeopleTable.add("Great General".tr())
|
greatPeopleTable.add("Great General".toLabel())
|
||||||
greatPeopleTable.add("$pointsForGreatGeneral/$pointsForNextGreatGeneral").row()
|
greatPeopleTable.add("$pointsForGreatGeneral/$pointsForNextGreatGeneral").row()
|
||||||
greatPeopleTable.pack()
|
greatPeopleTable.pack()
|
||||||
return greatPeopleTable
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,15 +73,21 @@ class UncivSlider (
|
|||||||
slider.stepSize = value
|
slider.stepSize = value
|
||||||
stepChanged()
|
stepChanged()
|
||||||
}
|
}
|
||||||
|
/** Returns true if the slider is being dragged. */
|
||||||
val isDragging: Boolean
|
val isDragging: Boolean
|
||||||
get() = slider.isDragging
|
get() = slider.isDragging
|
||||||
var isDisabled: Boolean
|
var isDisabled: Boolean
|
||||||
get() = slider.isDisabled
|
get() = slider.isDisabled
|
||||||
set(value) { slider.isDisabled = value }
|
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) {
|
fun setRange(min: Float, max: Float) {
|
||||||
slider.setRange(min, max)
|
slider.setRange(min, max)
|
||||||
setPlusMinusEnabled()
|
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
|
// Value tip format
|
||||||
var tipFormat = "%.1f"
|
var tipFormat = "%.1f"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user