mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-10 15:59:33 +07:00
Generalize production-to-stat conversion uniques (#7342)
* Generalize production to stat conversion enabling uniques * Remove unnecessary code * Rename class * Update sound
This commit is contained in:

committed by
GitHub

parent
1649b236bb
commit
9477b319bc
@ -197,7 +197,7 @@
|
||||
"name": "Guilds",
|
||||
"row": 7,
|
||||
"prerequisites": ["Currency"],
|
||||
"uniques": ["Enables conversion of city production to gold"],
|
||||
"uniques": ["Enables conversion of city production to [Gold]"],
|
||||
"quote": "'The merchants and the traders have come; their profits are pre-ordained...' - Sri Guru Granth Sahib"
|
||||
},
|
||||
{
|
||||
@ -226,7 +226,7 @@
|
||||
"name": "Education",
|
||||
"row": 3,
|
||||
"prerequisites": ["Theology","Civil Service"],
|
||||
"uniques": ["Enables conversion of city production to science","Enables Research agreements"],
|
||||
"uniques": ["Enables conversion of city production to [Science]","Enables Research agreements"],
|
||||
"quote": "'Education is the best provision for old age.' - Aristotle"
|
||||
},
|
||||
{
|
||||
|
@ -170,7 +170,7 @@
|
||||
"name": "Currency",
|
||||
"row": 7,
|
||||
"prerequisites": ["Mathematics"],
|
||||
"uniques": ["Enables conversion of city production to gold"],
|
||||
"uniques": ["Enables conversion of city production to [Gold]"],
|
||||
"quote": "'Better is bread with a happy heart than wealth with vexation.' - Amenemope"
|
||||
},
|
||||
{
|
||||
@ -206,7 +206,7 @@
|
||||
"name": "Education",
|
||||
"row": 3,
|
||||
"prerequisites": ["Theology","Civil Service"],
|
||||
"uniques": ["Enables conversion of city production to science"],
|
||||
"uniques": ["Enables conversion of city production to [Science]"],
|
||||
"quote": "'Education is the best provision for old age.' - Aristotle"
|
||||
},
|
||||
{
|
||||
|
@ -1023,6 +1023,8 @@ Current points =
|
||||
Points per turn =
|
||||
Convert production to gold at a rate of 4 to 1 =
|
||||
Convert production to science at a rate of [rate] to 1 =
|
||||
Convert production to [stat] at a rate of [rate] to 1 =
|
||||
Production to [stat] conversion in cities changed by [relativeAmount]% =
|
||||
The city will not produce anything. =
|
||||
Worked by [cityName] =
|
||||
Lock =
|
||||
|
@ -107,17 +107,22 @@ class CityStats(val cityInfo: CityInfo) {
|
||||
private fun getStatsFromProduction(production: Float): Stats {
|
||||
val stats = Stats()
|
||||
|
||||
when (cityInfo.cityConstructions.currentConstructionFromQueue) {
|
||||
"Gold" -> stats.gold += production / 4
|
||||
"Science" -> stats.science += production * getScienceConversionRate()
|
||||
if (cityInfo.cityConstructions.currentConstructionFromQueue in Stat.statsWithCivWideField.map { it.name }) {
|
||||
val stat = Stat.valueOf(cityInfo.cityConstructions.currentConstructionFromQueue)
|
||||
stats[stat] = production * getStatConversionRate(stat)
|
||||
}
|
||||
return stats
|
||||
}
|
||||
|
||||
fun getScienceConversionRate(): Float {
|
||||
fun getStatConversionRate(stat: Stat): Float {
|
||||
var conversionRate = 1 / 4f
|
||||
if (cityInfo.civInfo.hasUnique(UniqueType.ProductionToScienceConversionBonus))
|
||||
val conversionUnique = cityInfo.civInfo.getMatchingUniques(UniqueType.ProductionToCivWideStatConversionBonus).firstOrNull { it.params[0] == stat.name }
|
||||
if (conversionUnique != null) {
|
||||
conversionRate *= conversionUnique.params[1].toPercent()
|
||||
} else if (stat == Stat.Science && cityInfo.civInfo.hasUnique(UniqueType.ProductionToScienceConversionBonus)) {
|
||||
// backwards compatibility
|
||||
conversionRate *= 1.33f
|
||||
}
|
||||
return conversionRate
|
||||
}
|
||||
|
||||
|
@ -212,35 +212,19 @@ data class RejectionReasonInstance(val rejectionReason:RejectionReason,
|
||||
open class PerpetualConstruction(override var name: String, val description: String) : IConstruction {
|
||||
|
||||
override fun shouldBeDisplayed(cityConstructions: CityConstructions) = isBuildable(cityConstructions)
|
||||
open fun getProductionTooltip(cityInfo: CityInfo) : String
|
||||
= "\r\n${(cityInfo.cityStats.currentCityStats.production / CONVERSION_RATE).roundToInt()}/${Fonts.turn}"
|
||||
open fun getConversionRate(cityInfo: CityInfo) : Int
|
||||
= CONVERSION_RATE
|
||||
open fun getProductionTooltip(cityInfo: CityInfo) : String = ""
|
||||
|
||||
companion object {
|
||||
const val CONVERSION_RATE: Int = 4
|
||||
val science = object : PerpetualConstruction("Science", "Convert production to science at a rate of [rate] to 1") {
|
||||
override fun isBuildable(cityConstructions: CityConstructions): Boolean {
|
||||
return cityConstructions.cityInfo.civInfo.hasUnique(UniqueType.EnablesScienceProduction)
|
||||
}
|
||||
override fun getProductionTooltip(cityInfo: CityInfo): String {
|
||||
return "\r\n${(cityInfo.cityStats.currentCityStats.production / getConversionRate(cityInfo)).roundToInt()}/${Fonts.turn}"
|
||||
}
|
||||
override fun getConversionRate(cityInfo: CityInfo) = (1/cityInfo.cityStats.getScienceConversionRate()).roundToInt()
|
||||
}
|
||||
val gold = object : PerpetualConstruction("Gold", "Convert production to gold at a rate of $CONVERSION_RATE to 1") {
|
||||
override fun isBuildable(cityConstructions: CityConstructions): Boolean {
|
||||
return cityConstructions.cityInfo.civInfo.hasUnique(UniqueType.EnablesGoldProduction)
|
||||
}
|
||||
}
|
||||
val science = PerpetualStatConversion(Stat.Science)
|
||||
val gold = PerpetualStatConversion(Stat.Gold)
|
||||
val culture = PerpetualStatConversion(Stat.Culture)
|
||||
val faith = PerpetualStatConversion(Stat.Faith)
|
||||
val idle = object : PerpetualConstruction("Nothing", "The city will not produce anything.") {
|
||||
override fun isBuildable(cityConstructions: CityConstructions): Boolean = true
|
||||
|
||||
override fun getProductionTooltip(cityInfo: CityInfo): String = ""
|
||||
}
|
||||
|
||||
val perpetualConstructionsMap: Map<String, PerpetualConstruction>
|
||||
= mapOf(science.name to science, gold.name to gold, idle.name to idle)
|
||||
= mapOf(science.name to science, gold.name to gold, culture.name to culture, faith.name to faith, idle.name to idle)
|
||||
}
|
||||
|
||||
override fun isBuildable(cityConstructions: CityConstructions): Boolean =
|
||||
@ -251,3 +235,24 @@ open class PerpetualConstruction(override var name: String, val description: Str
|
||||
override fun requiresResource(resource: String) = false
|
||||
|
||||
}
|
||||
|
||||
open class PerpetualStatConversion(val stat: Stat) :
|
||||
PerpetualConstruction(stat.name, "Convert production to [${stat.name}] at a rate of [rate] to 1") {
|
||||
|
||||
override fun getProductionTooltip(cityInfo: CityInfo) : String
|
||||
= "\r\n${(cityInfo.cityStats.currentCityStats.production / getConversionRate(cityInfo)).roundToInt()}/${Fonts.turn}"
|
||||
fun getConversionRate(cityInfo: CityInfo) : Int = (1/cityInfo.cityStats.getStatConversionRate(stat)).roundToInt()
|
||||
|
||||
override fun isBuildable(cityConstructions: CityConstructions): Boolean {
|
||||
val hasProductionUnique = cityConstructions.cityInfo.civInfo.getMatchingUniques(UniqueType.EnablesCivWideStatProduction).any { it.params[0] == stat.name }
|
||||
return when (stat) {
|
||||
Stat.Science -> hasProductionUnique
|
||||
|| cityConstructions.cityInfo.civInfo.hasUnique(UniqueType.EnablesScienceProduction) // backwards compatibility
|
||||
Stat.Gold -> hasProductionUnique
|
||||
|| cityConstructions.cityInfo.civInfo.hasUnique(UniqueType.EnablesGoldProduction) // backwards compatibility
|
||||
Stat.Culture -> hasProductionUnique
|
||||
Stat.Faith -> cityConstructions.cityInfo.civInfo.gameInfo.isReligionEnabled() && hasProductionUnique
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ enum class UniqueParameterType(
|
||||
},
|
||||
|
||||
/** [UniqueType.DamageUnitsPlunder] and others near that one */
|
||||
PlunderableStatName("plunderableStat", "Gold", "All the following stats can be plundered: `Gold`, `Science`, `Culture`, `Faith`") {
|
||||
CivWideStatName("civWideStat", "Gold", "All the following stats have civ-wide fields: `Gold`, `Science`, `Culture`, `Faith`") {
|
||||
private val knownValues = Stat.statsWithCivWideField.map { it.name }.toSet()
|
||||
override fun getErrorSeverity(
|
||||
parameterText: String,
|
||||
|
@ -193,9 +193,11 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
BuyBuildingsByProductionCost("May buy [buildingFilter] buildings with [stat] for [amount] times their normal Production cost", UniqueTarget.FollowerBelief, UniqueTarget.Global),
|
||||
|
||||
|
||||
// ToDo: Unify
|
||||
@Deprecated("As of 4.1.14", ReplaceWith("Enables conversion of city production to [Gold]"))
|
||||
EnablesGoldProduction("Enables conversion of city production to gold", UniqueTarget.Global),
|
||||
@Deprecated("s of 4.1.14", ReplaceWith("Enables conversion of city production to [Science]"))
|
||||
EnablesScienceProduction("Enables conversion of city production to science", UniqueTarget.Global),
|
||||
EnablesCivWideStatProduction("Enables conversion of city production to [civWideStat]", UniqueTarget.Global),
|
||||
|
||||
BuyItemsDiscount("[stat] cost of purchasing items in cities [relativeAmount]%", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
BuyBuildingsDiscount("[stat] cost of purchasing [buildingFilter] buildings [relativeAmount]%", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
@ -227,7 +229,9 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
EnablesConstructionOfSpaceshipParts("Enables construction of Spaceship parts", UniqueTarget.Global),
|
||||
EnemyLandUnitsSpendExtraMovement("Enemy land units must spend 1 extra movement point when inside your territory (obsolete upon Dynamite)", UniqueTarget.Global),
|
||||
|
||||
@Deprecated("s of 4.1.14", ReplaceWith("Production to [Science] conversion in cities changed by [33]%"))
|
||||
ProductionToScienceConversionBonus("Production to science conversion in cities increased by 33%", UniqueTarget.Global),
|
||||
ProductionToCivWideStatConversionBonus("Production to [civWideStat] conversion in cities changed by [relativeAmount]%", UniqueTarget.Global),
|
||||
|
||||
// Misc national uniques
|
||||
NotifiedOfBarbarianEncampments("Notified of new Barbarian encampments", UniqueTarget.Global),
|
||||
@ -490,10 +494,10 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
UnitUpgradeCost("[relativeAmount]% Gold cost of upgrading", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
GreatPersonEarnedFaster("[greatPerson] is earned [relativeAmount]% faster", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
|
||||
DamageUnitsPlunder("Earn [amount]% of the damage done to [combatantFilter] units as [plunderableStat]", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
CaptureCityPlunder("Upon capturing a city, receive [amount] times its [stat] production as [plunderableStat] immediately", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
KillUnitPlunder("Earn [amount]% of killed [mapUnitFilter] unit's [costOrStrength] as [plunderableStat]", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
KillUnitPlunderNearCity("Earn [amount]% of [mapUnitFilter] unit's [costOrStrength] as [plunderableStat] when killed within 4 tiles of a city following this religion", UniqueTarget.FollowerBelief),
|
||||
DamageUnitsPlunder("Earn [amount]% of the damage done to [combatantFilter] units as [civWideStat]", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
CaptureCityPlunder("Upon capturing a city, receive [amount] times its [stat] production as [civWideStat] immediately", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
KillUnitPlunder("Earn [amount]% of killed [mapUnitFilter] unit's [costOrStrength] as [civWideStat]", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
KillUnitPlunderNearCity("Earn [amount]% of [mapUnitFilter] unit's [costOrStrength] as [civWideStat] when killed within 4 tiles of a city following this religion", UniqueTarget.FollowerBelief),
|
||||
KillUnitCapture("May capture killed [mapUnitFilter] units", UniqueTarget.Unit),
|
||||
|
||||
FlatXPGain("[amount] XP gained from combat", UniqueTarget.Unit, UniqueTarget.Global),
|
||||
|
@ -444,6 +444,8 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
|
||||
is BaseUnit -> UncivSound.Promote
|
||||
PerpetualConstruction.gold -> UncivSound.Coin
|
||||
PerpetualConstruction.science -> UncivSound.Paper
|
||||
PerpetualConstruction.culture -> UncivSound.Policy
|
||||
PerpetualConstruction.faith -> UncivSound.Choir
|
||||
else -> UncivSound.Click
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.city.IConstruction
|
||||
import com.unciv.logic.city.PerpetualConstruction
|
||||
import com.unciv.logic.city.PerpetualStatConversion
|
||||
import com.unciv.models.ruleset.Building
|
||||
import com.unciv.models.ruleset.IRulesetObject
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
@ -63,7 +64,7 @@ class ConstructionInfoTable(val cityScreen: CityScreen): Table() {
|
||||
val description = when (construction) {
|
||||
is BaseUnit -> construction.getDescription(city)
|
||||
is Building -> construction.getDescription(city, true)
|
||||
is PerpetualConstruction -> construction.description.replace("[rate]", "[${construction.getConversionRate(city)}]").tr()
|
||||
is PerpetualStatConversion -> construction.description.replace("[rate]", "[${construction.getConversionRate(city)}]").tr()
|
||||
else -> "" // Should never happen
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user