mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-10 07:48:31 +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
|
||||
|
||||
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 [amount] cities! =
|
||||
[cityName] changed production from [oldUnit] to [newUnit] =
|
||||
|
@ -90,6 +90,19 @@ class TechManager : IsPartOfGameInfoSerialization {
|
||||
|
||||
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
|
||||
|
||||
fun costOfTech(techName: String): Int {
|
||||
@ -97,12 +110,7 @@ class TechManager : IsPartOfGameInfoSerialization {
|
||||
if (civInfo.isHuman())
|
||||
techCost *= civInfo.getDifficulty().researchCostModifier
|
||||
techCost *= civInfo.gameInfo.speed.scienceCostModifier
|
||||
val techsResearchedKnownCivs = civInfo.getKnownCivs()
|
||||
.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
|
||||
techCost /= getScienceModifier(techName)
|
||||
// https://civilization.fandom.com/wiki/Map_(Civ5)
|
||||
val worldSizeModifier = with (civInfo.gameInfo.tileMap.mapParameters.mapSize) {
|
||||
when {
|
||||
@ -129,11 +137,18 @@ class TechManager : IsPartOfGameInfoSerialization {
|
||||
fun researchOfTech(TechName: String?) = techsInProgress[TechName] ?: 0
|
||||
// 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 -> "∞"
|
||||
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)
|
||||
@ -213,15 +228,15 @@ class TechManager : IsPartOfGameInfoSerialization {
|
||||
var finalScienceToAdd = scienceForNewTurn
|
||||
|
||||
if (scienceFromResearchAgreements != 0) {
|
||||
finalScienceToAdd += scienceFromResearchAgreements()
|
||||
val scienceBoost = scienceFromResearchAgreements()
|
||||
finalScienceToAdd += scienceBoost
|
||||
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/
|
||||
val techsResearchedKnownCivs = civInfo.getKnownCivs()
|
||||
.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
|
||||
if (overflowScience != 0) {
|
||||
finalScienceToAdd += getOverflowScience(currentTechnologyName()!!)
|
||||
overflowScience = 0
|
||||
}
|
||||
|
||||
@ -241,6 +256,20 @@ class TechManager : IsPartOfGameInfoSerialization {
|
||||
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) {
|
||||
freeTechs--
|
||||
addTechnology(techName)
|
||||
@ -301,6 +330,7 @@ class TechManager : IsPartOfGameInfoSerialization {
|
||||
}
|
||||
|
||||
moveToNewEra()
|
||||
updateResearchProgress()
|
||||
}
|
||||
|
||||
private fun obsoleteOldUnits(techName: String) {
|
||||
|
@ -30,6 +30,9 @@ class TurnManager(val civInfo: Civilization) {
|
||||
civInfo.statsHistory.recordRankingStats(civInfo)
|
||||
}
|
||||
|
||||
if (civInfo.cities.isNotEmpty() && civInfo.gameInfo.ruleset.technologies.isNotEmpty())
|
||||
civInfo.tech.updateResearchProgress()
|
||||
|
||||
civInfo.civConstructions.startTurn()
|
||||
civInfo.attacksSinceTurnStart.clear()
|
||||
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
|
||||
|
||||
civTech.updateResearchProgress()
|
||||
|
||||
game.settings.addCompletedTutorialTask("Pick technology")
|
||||
|
||||
game.popScreen()
|
||||
@ -424,7 +426,7 @@ class TechPickerScreen(
|
||||
}
|
||||
|
||||
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) }
|
||||
return "(${progress}/${techCost})"
|
||||
}
|
||||
|
Reference in New Issue
Block a user