mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-22 13:49:54 +07:00
Converted the "special power" of the Future Tech to a unique than can be applied to any tech
This commit is contained in:
@ -612,7 +612,7 @@
|
|||||||
"name": "Future Tech",
|
"name": "Future Tech",
|
||||||
"row": 5,
|
"row": 5,
|
||||||
"prerequisites": ["Nanotechnology","Particle Physics","Satellites"],
|
"prerequisites": ["Nanotechnology","Particle Physics","Satellites"],
|
||||||
"uniques": ["Who knows what the future holds?"],
|
"uniques": ["Who knows what the future holds?", "Can be continually researched"],
|
||||||
"quote": "'I think we agree, the past is over.' - George W. Bush"
|
"quote": "'I think we agree, the past is over.' - George W. Bush"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -14,7 +14,6 @@ import com.unciv.logic.trade.*
|
|||||||
import com.unciv.models.ruleset.VictoryType
|
import com.unciv.models.ruleset.VictoryType
|
||||||
import com.unciv.models.ruleset.tech.Technology
|
import com.unciv.models.ruleset.tech.Technology
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
import java.lang.reflect.Modifier
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
object NextTurnAutomation{
|
object NextTurnAutomation{
|
||||||
@ -153,27 +152,24 @@ object NextTurnAutomation{
|
|||||||
private fun chooseTechToResearch(civInfo: CivilizationInfo) {
|
private fun chooseTechToResearch(civInfo: CivilizationInfo) {
|
||||||
if (civInfo.tech.techsToResearch.isEmpty()) {
|
if (civInfo.tech.techsToResearch.isEmpty()) {
|
||||||
val researchableTechs = civInfo.gameInfo.ruleSet.technologies.values
|
val researchableTechs = civInfo.gameInfo.ruleSet.technologies.values
|
||||||
.filter { !civInfo.tech.isResearched(it.name) && civInfo.tech.canBeResearched(it.name) }
|
.filter { civInfo.tech.canBeResearched(it.name) }
|
||||||
val techsGroups = researchableTechs.groupBy { it.cost }
|
val techsGroups = researchableTechs.groupBy { it.cost }
|
||||||
val costs = techsGroups.keys.sorted()
|
val costs = techsGroups.keys.sorted()
|
||||||
|
|
||||||
val tech: Technology
|
if (researchableTechs.isEmpty()) return
|
||||||
if (researchableTechs.isEmpty()) { // no non-researched techs available, go for future tech
|
|
||||||
civInfo.tech.techsToResearch.add(Constants.futureTech)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val techsCheapest = techsGroups[costs[0]]!!
|
val cheapestTechs = techsGroups[costs[0]]!!
|
||||||
//Do not consider advanced techs if only one tech left in cheapest groupe
|
//Do not consider advanced techs if only one tech left in cheapest groupe
|
||||||
if (techsCheapest.size == 1 || costs.size == 1) {
|
val techToResearch: Technology
|
||||||
tech = techsCheapest.random()
|
if (cheapestTechs.size == 1 || costs.size == 1) {
|
||||||
|
techToResearch = cheapestTechs.random()
|
||||||
} else {
|
} else {
|
||||||
//Choose randomly between cheapest and second cheapest groupe
|
//Choose randomly between cheapest and second cheapest groupe
|
||||||
val techsAdvanced = techsGroups[costs[1]]!!
|
val techsAdvanced = techsGroups[costs[1]]!!
|
||||||
tech = (techsCheapest + techsAdvanced).random()
|
techToResearch = (cheapestTechs + techsAdvanced).random()
|
||||||
}
|
}
|
||||||
|
|
||||||
civInfo.tech.techsToResearch.add(tech.name)
|
civInfo.tech.techsToResearch.add(techToResearch.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,8 +60,10 @@ class TechManager {
|
|||||||
if (civInfo.isPlayerCivilization())
|
if (civInfo.isPlayerCivilization())
|
||||||
techCost *= civInfo.getDifficulty().researchCostModifier
|
techCost *= civInfo.getDifficulty().researchCostModifier
|
||||||
techCost *= civInfo.gameInfo.gameParameters.gameSpeed.modifier
|
techCost *= civInfo.gameInfo.gameParameters.gameSpeed.modifier
|
||||||
val techsResearchedKnownCivs = civInfo.getKnownCivs().count { it.isMajorCiv() && it.tech.isResearched(techName) }
|
val techsResearchedKnownCivs = civInfo.getKnownCivs()
|
||||||
val undefeatedCivs = civInfo.gameInfo.civilizations.count { it.isMajorCiv() && !it.isDefeated() }
|
.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/
|
// https://forums.civfanatics.com/threads/the-mechanics-of-overflow-inflation.517970/
|
||||||
techCost /= 1 + techsResearchedKnownCivs / undefeatedCivs.toFloat() * 0.3f
|
techCost /= 1 + techsResearchedKnownCivs / undefeatedCivs.toFloat() * 0.3f
|
||||||
// http://www.civclub.net/bbs/forum.php?mod=viewthread&tid=123976
|
// http://www.civclub.net/bbs/forum.php?mod=viewthread&tid=123976
|
||||||
@ -96,10 +98,13 @@ class TechManager {
|
|||||||
return max(1, ceil(remainingScienceToTech(techName).toDouble() / civInfo.statsForNextTurn.science).toInt())
|
return max(1, ceil(remainingScienceToTech(techName).toDouble() / civInfo.statsForNextTurn.science).toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isResearched(TechName: String): Boolean = techsResearched.contains(TechName)
|
fun isResearched(techName: String): Boolean = techsResearched.contains(techName)
|
||||||
|
|
||||||
fun canBeResearched(TechName: String): Boolean {
|
fun canBeResearched(techName: String): Boolean {
|
||||||
return getRuleset().technologies[TechName]!!.prerequisites.all { isResearched(it) }
|
val tech = getRuleset().technologies[techName]!!
|
||||||
|
if (isResearched(tech.name) && !tech.isContinuallyResearchable())
|
||||||
|
return false
|
||||||
|
return tech.prerequisites.all { isResearched(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTechUniques() = researchedTechUniques
|
fun getTechUniques() = researchedTechUniques
|
||||||
@ -116,7 +121,7 @@ class TechManager {
|
|||||||
val techToCheck = checkPrerequisites.pop()
|
val techToCheck = checkPrerequisites.pop()
|
||||||
// future tech can have been researched even when we're researching it,
|
// future tech can have been researched even when we're researching it,
|
||||||
// so...if we skip it we'll end up with 0 techs in the "required techs", which will mean that we don't have anything to research. Yeah.
|
// so...if we skip it we'll end up with 0 techs in the "required techs", which will mean that we don't have anything to research. Yeah.
|
||||||
if (techToCheck.name != Constants.futureTech &&
|
if (!techToCheck.isContinuallyResearchable() &&
|
||||||
(isResearched(techToCheck.name) || prerequisites.contains(techToCheck)))
|
(isResearched(techToCheck.name) || prerequisites.contains(techToCheck)))
|
||||||
continue //no need to add or check prerequisites
|
continue //no need to add or check prerequisites
|
||||||
for (prerequisite in techToCheck.prerequisites)
|
for (prerequisite in techToCheck.prerequisites)
|
||||||
@ -204,8 +209,6 @@ class TechManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addTechnology(techName: String) {
|
fun addTechnology(techName: String) {
|
||||||
if (techName != Constants.futureTech)
|
|
||||||
techsToResearch.remove(techName)
|
|
||||||
techsInProgress.remove(techName)
|
techsInProgress.remove(techName)
|
||||||
|
|
||||||
val previousEra = civInfo.getEra()
|
val previousEra = civInfo.getEra()
|
||||||
@ -213,6 +216,8 @@ class TechManager {
|
|||||||
|
|
||||||
// this is to avoid concurrent modification problems
|
// this is to avoid concurrent modification problems
|
||||||
val newTech = getRuleset().technologies[techName]!!
|
val newTech = getRuleset().technologies[techName]!!
|
||||||
|
if (!newTech.isContinuallyResearchable())
|
||||||
|
techsToResearch.remove(techName)
|
||||||
researchedTechnologies = researchedTechnologies.withItem(newTech)
|
researchedTechnologies = researchedTechnologies.withItem(newTech)
|
||||||
for (unique in newTech.uniques)
|
for (unique in newTech.uniques)
|
||||||
researchedTechUniques = researchedTechUniques.withItem(unique)
|
researchedTechUniques = researchedTechUniques.withItem(unique)
|
||||||
@ -325,4 +330,8 @@ class TechManager {
|
|||||||
|
|
||||||
return if (canBuildRailroad) RoadStatus.Railroad else RoadStatus.Road
|
return if (canBuildRailroad) RoadStatus.Railroad else RoadStatus.Road
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun canResearchTech(): Boolean {
|
||||||
|
return getRuleset().technologies.values.any { canBeResearched(it.name) }
|
||||||
|
}
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ class Technology {
|
|||||||
|
|
||||||
var column: TechColumn? = null // The column that this tech is in the tech tree
|
var column: TechColumn? = null // The column that this tech is in the tech tree
|
||||||
var row: Int = 0
|
var row: Int = 0
|
||||||
var quote=""
|
var quote = ""
|
||||||
|
|
||||||
fun getDescription(ruleset: Ruleset): String {
|
fun getDescription(ruleset: Ruleset): String {
|
||||||
val lineList = ArrayList<String>() // more readable than StringBuilder, with same performance for our use-case
|
val lineList = ArrayList<String>() // more readable than StringBuilder, with same performance for our use-case
|
||||||
@ -81,12 +81,12 @@ class Technology {
|
|||||||
return enabledBuildings
|
return enabledBuildings
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEnabledUnits(civInfo:CivilizationInfo): List<BaseUnit> {
|
fun getEnabledUnits(civInfo: CivilizationInfo): List<BaseUnit> {
|
||||||
var enabledUnits = civInfo.gameInfo.ruleSet.units.values.filter {
|
var enabledUnits = civInfo.gameInfo.ruleSet.units.values.filter {
|
||||||
it.requiredTech == name &&
|
it.requiredTech == name &&
|
||||||
(it.uniqueTo == null || it.uniqueTo == civInfo.civName)
|
(it.uniqueTo == null || it.uniqueTo == civInfo.civName)
|
||||||
}
|
}
|
||||||
val replacedUnits = civInfo.gameInfo.ruleSet.units.values.filter { it.uniqueTo==civInfo.civName }
|
val replacedUnits = civInfo.gameInfo.ruleSet.units.values.filter { it.uniqueTo == civInfo.civName }
|
||||||
.mapNotNull { it.replaces }
|
.mapNotNull { it.replaces }
|
||||||
enabledUnits = enabledUnits.filter { it.name !in replacedUnits }
|
enabledUnits = enabledUnits.filter { it.name !in replacedUnits }
|
||||||
|
|
||||||
@ -96,9 +96,9 @@ class Technology {
|
|||||||
return enabledUnits
|
return enabledUnits
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString() = name
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
fun era(): String = column!!.era
|
fun era(): String = column!!.era
|
||||||
|
|
||||||
|
fun isContinuallyResearchable() = uniques.contains("Can be continually researched")
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ class TechPickerScreen(internal val civInfo: CivilizationInfo, centerOnTech: Tec
|
|||||||
|
|
||||||
// All these are to counter performance problems when updating buttons for all techs.
|
// All these are to counter performance problems when updating buttons for all techs.
|
||||||
private var researchableTechs = civInfo.gameInfo.ruleSet.technologies.keys
|
private var researchableTechs = civInfo.gameInfo.ruleSet.technologies.keys
|
||||||
.filter { civTech.canBeResearched(it) && !civTech.isResearched(it) }.toHashSet()
|
.filter { civTech.canBeResearched(it) }.toHashSet()
|
||||||
|
|
||||||
private val currentTechColor = colorFromRGB(7,46,43)
|
private val currentTechColor = colorFromRGB(7,46,43)
|
||||||
private val researchedTechColor = colorFromRGB(133,112,39)
|
private val researchedTechColor = colorFromRGB(133,112,39)
|
||||||
@ -170,7 +170,7 @@ class TechPickerScreen(internal val civInfo: CivilizationInfo, centerOnTech: Tec
|
|||||||
prerequisiteCoords.x, prerequisiteCoords.y, 2f)
|
prerequisiteCoords.x, prerequisiteCoords.y, 2f)
|
||||||
|
|
||||||
val lineColor = when {
|
val lineColor = when {
|
||||||
civTech.isResearched(tech.name) && tech.name != Constants.futureTech -> researchedTechColor
|
civTech.isResearched(tech.name) && !tech.isContinuallyResearchable() -> researchedTechColor
|
||||||
civTech.isResearched(prerequisite) -> researchableTechColor
|
civTech.isResearched(prerequisite) -> researchableTechColor
|
||||||
else -> Color.GRAY
|
else -> Color.GRAY
|
||||||
}
|
}
|
||||||
@ -210,7 +210,7 @@ class TechPickerScreen(internal val civInfo: CivilizationInfo, centerOnTech: Tec
|
|||||||
civInfo.tech.addTechnology(tech.name)
|
civInfo.tech.addTechnology(tech.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (civTech.isResearched(tech.name) && tech.name != Constants.futureTech) {
|
if (civTech.isResearched(tech.name) && !tech.isContinuallyResearchable()) {
|
||||||
rightSideButton.setText("Pick a tech".tr())
|
rightSideButton.setText("Pick a tech".tr())
|
||||||
rightSideButton.disable()
|
rightSideButton.disable()
|
||||||
setButtonsInfo()
|
setButtonsInfo()
|
||||||
@ -242,8 +242,7 @@ class TechPickerScreen(internal val civInfo: CivilizationInfo, centerOnTech: Tec
|
|||||||
|
|
||||||
|
|
||||||
private fun selectTechnologyForFreeTech(tech: Technology) {
|
private fun selectTechnologyForFreeTech(tech: Technology) {
|
||||||
if (researchableTechs.contains(tech.name) ||
|
if (researchableTechs.contains(tech.name)) {
|
||||||
(tech.name==Constants.futureTech && civTech.canBeResearched(tech.name))) {
|
|
||||||
pick("Pick [${selectedTech!!.name}] as free tech".tr())
|
pick("Pick [${selectedTech!!.name}] as free tech".tr())
|
||||||
} else {
|
} else {
|
||||||
rightSideButton.setText("Pick a free tech".tr())
|
rightSideButton.setText("Pick a free tech".tr())
|
||||||
|
@ -439,11 +439,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
techButtonHolder.isVisible = viewingCiv.cities.isNotEmpty()
|
techButtonHolder.isVisible = viewingCiv.cities.isNotEmpty()
|
||||||
techButtonHolder.clearChildren()
|
techButtonHolder.clearChildren()
|
||||||
|
|
||||||
val researchableTechs = viewingCiv.gameInfo.ruleSet.technologies.values.filter { !viewingCiv.tech.isResearched(it.name) && viewingCiv.tech.canBeResearched(it.name) }
|
if (viewingCiv.tech.currentTechnology() == null && viewingCiv.tech.canResearchTech()) {
|
||||||
if (viewingCiv.tech.currentTechnology() == null && researchableTechs.isEmpty())
|
|
||||||
viewingCiv.tech.techsToResearch.add(Constants.futureTech)
|
|
||||||
|
|
||||||
if (viewingCiv.tech.currentTechnology() == null) {
|
|
||||||
val buttonPic = Table()
|
val buttonPic = Table()
|
||||||
buttonPic.background = ImageGetter.getRoundedEdgeTableBackground(colorFromRGB(7, 46, 43))
|
buttonPic.background = ImageGetter.getRoundedEdgeTableBackground(colorFromRGB(7, 46, 43))
|
||||||
buttonPic.defaults().pad(20f)
|
buttonPic.defaults().pad(20f)
|
||||||
|
Reference in New Issue
Block a user