Solved unit purchase discount being 100x what it was supposed to be

This commit is contained in:
Yair Morgenstern 2020-08-06 18:11:58 +03:00
parent 04d84803da
commit 93435948d6
11 changed files with 28 additions and 37 deletions

View File

@ -16,7 +16,6 @@ import com.unciv.logic.map.TileMap
import com.unciv.logic.trade.TradeLogic import com.unciv.logic.trade.TradeLogic
import com.unciv.logic.trade.TradeOffer import com.unciv.logic.trade.TradeOffer
import com.unciv.logic.trade.TradeType import com.unciv.logic.trade.TradeType
import com.unciv.models.ruleset.Unique
import com.unciv.models.ruleset.tile.ResourceSupplyList import com.unciv.models.ruleset.tile.ResourceSupplyList
import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.ruleset.tile.ResourceType
import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.ruleset.unit.BaseUnit
@ -203,7 +202,7 @@ class CityInfo {
if (civInfo.hasUnique("Quantity of strategic resources produced by the empire increased by 100%")) if (civInfo.hasUnique("Quantity of strategic resources produced by the empire increased by 100%"))
amountToAdd *= 2 amountToAdd *= 2
} }
for (unique in civInfo.getMatchingUniques2("Double quantity of [] produced")) for (unique in civInfo.getMatchingUniques("Double quantity of [] produced"))
if (unique.params[0] == resource.name) if (unique.params[0] == resource.name)
amountToAdd *= 2 amountToAdd *= 2
if (resource.resourceType == ResourceType.Luxury if (resource.resourceType == ResourceType.Luxury
@ -260,7 +259,7 @@ class CityInfo {
stats["Buildings"] = buildingStats stats["Buildings"] = buildingStats
for (entry in stats) { for (entry in stats) {
for (unique in civInfo.getMatchingUniques2("[] is earned []% faster")) { for (unique in civInfo.getMatchingUniques("[] is earned []% faster")) {
val unit = civInfo.gameInfo.ruleSet.units[unique.params[0]] val unit = civInfo.gameInfo.ruleSet.units[unique.params[0]]
if (unit == null) continue if (unit == null) continue
val greatUnitUnique = unit.uniques.firstOrNull { it.equalsPlaceholderText("Great Person - []") } val greatUnitUnique = unit.uniques.firstOrNull { it.equalsPlaceholderText("Great Person - []") }
@ -271,7 +270,7 @@ class CityInfo {
if (stat != null) entry.value.add(stat, entry.value.get(stat) * unique.params[1].toFloat()/100) if (stat != null) entry.value.add(stat, entry.value.get(stat) * unique.params[1].toFloat()/100)
} }
for (unique in civInfo.getMatchingUniques2("+[]% great person generation in all cities")) for (unique in civInfo.getMatchingUniques("+[]% great person generation in all cities"))
stats[entry.key] = stats[entry.key]!!.times(1 + (unique.params[0].toFloat() / 100)) stats[entry.key] = stats[entry.key]!!.times(1 + (unique.params[0].toFloat() / 100))
} }
@ -279,8 +278,8 @@ class CityInfo {
} }
fun getGreatPersonPoints(): Stats { fun getGreatPersonPoints(): Stats {
val stats=Stats() val stats = Stats()
for(entry in getGreatPersonMap().values) for (entry in getGreatPersonMap().values)
stats.add(entry) stats.add(entry)
return stats return stats
} }

View File

@ -14,7 +14,6 @@ import com.unciv.models.stats.Stat
import com.unciv.models.stats.Stats import com.unciv.models.stats.Stats
import com.unciv.models.translations.equalsPlaceholderText import com.unciv.models.translations.equalsPlaceholderText
import com.unciv.models.translations.getPlaceholderParameters import com.unciv.models.translations.getPlaceholderParameters
import com.unciv.models.translations.getPlaceholderText
class CityStats { class CityStats {
@ -52,7 +51,7 @@ class CityStats {
if (!cityInfo.isCapital() && cityInfo.isConnectedToCapital()) { if (!cityInfo.isCapital() && cityInfo.isConnectedToCapital()) {
val civInfo = cityInfo.civInfo val civInfo = cityInfo.civInfo
stats.gold = civInfo.getCapital().population.population * 0.15f + cityInfo.population.population * 1.1f - 1 // Calculated by http://civilization.wikia.com/wiki/Trade_route_(Civ5) stats.gold = civInfo.getCapital().population.population * 0.15f + cityInfo.population.population * 1.1f - 1 // Calculated by http://civilization.wikia.com/wiki/Trade_route_(Civ5)
for (unique in civInfo.getMatchingUniques2("[] from each Trade Route")) for (unique in civInfo.getMatchingUniques("[] from each Trade Route"))
stats.add(Stats.parse(unique.params[0])) stats.add(Stats.parse(unique.params[0]))
if (civInfo.hasUnique("Gold from all trade routes +25%")) stats.gold *= 1.25f // Machu Pichu speciality if (civInfo.hasUnique("Gold from all trade routes +25%")) stats.gold *= 1.25f // Machu Pichu speciality
} }
@ -250,7 +249,7 @@ class CityStats {
if (stat == Stat.Culture || stat == Stat.Science) stats.add(stat, 3f) if (stat == Stat.Culture || stat == Stat.Science) stats.add(stat, 3f)
else stats.add(stat, 2f) // science and gold specialists else stats.add(stat, 2f) // science and gold specialists
for(unique in cityInfo.civInfo.getMatchingUniques2("[] from every specialist")) for(unique in cityInfo.civInfo.getMatchingUniques("[] from every specialist"))
stats.add(Stats.parse(unique.params[0])) stats.add(Stats.parse(unique.params[0]))
if (cityInfo.civInfo.hasUnique("+1 Production from specialists")) if (cityInfo.civInfo.hasUnique("+1 Production from specialists"))
stats.production += 1 stats.production += 1
@ -342,7 +341,7 @@ class CityStats {
val filter = unique.params[1] val filter = unique.params[1]
if (currentConstruction.name == filter if (currentConstruction.name == filter
|| (filter == "military units" && currentConstruction is BaseUnit && !currentConstruction.unitType.isCivilian()) || (filter == "military units" && currentConstruction is BaseUnit && !currentConstruction.unitType.isCivilian())
|| (filter == "melee units" && currentConstruction is BaseUnit && !currentConstruction.unitType.isMelee()) || (filter == "melee units" && currentConstruction is BaseUnit && currentConstruction.unitType.isMelee())
|| (filter == "Buildings" && currentConstruction is Building && !currentConstruction.isWonder) || (filter == "Buildings" && currentConstruction is Building && !currentConstruction.isWonder)
|| (filter == "Wonders" && currentConstruction is Building && currentConstruction.isWonder)) || (filter == "Wonders" && currentConstruction is Building && currentConstruction.isWonder))
stats.production += unique.params[0].toInt() stats.production += unique.params[0].toInt()

View File

@ -118,7 +118,7 @@ class CivInfoStats(val civInfo: CivilizationInfo){
// TODO - happinessPerUnique should be difficulty-dependent, 5 on Settler and Chieftian and 4 on other difficulties (should be parameter, not in code) // TODO - happinessPerUnique should be difficulty-dependent, 5 on Settler and Chieftian and 4 on other difficulties (should be parameter, not in code)
var happinessPerUniqueLuxury = 4f + civInfo.getDifficulty().extraHappinessPerLuxury var happinessPerUniqueLuxury = 4f + civInfo.getDifficulty().extraHappinessPerLuxury
for(unique in civInfo.getMatchingUniques2("+1 happiness from each luxury resource")) for(unique in civInfo.getMatchingUniques("+1 happiness from each luxury resource"))
happinessPerUniqueLuxury += 1 happinessPerUniqueLuxury += 1
statMap["Luxury resources"]= civInfo.getCivResources().map { it.resource } statMap["Luxury resources"]= civInfo.getCivResources().map { it.resource }
.count { it.resourceType === ResourceType.Luxury } * happinessPerUniqueLuxury .count { it.resourceType === ResourceType.Luxury } * happinessPerUniqueLuxury

View File

@ -177,9 +177,9 @@ class CivilizationInfo {
fun getBuildingUniques(): Sequence<Unique> = cities.asSequence().flatMap { it.cityConstructions.builtBuildingUniqueMap.getAllUniques() } fun getBuildingUniques(): Sequence<Unique> = cities.asSequence().flatMap { it.cityConstructions.builtBuildingUniqueMap.getAllUniques() }
fun hasUnique(unique:String) = getMatchingUniques2(unique).any() fun hasUnique(unique:String) = getMatchingUniques(unique).any()
fun getMatchingUniques2(uniqueTemplate: String): Sequence<Unique> { fun getMatchingUniques(uniqueTemplate: String): Sequence<Unique> {
return nation.uniqueObjects.asSequence().filter { it.placeholderText == uniqueTemplate } + return nation.uniqueObjects.asSequence().filter { it.placeholderText == uniqueTemplate } +
cities.asSequence().flatMap { it.cityConstructions.builtBuildingUniqueMap.getUniques(uniqueTemplate).asSequence() } + cities.asSequence().flatMap { it.cityConstructions.builtBuildingUniqueMap.getUniques(uniqueTemplate).asSequence() } +
policies.policyUniques.getUniques(uniqueTemplate) policies.policyUniques.getUniques(uniqueTemplate)

View File

@ -27,7 +27,7 @@ class GoldenAgeManager{
fun enterGoldenAge() { fun enterGoldenAge() {
var turnsToGoldenAge = 10.0 var turnsToGoldenAge = 10.0
for(unique in civInfo.getMatchingUniques2("Golden Age length increases +50%")) for(unique in civInfo.getMatchingUniques("Golden Age length increases +50%"))
turnsToGoldenAge *= 1.5 turnsToGoldenAge *= 1.5
if(civInfo.nation.unique == UniqueAbility.ACHAEMENID_LEGACY ) if(civInfo.nation.unique == UniqueAbility.ACHAEMENID_LEGACY )
turnsToGoldenAge*=1.5 turnsToGoldenAge*=1.5

View File

@ -1,15 +1,11 @@
package com.unciv.logic.civilization package com.unciv.logic.civilization
import com.sun.xml.internal.ws.policy.PolicyMap
import com.unciv.Constants import com.unciv.Constants
import com.unciv.models.ruleset.Policy import com.unciv.models.ruleset.Policy
import com.unciv.models.ruleset.Unique
import com.unciv.models.ruleset.UniqueMap import com.unciv.models.ruleset.UniqueMap
import com.unciv.models.ruleset.VictoryType import com.unciv.models.ruleset.VictoryType
import com.unciv.models.translations.equalsPlaceholderText
import com.unciv.models.translations.getPlaceholderParameters import com.unciv.models.translations.getPlaceholderParameters
import com.unciv.models.translations.getPlaceholderText import com.unciv.models.translations.getPlaceholderText
import com.unciv.ui.utils.withItem
import kotlin.math.min import kotlin.math.min
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -81,7 +77,7 @@ class PolicyManager {
if (civInfo.hasUnique("Each city founded increases culture cost of policies 33% less than normal")) if (civInfo.hasUnique("Each city founded increases culture cost of policies 33% less than normal"))
cityModifier *= (2 / 3f) cityModifier *= (2 / 3f)
for(unique in civInfo.getMatchingUniques2("Culture cost of adopting new Policies reduced by 10%")) for(unique in civInfo.getMatchingUniques("Culture cost of adopting new Policies reduced by 10%"))
policyCultureCost *= 0.9 policyCultureCost *= 0.9
if (civInfo.isPlayerCivilization()) if (civInfo.isPlayerCivilization())
policyCultureCost *= civInfo.getDifficulty().policyCostModifier policyCultureCost *= civInfo.getDifficulty().policyCostModifier

View File

@ -8,7 +8,6 @@ import com.unciv.UniqueAbility
import com.unciv.logic.map.MapSize import com.unciv.logic.map.MapSize
import com.unciv.logic.map.RoadStatus import com.unciv.logic.map.RoadStatus
import com.unciv.models.ruleset.tech.Technology import com.unciv.models.ruleset.tech.Technology
import com.unciv.models.translations.getPlaceholderParameters
import com.unciv.ui.utils.withItem import com.unciv.ui.utils.withItem
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
@ -170,7 +169,7 @@ class TechManager {
private fun scienceFromResearchAgreements(): Int { private fun scienceFromResearchAgreements(): Int {
// https://forums.civfanatics.com/resources/research-agreements-bnw.25568/ // https://forums.civfanatics.com/resources/research-agreements-bnw.25568/
var researchAgreementModifier = 0.5f var researchAgreementModifier = 0.5f
for(unique in civInfo.getMatchingUniques2("Science gained from research agreements +50%")) for(unique in civInfo.getMatchingUniques("Science gained from research agreements +50%"))
researchAgreementModifier += 0.25f researchAgreementModifier += 0.25f
return (scienceFromResearchAgreements / 3 * researchAgreementModifier).toInt() return (scienceFromResearchAgreements / 3 * researchAgreementModifier).toInt()
} }
@ -272,7 +271,7 @@ class TechManager {
} }
} }
for(unique in civInfo.getMatchingUniques2("Receive free [] when you discover []")) { for(unique in civInfo.getMatchingUniques("Receive free [] when you discover []")) {
if (unique.params[1] != techName) continue if (unique.params[1] != techName) continue
civInfo.addUnit(unique.params[0]) civInfo.addUnit(unique.params[0])
} }

View File

@ -263,7 +263,7 @@ class MapUnit {
fun getCostOfUpgrade(): Int { fun getCostOfUpgrade(): Int {
val unitToUpgradeTo = getUnitToUpgradeTo() val unitToUpgradeTo = getUnitToUpgradeTo()
var goldCostOfUpgrade = (unitToUpgradeTo.cost - baseUnit().cost) * 2 + 10 var goldCostOfUpgrade = (unitToUpgradeTo.cost - baseUnit().cost) * 2 + 10
for(unique in civInfo.getMatchingUniques2("Gold cost of upgrading military units reduced by 33%")) for(unique in civInfo.getMatchingUniques("Gold cost of upgrading military units reduced by 33%"))
goldCostOfUpgrade = (goldCostOfUpgrade * 0.66f).toInt() goldCostOfUpgrade = (goldCostOfUpgrade * 0.66f).toInt()
if(goldCostOfUpgrade<0) return 0 // For instance, Landsknecht costs less than Spearman, so upgrading would cost negative gold if(goldCostOfUpgrade<0) return 0 // For instance, Landsknecht costs less than Spearman, so upgrading would cost negative gold
return goldCostOfUpgrade return goldCostOfUpgrade

View File

@ -10,8 +10,6 @@ import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.tile.* import com.unciv.models.ruleset.tile.*
import com.unciv.models.stats.Stats import com.unciv.models.stats.Stats
import com.unciv.models.translations.equalsPlaceholderText
import com.unciv.models.translations.getPlaceholderParameters
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import kotlin.math.abs import kotlin.math.abs
@ -245,7 +243,7 @@ open class TileInfo {
stats.add(improvement.improvingTechStats!!) // eg Chemistry for mines stats.add(improvement.improvingTechStats!!) // eg Chemistry for mines
if(city!=null) if(city!=null)
for(unique in city.civInfo.getMatchingUniques2("[] from every []")) { for(unique in city.civInfo.getMatchingUniques("[] from every []")) {
if (improvement.name == unique.params[1]) if (improvement.name == unique.params[1])
stats.add(Stats.parse(unique.params[0])) stats.add(Stats.parse(unique.params[0]))
} }

View File

@ -156,7 +156,7 @@ class Building : NamedStats(), IConstruction {
val adoptedPolicies = civInfo.policies.adoptedPolicies val adoptedPolicies = civInfo.policies.adoptedPolicies
val baseBuildingName = getBaseBuilding(civInfo.gameInfo.ruleSet).name val baseBuildingName = getBaseBuilding(civInfo.gameInfo.ruleSet).name
for(unique in civInfo.getMatchingUniques2("[] from every []")) { for(unique in civInfo.getMatchingUniques("[] from every []")) {
if (unique.params[1] != baseBuildingName) continue if (unique.params[1] != baseBuildingName) continue
stats.add(Stats.parse(unique.params[0])) stats.add(Stats.parse(unique.params[0]))
} }
@ -166,12 +166,12 @@ class Building : NamedStats(), IConstruction {
stats.happiness += 1f stats.happiness += 1f
if(!isWonder) if(!isWonder)
for(unique in civInfo.getMatchingUniques2("[] from all [] buildings")){ for(unique in civInfo.getMatchingUniques("[] from all [] buildings")){
if(isStatRelated(Stat.valueOf(unique.params[1]))) if(isStatRelated(Stat.valueOf(unique.params[1])))
stats.add(Stats.parse(unique.params[0])) stats.add(Stats.parse(unique.params[0]))
} }
else else
for(unique in civInfo.getMatchingUniques2("[] from every Wonder")) for(unique in civInfo.getMatchingUniques("[] from every Wonder"))
stats.add(Stats.parse(unique.params[0])) stats.add(Stats.parse(unique.params[0]))
if (adoptedPolicies.contains("Police State") && baseBuildingName == "Courthouse") if (adoptedPolicies.contains("Police State") && baseBuildingName == "Courthouse")
@ -187,7 +187,7 @@ class Building : NamedStats(), IConstruction {
val baseBuildingName = getBaseBuilding(civInfo.gameInfo.ruleSet).name val baseBuildingName = getBaseBuilding(civInfo.gameInfo.ruleSet).name
for (unique in civInfo.getMatchingUniques2("+[]% [] from every []")) { for (unique in civInfo.getMatchingUniques("+[]% [] from every []")) {
if (unique.params[2] == baseBuildingName) if (unique.params[2] == baseBuildingName)
stats.add(Stat.valueOf(unique.params[1]), unique.params[0].toFloat()) stats.add(Stat.valueOf(unique.params[1]), unique.params[0].toFloat())
} }
@ -225,10 +225,10 @@ class Building : NamedStats(), IConstruction {
// https://forums.civfanatics.com/threads/rush-buying-formula.393892/ // https://forums.civfanatics.com/threads/rush-buying-formula.393892/
var cost = (30 * getProductionCost(civInfo)).toDouble().pow(0.75) * (1 + hurryCostModifier / 100) var cost = (30 * getProductionCost(civInfo)).toDouble().pow(0.75) * (1 + hurryCostModifier / 100)
for (unique in civInfo.getMatchingUniques2("Cost of purchasing items in cities reduced by []%")) for (unique in civInfo.getMatchingUniques("Cost of purchasing items in cities reduced by []%"))
cost *= 1 - (unique.params[0].toFloat() / 100) cost *= 1 - (unique.params[0].toFloat() / 100)
for (unique in civInfo.getMatchingUniques2("Cost of purchasing [] buildings reduced by []%")) { for (unique in civInfo.getMatchingUniques("Cost of purchasing [] buildings reduced by []%")) {
if (isStatRelated(Stat.valueOf(unique.params[0]))) if (isStatRelated(Stat.valueOf(unique.params[0])))
cost *= 1 - (unique.params[1].toFloat() / 100) cost *= 1 - (unique.params[1].toFloat() / 100)
} }

View File

@ -9,7 +9,7 @@ import com.unciv.models.ruleset.Ruleset
import com.unciv.models.translations.Translations import com.unciv.models.translations.Translations
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.models.stats.INamed import com.unciv.models.stats.INamed
import com.unciv.models.translations.getPlaceholderParameters import kotlin.math.pow
// This is BaseUnit because Unit is already a base Kotlin class and to avoid mixing the two up // This is BaseUnit because Unit is already a base Kotlin class and to avoid mixing the two up
@ -99,13 +99,13 @@ class BaseUnit : INamed, IConstruction {
return productionCost.toInt() return productionCost.toInt()
} }
fun getBaseGoldCost() = Math.pow((30 * cost).toDouble(), 0.75) * (1 + hurryCostModifier / 100) fun getBaseGoldCost() = (30.0 * cost).pow(0.75) * (1 + hurryCostModifier / 100)
override fun getGoldCost(civInfo: CivilizationInfo): Int { override fun getGoldCost(civInfo: CivilizationInfo): Int {
var cost = getBaseGoldCost() var cost = getBaseGoldCost()
if (civInfo.hasUnique("Gold cost of purchasing units -33%")) cost *= 0.66f if (civInfo.hasUnique("Gold cost of purchasing units -33%")) cost *= 0.66f
for(unique in civInfo.getMatchingUniques2("Cost of purchasing items in cities reduced by []%")) for (unique in civInfo.getMatchingUniques("Cost of purchasing items in cities reduced by []%"))
cost *= 1-(unique.params[0].toFloat()) cost *= 1 - (unique.params[0].toFloat() / 100)
return (cost / 10).toInt() * 10 // rounded down o nearest ten return (cost / 10).toInt() * 10 // rounded down o nearest ten
} }
@ -159,7 +159,7 @@ class BaseUnit : INamed, IConstruction {
if (this.unitType.isCivilian()) return true // tiny optimization makes save files a few bytes smaller if (this.unitType.isCivilian()) return true // tiny optimization makes save files a few bytes smaller
var XP = construction.getBuiltBuildings().sumBy { it.xpForNewUnits } var XP = construction.getBuiltBuildings().sumBy { it.xpForNewUnits }
for (unique in construction.cityInfo.civInfo.getMatchingUniques2("New military units start with [] Experience")) for (unique in construction.cityInfo.civInfo.getMatchingUniques("New military units start with [] Experience"))
XP += unique.params[0].toInt() XP += unique.params[0].toInt()
unit.promotions.XP = XP unit.promotions.XP = XP