From 5ba8e050795a3aba2d94f8a4c0d954ff7ffc9b50 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Tue, 22 Nov 2022 00:13:05 +0200 Subject: [PATCH] Fixed city state tests --- core/src/com/unciv/logic/city/CityStats.kt | 39 +++++-------------- .../logic/civilization/CityStateFunctions.kt | 18 +++++++-- .../unciv/logic/civilization/CivInfoStats.kt | 6 +-- .../diplomacy/DiplomacyManager.kt | 4 +- core/src/com/unciv/models/ruleset/Era.kt | 12 ------ .../unciv/models/ruleset/RulesetValidator.kt | 4 +- .../ruleset/unique/UniqueParameterType.kt | 13 +++++++ .../src/com/unciv/ui/trade/DiplomacyScreen.kt | 6 +-- 8 files changed, 45 insertions(+), 57 deletions(-) diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index 8d1998a056..8397be13c2 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -2,7 +2,6 @@ package com.unciv.logic.city import com.unciv.Constants import com.unciv.UncivGame -import com.unciv.logic.civilization.diplomacy.RelationshipLevel import com.unciv.logic.map.RoadStatus import com.unciv.models.Counter import com.unciv.models.ruleset.Building @@ -138,32 +137,6 @@ class CityStats(val cityInfo: CityInfo) { statPercentBonusTree.addStats(building.getStatPercentageBonuses(cityInfo, localUniqueCache), "Buildings", building.name) } - - - private fun getStatsFromCityStates(): Stats { - val stats = Stats() - - for (otherCiv in cityInfo.civInfo.getKnownCivs()) { - val relationshipLevel = otherCiv.getDiplomacyManager(cityInfo.civInfo).relationshipLevel() - if (otherCiv.isCityState() && relationshipLevel >= RelationshipLevel.Friend) { - val eraInfo = cityInfo.civInfo.getEra() - - for (bonus in eraInfo.getCityStateBonuses(otherCiv.cityStateType, relationshipLevel, UniqueType.CityStateStatsPerCity)) { - if (cityInfo.matchesFilter(bonus.params[1]) - && bonus.conditionalsApply(otherCiv, cityInfo) - ) stats.add(bonus.stats) - } - } - } - - for (unique in cityInfo.civInfo.getMatchingUniques(UniqueType.BonusStatsFromCityStates)) { - stats[Stat.valueOf(unique.params[1])] *= unique.params[0].toPercent() - } - - return stats - } - - private fun getStatPercentBonusesFromPuppetCity(): Stats { val stats = Stats() if (cityInfo.isPuppet) { @@ -216,8 +189,15 @@ class CityStats(val cityInfo: CityInfo) { private fun getStatsFromUniquesBySource(): StatTreeNode { val sourceToStats = StatTreeNode() + + val cityStateStatsMultipliers = cityInfo.civInfo.getMatchingUniques(UniqueType.BonusStatsFromCityStates).toList() + fun addUniqueStats(unique:Unique) { - sourceToStats.addStats(unique.stats, getSourceNameForUnique(unique), unique.sourceObjectName ?: "") + val stats = unique.stats.clone() + if (unique.sourceObjectType==UniqueTarget.CityState) + for (multiplierUnique in cityStateStatsMultipliers) + stats[Stat.valueOf(multiplierUnique.params[1])] *= multiplierUnique.params[0].toPercent() + sourceToStats.addStats(stats, getSourceNameForUnique(unique), unique.sourceObjectName ?: "") } for (unique in cityInfo.getMatchingUniques(UniqueType.StatsPerCity)) @@ -236,6 +216,7 @@ class CityStats(val cityInfo: CityInfo) { addUniqueStats(unique) + return sourceToStats } @@ -246,6 +227,7 @@ class CityStats(val cityInfo: CityInfo) { UniqueTarget.Wonder -> "Wonders" UniqueTarget.Building -> "Buildings" UniqueTarget.Policy -> "Policies" + UniqueTarget.CityState -> Constants.cityStates else -> unique.sourceObjectType.name } } @@ -444,7 +426,6 @@ class CityStats(val cityInfo: CityInfo) { getStatsFromSpecialists(cityInfo.population.getNewSpecialists()) newBaseStatList["Trade routes"] = getStatsFromTradeRoute() newBaseStatTree.children["Buildings"] = statsFromBuildings - newBaseStatList[Constants.cityStates] = getStatsFromCityStates() for ((source, stats) in newBaseStatList) newBaseStatTree.addStats(stats, source) diff --git a/core/src/com/unciv/logic/civilization/CityStateFunctions.kt b/core/src/com/unciv/logic/civilization/CityStateFunctions.kt index c1b9142402..4fe760b584 100644 --- a/core/src/com/unciv/logic/civilization/CityStateFunctions.kt +++ b/core/src/com/unciv/logic/civilization/CityStateFunctions.kt @@ -6,6 +6,7 @@ import com.unciv.logic.civilization.diplomacy.DiplomacyFlags import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers import com.unciv.logic.civilization.diplomacy.DiplomaticStatus import com.unciv.logic.civilization.diplomacy.RelationshipLevel +import com.unciv.models.ruleset.CityStateType import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.tile.ResourceSupplyList import com.unciv.models.ruleset.unique.StateForConditionals @@ -419,8 +420,7 @@ class CityStateFunctions(val civInfo: CivilizationInfo) { fun canGiveStat(statType: Stat): Boolean { if (!civInfo.isCityState()) return false - val eraInfo = civInfo.getEra() - for (bonus in eraInfo.getCityStateBonuses(civInfo.cityStateType, RelationshipLevel.Ally)) { + for (bonus in getCityStateBonuses(civInfo.cityStateType, RelationshipLevel.Ally)) { if (bonus.stats[statType] > 0 || (bonus.isOfType(UniqueType.CityStateHappiness) && statType == Stat.Happiness)) return true } @@ -650,10 +650,20 @@ class CityStateFunctions(val civInfo: CivilizationInfo) { stateForConditionals: StateForConditionals ):Sequence { if (civInfo.isCityState()) return emptySequence() - val era = civInfo.getEra() return civInfo.getKnownCivs().asSequence().filter { it.isCityState() } - .flatMap { era.getCityStateBonuses(it.cityStateType, civInfo.getDiplomacyManager(it).relationshipLevel(), uniqueType) } + .flatMap { getCityStateBonuses(it.cityStateType, it.getDiplomacyManager(civInfo).relationshipLevel(), uniqueType) } .filter { it.conditionalsApply(stateForConditionals) } } + + + fun getCityStateBonuses(cityStateType: CityStateType, relationshipLevel: RelationshipLevel, uniqueType:UniqueType?=null): Sequence { + val cityStateUniqueMap = when (relationshipLevel) { + RelationshipLevel.Ally -> cityStateType.allyBonusUniqueMap + RelationshipLevel.Friend -> cityStateType.friendBonusUniqueMap + else -> null + } ?: return emptySequence() + return if (uniqueType == null) cityStateUniqueMap.getAllUniques() + else cityStateUniqueMap.getUniques(uniqueType) + } } diff --git a/core/src/com/unciv/logic/civilization/CivInfoStats.kt b/core/src/com/unciv/logic/civilization/CivInfoStats.kt index 9c67021235..e8f43f2a04 100644 --- a/core/src/com/unciv/logic/civilization/CivInfoStats.kt +++ b/core/src/com/unciv/logic/civilization/CivInfoStats.kt @@ -149,9 +149,8 @@ class CivInfoStats(val civInfo: CivilizationInfo) { val relationshipLevel = otherCiv.getDiplomacyManager(civInfo.civName).relationshipLevel() if (otherCiv.isCityState() && relationshipLevel >= RelationshipLevel.Friend) { val cityStateBonus = Stats() - val eraInfo = civInfo.getEra() - for (bonus in eraInfo.getCityStateBonuses(otherCiv.cityStateType, relationshipLevel, UniqueType.CityStateStatsPerTurn)) { + for (bonus in civInfo.cityStateFunctions.getCityStateBonuses(otherCiv.cityStateType, relationshipLevel, UniqueType.CityStateStatsPerTurn)) { cityStateBonus.add(bonus.stats) } @@ -314,8 +313,7 @@ class CivInfoStats(val civInfo: CivilizationInfo) { val relationshipLevel = otherCiv.getDiplomacyManager(civInfo).relationshipLevel() if (!otherCiv.isCityState() || relationshipLevel < RelationshipLevel.Friend) continue - val eraInfo = civInfo.getEra() - for (bonus in eraInfo.getCityStateBonuses(otherCiv.cityStateType, relationshipLevel)) { + for (bonus in civInfo.cityStateFunctions.getCityStateBonuses(otherCiv.cityStateType, relationshipLevel)) { if (!bonus.conditionalsApply(otherCiv)) continue if (bonus.isOfType(UniqueType.CityStateHappiness)) cityStatesHappiness += bonus.params[0].toFloat() diff --git a/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt index 3177b2cf5d..e501457c4b 100644 --- a/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt +++ b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt @@ -610,8 +610,6 @@ class DiplomacyManager() : IsPartOfGameInfoSerialization { if (!otherCiv().isCityState()) return - val eraInfo = civInfo.getEra() - if (relationshipLevel() < RelationshipLevel.Friend) { if (hasFlag(DiplomacyFlags.ProvideMilitaryUnit)) removeFlag(DiplomacyFlags.ProvideMilitaryUnit) @@ -620,7 +618,7 @@ class DiplomacyManager() : IsPartOfGameInfoSerialization { val variance = listOf(-1, 0, 1).random() - val provideMilitaryUnitUniques = eraInfo.getCityStateBonuses(otherCiv().cityStateType, relationshipLevel(), UniqueType.CityStateMilitaryUnits) + val provideMilitaryUnitUniques = civInfo.cityStateFunctions.getCityStateBonuses(otherCiv().cityStateType, relationshipLevel(), UniqueType.CityStateMilitaryUnits) .filter { it.conditionalsApply(civInfo) }.toList() if (provideMilitaryUnitUniques.isEmpty()) removeFlag(DiplomacyFlags.ProvideMilitaryUnit) diff --git a/core/src/com/unciv/models/ruleset/Era.kt b/core/src/com/unciv/models/ruleset/Era.kt index 4b7df6e06a..c91236980a 100644 --- a/core/src/com/unciv/models/ruleset/Era.kt +++ b/core/src/com/unciv/models/ruleset/Era.kt @@ -1,9 +1,7 @@ package com.unciv.models.ruleset import com.badlogic.gdx.graphics.Color -import com.unciv.logic.civilization.diplomacy.RelationshipLevel import com.unciv.models.ruleset.unique.StateForConditionals -import com.unciv.models.ruleset.unique.Unique import com.unciv.models.ruleset.unique.UniqueTarget import com.unciv.models.ruleset.unique.UniqueType import com.unciv.ui.civilopedia.FormattedLine @@ -81,16 +79,6 @@ class Era : RulesetObject() { }.map { it.first }.distinct() } - fun getCityStateBonuses(cityStateType: CityStateType, relationshipLevel: RelationshipLevel, uniqueType:UniqueType?=null): Sequence { - val cityStateUniqueMap = when (relationshipLevel) { - RelationshipLevel.Ally -> cityStateType.allyBonusUniqueMap - RelationshipLevel.Friend -> cityStateType.friendBonusUniqueMap - else -> null - } ?: return emptySequence() - return if (uniqueType == null) cityStateUniqueMap.getAllUniques() - else cityStateUniqueMap.getUniques(uniqueType) - } - fun getStartingUnits(): List { val startingUnits = mutableListOf() repeat(startingSettlerCount) { startingUnits.add(startingSettlerUnit) } diff --git a/core/src/com/unciv/models/ruleset/RulesetValidator.kt b/core/src/com/unciv/models/ruleset/RulesetValidator.kt index 85b7ef57c8..40a72353c7 100644 --- a/core/src/com/unciv/models/ruleset/RulesetValidator.kt +++ b/core/src/com/unciv/models/ruleset/RulesetValidator.kt @@ -253,7 +253,6 @@ class RulesetValidator(val ruleset: Ruleset) { allDifficultiesStartingUnits.addAll(difficulty.playerBonusStartingUnits) } - val rulesetHasCityStates = ruleset.nations.values.any { it.isCityState() } for (era in ruleset.eras.values) { for (wonder in era.startingObsoleteWonders) if (wonder !in ruleset.buildings) @@ -298,6 +297,9 @@ class RulesetValidator(val ruleset: Ruleset) { for (nation in ruleset.nations.values) { checkUniques(nation, lines, rulesetSpecific, tryFixUnknownUniques) + + if (nation.cityStateType!=null && nation.cityStateType !in ruleset.cityStateTypes) + lines += "${nation.name} is of city-state type ${nation.cityStateType} which does not exist!" if (nation.favoredReligion != null && nation.favoredReligion !in ruleset.religions) lines += "${nation.name} has ${nation.favoredReligion} as their favored religion, which does not exist!" } diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt index 3286e99600..7dd6b3f49c 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt @@ -232,6 +232,19 @@ enum class UniqueParameterType( parameterText != "All" && getErrorSeverity(parameterText, ruleset) == null }, + /** [UniqueType.PercentProductionConstructions], [UniqueType.PercentProductionConstructionsCities] */ + @Deprecated("as of 3.17.10 - removed 3.18.5") + ConstructionFilter("constructionFilter", "Spaceship Part") { + override fun getErrorSeverity( + parameterText: String, + ruleset: Ruleset + ): UniqueType.UniqueComplianceErrorSeverity? { + if (BuildingFilter.getErrorSeverity(parameterText, ruleset) == null) return null + if (BaseUnitFilter.getErrorSeverity(parameterText, ruleset) == null) return null + return UniqueType.UniqueComplianceErrorSeverity.WarningOnly + } + }, + /** Implemented by [PopulationManager.getPopulationFilterAmount][com.unciv.logic.city.PopulationManager.getPopulationFilterAmount] */ PopulationFilter("populationFilter", "Followers of this Religion", null, "Population Filters") { private val knownValues = setOf("Population", "Specialists", "Unemployed", "Followers of the Majority Religion", "Followers of this Religion") diff --git a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt index 391637e4e4..7553914813 100644 --- a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt +++ b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt @@ -246,15 +246,13 @@ class DiplomacyScreen( } diplomacyTable.row().padTop(15f) - val eraInfo = viewingCiv.getEra() - var friendBonusText = "{When Friends:}\n".tr() - val friendBonusObjects = eraInfo.getCityStateBonuses(otherCiv.cityStateType, RelationshipLevel.Friend) + val friendBonusObjects = viewingCiv.cityStateFunctions.getCityStateBonuses(otherCiv.cityStateType, RelationshipLevel.Friend) val friendBonusStrings = getAdjustedBonuses(friendBonusObjects) friendBonusText += friendBonusStrings.joinToString(separator = "\n") { it.tr() } var allyBonusText = "{When Allies:}\n".tr() - val allyBonusObjects = eraInfo.getCityStateBonuses(otherCiv.cityStateType, RelationshipLevel.Ally) + val allyBonusObjects = viewingCiv.cityStateFunctions.getCityStateBonuses(otherCiv.cityStateType, RelationshipLevel.Ally) val allyBonusStrings = getAdjustedBonuses(allyBonusObjects) allyBonusText += allyBonusStrings.joinToString(separator = "\n") { it.tr() }