mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-28 06:16:37 -04: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:
parent
1649b236bb
commit
9477b319bc
@ -197,7 +197,7 @@
|
|||||||
"name": "Guilds",
|
"name": "Guilds",
|
||||||
"row": 7,
|
"row": 7,
|
||||||
"prerequisites": ["Currency"],
|
"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"
|
"quote": "'The merchants and the traders have come; their profits are pre-ordained...' - Sri Guru Granth Sahib"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -226,7 +226,7 @@
|
|||||||
"name": "Education",
|
"name": "Education",
|
||||||
"row": 3,
|
"row": 3,
|
||||||
"prerequisites": ["Theology","Civil Service"],
|
"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"
|
"quote": "'Education is the best provision for old age.' - Aristotle"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -170,7 +170,7 @@
|
|||||||
"name": "Currency",
|
"name": "Currency",
|
||||||
"row": 7,
|
"row": 7,
|
||||||
"prerequisites": ["Mathematics"],
|
"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"
|
"quote": "'Better is bread with a happy heart than wealth with vexation.' - Amenemope"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -206,7 +206,7 @@
|
|||||||
"name": "Education",
|
"name": "Education",
|
||||||
"row": 3,
|
"row": 3,
|
||||||
"prerequisites": ["Theology","Civil Service"],
|
"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"
|
"quote": "'Education is the best provision for old age.' - Aristotle"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1023,6 +1023,8 @@ Current points =
|
|||||||
Points per turn =
|
Points per turn =
|
||||||
Convert production to gold at a rate of 4 to 1 =
|
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 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. =
|
The city will not produce anything. =
|
||||||
Worked by [cityName] =
|
Worked by [cityName] =
|
||||||
Lock =
|
Lock =
|
||||||
|
@ -107,17 +107,22 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
private fun getStatsFromProduction(production: Float): Stats {
|
private fun getStatsFromProduction(production: Float): Stats {
|
||||||
val stats = Stats()
|
val stats = Stats()
|
||||||
|
|
||||||
when (cityInfo.cityConstructions.currentConstructionFromQueue) {
|
if (cityInfo.cityConstructions.currentConstructionFromQueue in Stat.statsWithCivWideField.map { it.name }) {
|
||||||
"Gold" -> stats.gold += production / 4
|
val stat = Stat.valueOf(cityInfo.cityConstructions.currentConstructionFromQueue)
|
||||||
"Science" -> stats.science += production * getScienceConversionRate()
|
stats[stat] = production * getStatConversionRate(stat)
|
||||||
}
|
}
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getScienceConversionRate(): Float {
|
fun getStatConversionRate(stat: Stat): Float {
|
||||||
var conversionRate = 1 / 4f
|
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
|
conversionRate *= 1.33f
|
||||||
|
}
|
||||||
return conversionRate
|
return conversionRate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,35 +212,19 @@ data class RejectionReasonInstance(val rejectionReason:RejectionReason,
|
|||||||
open class PerpetualConstruction(override var name: String, val description: String) : IConstruction {
|
open class PerpetualConstruction(override var name: String, val description: String) : IConstruction {
|
||||||
|
|
||||||
override fun shouldBeDisplayed(cityConstructions: CityConstructions) = isBuildable(cityConstructions)
|
override fun shouldBeDisplayed(cityConstructions: CityConstructions) = isBuildable(cityConstructions)
|
||||||
open fun getProductionTooltip(cityInfo: CityInfo) : String
|
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
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val CONVERSION_RATE: Int = 4
|
val science = PerpetualStatConversion(Stat.Science)
|
||||||
val science = object : PerpetualConstruction("Science", "Convert production to science at a rate of [rate] to 1") {
|
val gold = PerpetualStatConversion(Stat.Gold)
|
||||||
override fun isBuildable(cityConstructions: CityConstructions): Boolean {
|
val culture = PerpetualStatConversion(Stat.Culture)
|
||||||
return cityConstructions.cityInfo.civInfo.hasUnique(UniqueType.EnablesScienceProduction)
|
val faith = PerpetualStatConversion(Stat.Faith)
|
||||||
}
|
|
||||||
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 idle = object : PerpetualConstruction("Nothing", "The city will not produce anything.") {
|
val idle = object : PerpetualConstruction("Nothing", "The city will not produce anything.") {
|
||||||
override fun isBuildable(cityConstructions: CityConstructions): Boolean = true
|
override fun isBuildable(cityConstructions: CityConstructions): Boolean = true
|
||||||
|
|
||||||
override fun getProductionTooltip(cityInfo: CityInfo): String = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val perpetualConstructionsMap: Map<String, PerpetualConstruction>
|
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 =
|
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
|
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 */
|
/** [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()
|
private val knownValues = Stat.statsWithCivWideField.map { it.name }.toSet()
|
||||||
override fun getErrorSeverity(
|
override fun getErrorSeverity(
|
||||||
parameterText: String,
|
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),
|
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),
|
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),
|
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),
|
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),
|
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),
|
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),
|
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),
|
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
|
// Misc national uniques
|
||||||
NotifiedOfBarbarianEncampments("Notified of new Barbarian encampments", UniqueTarget.Global),
|
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),
|
UnitUpgradeCost("[relativeAmount]% Gold cost of upgrading", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
GreatPersonEarnedFaster("[greatPerson] is earned [relativeAmount]% faster", 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),
|
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 [plunderableStat] immediately", 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 [plunderableStat]", 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 [plunderableStat] when killed within 4 tiles of a city following this religion", UniqueTarget.FollowerBelief),
|
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),
|
KillUnitCapture("May capture killed [mapUnitFilter] units", UniqueTarget.Unit),
|
||||||
|
|
||||||
FlatXPGain("[amount] XP gained from combat", UniqueTarget.Unit, UniqueTarget.Global),
|
FlatXPGain("[amount] XP gained from combat", UniqueTarget.Unit, UniqueTarget.Global),
|
||||||
|
@ -444,6 +444,8 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
|
|||||||
is BaseUnit -> UncivSound.Promote
|
is BaseUnit -> UncivSound.Promote
|
||||||
PerpetualConstruction.gold -> UncivSound.Coin
|
PerpetualConstruction.gold -> UncivSound.Coin
|
||||||
PerpetualConstruction.science -> UncivSound.Paper
|
PerpetualConstruction.science -> UncivSound.Paper
|
||||||
|
PerpetualConstruction.culture -> UncivSound.Policy
|
||||||
|
PerpetualConstruction.faith -> UncivSound.Choir
|
||||||
else -> UncivSound.Click
|
else -> UncivSound.Click
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
|||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.city.IConstruction
|
import com.unciv.logic.city.IConstruction
|
||||||
import com.unciv.logic.city.PerpetualConstruction
|
import com.unciv.logic.city.PerpetualConstruction
|
||||||
|
import com.unciv.logic.city.PerpetualStatConversion
|
||||||
import com.unciv.models.ruleset.Building
|
import com.unciv.models.ruleset.Building
|
||||||
import com.unciv.models.ruleset.IRulesetObject
|
import com.unciv.models.ruleset.IRulesetObject
|
||||||
import com.unciv.models.ruleset.unit.BaseUnit
|
import com.unciv.models.ruleset.unit.BaseUnit
|
||||||
@ -63,7 +64,7 @@ class ConstructionInfoTable(val cityScreen: CityScreen): Table() {
|
|||||||
val description = when (construction) {
|
val description = when (construction) {
|
||||||
is BaseUnit -> construction.getDescription(city)
|
is BaseUnit -> construction.getDescription(city)
|
||||||
is Building -> construction.getDescription(city, true)
|
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
|
else -> "" // Should never happen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user