mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-11 16:29:48 +07:00
Improvements in science display (#8990)
* Displaying science overflow * The amount of science from research agreement notification * Check tech progress at the start of a turn * Fixed exception * Better remainingScienceToTech calculation * Multiple technologies can be researched in one turn * Small improvements
This commit is contained in:
@ -788,6 +788,7 @@ You need to restart the game for this change to take effect. =
|
|||||||
# Notifications
|
# Notifications
|
||||||
|
|
||||||
Research of [technologyName] has completed! =
|
Research of [technologyName] has completed! =
|
||||||
|
We gained [amount] Science from Research Agreement =
|
||||||
[construction] has become obsolete and was removed from the queue in [cityName]! =
|
[construction] has become obsolete and was removed from the queue in [cityName]! =
|
||||||
[construction] has become obsolete and was removed from the queue in [amount] cities! =
|
[construction] has become obsolete and was removed from the queue in [amount] cities! =
|
||||||
[cityName] changed production from [oldUnit] to [newUnit] =
|
[cityName] changed production from [oldUnit] to [newUnit] =
|
||||||
|
@ -90,6 +90,19 @@ class TechManager : IsPartOfGameInfoSerialization {
|
|||||||
|
|
||||||
fun getNumberOfTechsResearched(): Int = techsResearched.size
|
fun getNumberOfTechsResearched(): Int = techsResearched.size
|
||||||
|
|
||||||
|
fun getOverflowScience(techName: String): Int {
|
||||||
|
return if (overflowScience == 0) 0
|
||||||
|
else (getScienceModifier(techName) * overflowScience).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getScienceModifier(techName: String): Float { // https://forums.civfanatics.com/threads/the-mechanics-of-overflow-inflation.517970/
|
||||||
|
val techsResearchedKnownCivs = civInfo.getKnownCivs()
|
||||||
|
.count { it.isMajorCiv() && it.tech.isResearched(techName) }
|
||||||
|
val undefeatedCivs = civInfo.gameInfo.civilizations
|
||||||
|
.count { it.isMajorCiv() && !it.isDefeated() }
|
||||||
|
return 1 + techsResearchedKnownCivs / undefeatedCivs.toFloat() * 0.3f
|
||||||
|
}
|
||||||
|
|
||||||
private fun getRuleset() = civInfo.gameInfo.ruleset
|
private fun getRuleset() = civInfo.gameInfo.ruleset
|
||||||
|
|
||||||
fun costOfTech(techName: String): Int {
|
fun costOfTech(techName: String): Int {
|
||||||
@ -97,12 +110,7 @@ class TechManager : IsPartOfGameInfoSerialization {
|
|||||||
if (civInfo.isHuman())
|
if (civInfo.isHuman())
|
||||||
techCost *= civInfo.getDifficulty().researchCostModifier
|
techCost *= civInfo.getDifficulty().researchCostModifier
|
||||||
techCost *= civInfo.gameInfo.speed.scienceCostModifier
|
techCost *= civInfo.gameInfo.speed.scienceCostModifier
|
||||||
val techsResearchedKnownCivs = civInfo.getKnownCivs()
|
techCost /= getScienceModifier(techName)
|
||||||
.count { it.isMajorCiv() && it.tech.isResearched(techName) }
|
|
||||||
val undefeatedCivs = civInfo.gameInfo.civilizations
|
|
||||||
.count { it.isMajorCiv() && !it.isDefeated() }
|
|
||||||
// https://forums.civfanatics.com/threads/the-mechanics-of-overflow-inflation.517970/
|
|
||||||
techCost /= 1 + techsResearchedKnownCivs / undefeatedCivs.toFloat() * 0.3f
|
|
||||||
// https://civilization.fandom.com/wiki/Map_(Civ5)
|
// https://civilization.fandom.com/wiki/Map_(Civ5)
|
||||||
val worldSizeModifier = with (civInfo.gameInfo.tileMap.mapParameters.mapSize) {
|
val worldSizeModifier = with (civInfo.gameInfo.tileMap.mapParameters.mapSize) {
|
||||||
when {
|
when {
|
||||||
@ -129,11 +137,18 @@ class TechManager : IsPartOfGameInfoSerialization {
|
|||||||
fun researchOfTech(TechName: String?) = techsInProgress[TechName] ?: 0
|
fun researchOfTech(TechName: String?) = techsInProgress[TechName] ?: 0
|
||||||
// Was once duplicated as fun scienceSpentOnTech(tech: String): Int
|
// Was once duplicated as fun scienceSpentOnTech(tech: String): Int
|
||||||
|
|
||||||
fun remainingScienceToTech(techName: String) = costOfTech(techName) - researchOfTech(techName)
|
fun remainingScienceToTech(techName: String): Int {
|
||||||
|
val spareScience = if (canBeResearched(techName)) getOverflowScience(techName) else 0
|
||||||
|
return costOfTech(techName) - researchOfTech(techName) - spareScience
|
||||||
|
}
|
||||||
|
|
||||||
fun turnsToTech(techName: String) = when {
|
fun turnsToTech(techName: String): String {
|
||||||
|
val remainingCost = remainingScienceToTech(techName).toDouble()
|
||||||
|
return when {
|
||||||
|
remainingCost <= 0f -> "0"
|
||||||
civInfo.stats.statsForNextTurn.science <= 0f -> "∞"
|
civInfo.stats.statsForNextTurn.science <= 0f -> "∞"
|
||||||
else -> max(1, ceil(remainingScienceToTech(techName).toDouble() / civInfo.stats.statsForNextTurn.science).toInt()).toString()
|
else -> max(1, ceil(remainingCost / civInfo.stats.statsForNextTurn.science).toInt()).toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isResearched(techName: String): Boolean = techsResearched.contains(techName)
|
fun isResearched(techName: String): Boolean = techsResearched.contains(techName)
|
||||||
@ -213,15 +228,15 @@ class TechManager : IsPartOfGameInfoSerialization {
|
|||||||
var finalScienceToAdd = scienceForNewTurn
|
var finalScienceToAdd = scienceForNewTurn
|
||||||
|
|
||||||
if (scienceFromResearchAgreements != 0) {
|
if (scienceFromResearchAgreements != 0) {
|
||||||
finalScienceToAdd += scienceFromResearchAgreements()
|
val scienceBoost = scienceFromResearchAgreements()
|
||||||
|
finalScienceToAdd += scienceBoost
|
||||||
scienceFromResearchAgreements = 0
|
scienceFromResearchAgreements = 0
|
||||||
|
civInfo.addNotification("We gained [$scienceBoost] Science from Research Agreement",
|
||||||
|
NotificationCategory.General,
|
||||||
|
NotificationIcon.Science)
|
||||||
}
|
}
|
||||||
if (overflowScience != 0) { // https://forums.civfanatics.com/threads/the-mechanics-of-overflow-inflation.517970/
|
if (overflowScience != 0) {
|
||||||
val techsResearchedKnownCivs = civInfo.getKnownCivs()
|
finalScienceToAdd += getOverflowScience(currentTechnologyName()!!)
|
||||||
.count { it.isMajorCiv() && it.tech.isResearched(currentTechnologyName()!!) }
|
|
||||||
val undefeatedCivs = civInfo.gameInfo.civilizations.count { it.isMajorCiv() && !it.isDefeated() }
|
|
||||||
val finalScienceFromOverflow = ((1 + techsResearchedKnownCivs / undefeatedCivs.toFloat() * 0.3f) * overflowScience).toInt()
|
|
||||||
finalScienceToAdd += finalScienceFromOverflow
|
|
||||||
overflowScience = 0
|
overflowScience = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,6 +256,20 @@ class TechManager : IsPartOfGameInfoSerialization {
|
|||||||
addTechnology(currentTechnology)
|
addTechnology(currentTechnology)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the research on the current technology can be completed
|
||||||
|
* and, if so, completes the research.
|
||||||
|
*/
|
||||||
|
fun updateResearchProgress() {
|
||||||
|
val currentTechnology = currentTechnologyName() ?: return
|
||||||
|
val realOverflow = getOverflowScience(currentTechnology)
|
||||||
|
val scienceSpent = researchOfTech(currentTechnology) + realOverflow
|
||||||
|
if (scienceSpent >= costOfTech(currentTechnology)) {
|
||||||
|
overflowScience = 0
|
||||||
|
addScience(realOverflow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getFreeTechnology(techName: String) {
|
fun getFreeTechnology(techName: String) {
|
||||||
freeTechs--
|
freeTechs--
|
||||||
addTechnology(techName)
|
addTechnology(techName)
|
||||||
@ -301,6 +330,7 @@ class TechManager : IsPartOfGameInfoSerialization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
moveToNewEra()
|
moveToNewEra()
|
||||||
|
updateResearchProgress()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun obsoleteOldUnits(techName: String) {
|
private fun obsoleteOldUnits(techName: String) {
|
||||||
|
@ -30,6 +30,9 @@ class TurnManager(val civInfo: Civilization) {
|
|||||||
civInfo.statsHistory.recordRankingStats(civInfo)
|
civInfo.statsHistory.recordRankingStats(civInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (civInfo.cities.isNotEmpty() && civInfo.gameInfo.ruleset.technologies.isNotEmpty())
|
||||||
|
civInfo.tech.updateResearchProgress()
|
||||||
|
|
||||||
civInfo.civConstructions.startTurn()
|
civInfo.civConstructions.startTurn()
|
||||||
civInfo.attacksSinceTurnStart.clear()
|
civInfo.attacksSinceTurnStart.clear()
|
||||||
civInfo.updateStatsForNextTurn() // for things that change when turn passes e.g. golden age, city state influence
|
civInfo.updateStatsForNextTurn() // for things that change when turn passes e.g. golden age, city state influence
|
||||||
|
@ -115,6 +115,8 @@ class TechPickerScreen(
|
|||||||
}
|
}
|
||||||
else civTech.techsToResearch = tempTechsToResearch
|
else civTech.techsToResearch = tempTechsToResearch
|
||||||
|
|
||||||
|
civTech.updateResearchProgress()
|
||||||
|
|
||||||
game.settings.addCompletedTutorialTask("Pick technology")
|
game.settings.addCompletedTutorialTask("Pick technology")
|
||||||
|
|
||||||
game.popScreen()
|
game.popScreen()
|
||||||
@ -424,7 +426,7 @@ class TechPickerScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getTechProgressLabel(techs: List<String>): String {
|
private fun getTechProgressLabel(techs: List<String>): String {
|
||||||
val progress = techs.sumOf { tech -> civTech.researchOfTech(tech) }
|
val progress = techs.sumOf { tech -> civTech.researchOfTech(tech) } + civTech.getOverflowScience(techs.first())
|
||||||
val techCost = techs.sumOf { tech -> civInfo.tech.costOfTech(tech) }
|
val techCost = techs.sumOf { tech -> civInfo.tech.costOfTech(tech) }
|
||||||
return "(${progress}/${techCost})"
|
return "(${progress}/${techCost})"
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user