diff --git a/android/assets/jsons/ManuallyBlockedMods.json b/android/assets/jsons/ManuallyBlockedMods.json new file mode 100644 index 0000000000..d357715b41 --- /dev/null +++ b/android/assets/jsons/ManuallyBlockedMods.json @@ -0,0 +1,9 @@ +[ + "https://github.com/k4zoo/Civ5ExpansionMod", + "https://github.com/k4zoo/Civilization-6-Mod", + "https://github.com/9kgsofrice/DeCiv", + "https://github.com/k4zoo/EmpireOfSmokySkies", + "https://github.com/shannaurelle/ph-bonifacio-unciv", + "https://github.com/ID1m0nI/PolyCiv", + "https://github.com/CrispyXYZ/Optimize-tech-mod" +] diff --git a/core/src/com/unciv/logic/GameStarter.kt b/core/src/com/unciv/logic/GameStarter.kt index b202a68bcf..db9871ebae 100644 --- a/core/src/com/unciv/logic/GameStarter.kt +++ b/core/src/com/unciv/logic/GameStarter.kt @@ -143,7 +143,7 @@ object GameStarter { civInfo.tech.addTechnology(tech.name) for (tech in ruleset.technologies.values - .filter { ruleset.getEraNumber(it.era()) < ruleset.getEraNumber(gameSetupInfo.gameParameters.startingEra) }) + .filter { ruleset.eras[it.era()]!!.eraNumber < ruleset.eras[gameSetupInfo.gameParameters.startingEra]!!.eraNumber }) if (!civInfo.tech.isResearched(tech.name)) civInfo.tech.addTechnology(tech.name) @@ -154,12 +154,7 @@ object GameStarter { private fun addCivStats(gameInfo: GameInfo) { val ruleSet = gameInfo.ruleSet val startingEra = gameInfo.gameParameters.startingEra - val era = - if (startingEra in ruleSet.eras.keys) { - ruleSet.eras[startingEra]!! - } else { - Era() - } + val era = ruleSet.eras[startingEra]!! for (civInfo in gameInfo.civilizations.filter { !it.isBarbarian() }) { civInfo.addGold((era.startingGold * gameInfo.gameParameters.gameSpeed.modifier).toInt()) civInfo.policies.addCulture((era.startingCulture * gameInfo.gameParameters.gameSpeed.modifier).toInt()) @@ -277,35 +272,9 @@ object GameStarter { civ.placeUnitNearTile(startingLocation.position, unitName) } - // We are using an older mod, so we only look at the difficulty file - if (ruleSet.eras.isEmpty()) { - startingUnits = (when { - civ.isPlayerCivilization() -> gameInfo.getDifficulty().startingUnits - civ.isMajorCiv() -> gameInfo.getDifficulty().aiMajorCivStartingUnits - else -> gameInfo.getDifficulty().aiCityStateStartingUnits - }).toMutableList() - - val warriorEquivalent = ruleSet.units.values - .filter { it.isLandUnit() && it.isMilitary() && it.isBuildable(civ) } - .maxByOrNull {max(it.strength, it.rangedStrength)} - ?.name - - for (unit in startingUnits) { - val unitToAdd = if (unit == "Warrior") warriorEquivalent else unit - if (unitToAdd != null) placeNearStartingPosition(unitToAdd) - } - - continue - } - // Determine starting units based on starting era - if (startingEra in ruleSet.eras.keys) { - startingUnits = ruleSet.eras[startingEra]!!.getStartingUnits().toMutableList() - eraUnitReplacement = ruleSet.eras[startingEra]!!.startingMilitaryUnit - } else { - startingUnits = Era().getStartingUnits().toMutableList() - eraUnitReplacement = Era().startingMilitaryUnit - } + startingUnits = ruleSet.eras[startingEra]!!.getStartingUnits().toMutableList() + eraUnitReplacement = ruleSet.eras[startingEra]!!.startingMilitaryUnit // Add extra units granted by difficulty startingUnits.addAll(when { diff --git a/core/src/com/unciv/logic/city/CityInfo.kt b/core/src/com/unciv/logic/city/CityInfo.kt index 0fb9874598..7603fe9fed 100644 --- a/core/src/com/unciv/logic/city/CityInfo.kt +++ b/core/src/com/unciv/logic/city/CityInfo.kt @@ -120,8 +120,7 @@ class CityInfo { val ruleset = civInfo.gameInfo.ruleSet workedTiles = hashSetOf() //reassign 1st working tile - if (startingEra in ruleset.eras) - population.setPopulation(ruleset.eras[startingEra]!!.settlerPopulation) + population.setPopulation(ruleset.eras[startingEra]!!.settlerPopulation) if (civInfo.religionManager.religionState == ReligionState.Pantheon) { religion.addPressure( @@ -141,13 +140,11 @@ class CityInfo { if (civInfo.cities.size == 1) cityConstructions.addBuilding(capitalCityIndicator()) // Add buildings and pop we get from starting in this era - if (startingEra in ruleset.eras) { - for (buildingName in ruleset.eras[startingEra]!!.settlerBuildings) { - val building = ruleset.buildings[buildingName] ?: continue - val uniqueBuilding = civInfo.getEquivalentBuilding(building) - if (uniqueBuilding.isBuildable(cityConstructions)) - cityConstructions.addBuilding(uniqueBuilding.name) - } + for (buildingName in ruleset.eras[startingEra]!!.settlerBuildings) { + val building = ruleset.buildings[buildingName] ?: continue + val uniqueBuilding = civInfo.getEquivalentBuilding(building) + if (uniqueBuilding.isBuildable(cityConstructions)) + cityConstructions.addBuilding(uniqueBuilding.name) } civInfo.policies.tryToAddPolicyBuildings() diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index 6046581885..c20c3cdb3e 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -113,9 +113,9 @@ class CityStats(val cityInfo: CityInfo) { for (otherCiv in cityInfo.civInfo.getKnownCivs()) { if (otherCiv.isCityState() && otherCiv.getDiplomacyManager(cityInfo.civInfo).relationshipLevel() >= RelationshipLevel.Friend) { - val eraInfo = cityInfo.civInfo.getEraObject() + val eraInfo = cityInfo.civInfo.getEra() - if (eraInfo == null || eraInfo.friendBonus[otherCiv.cityStateType.name] == null || eraInfo.allyBonus[otherCiv.cityStateType.name] == null) { + if (eraInfo.friendBonus[otherCiv.cityStateType.name] == null || eraInfo.allyBonus[otherCiv.cityStateType.name] == null) { // Deprecated, assume Civ V values for compatibility if (otherCiv.cityStateType == CityStateType.Maritime && otherCiv.getDiplomacyManager(cityInfo.civInfo).relationshipLevel() == RelationshipLevel.Ally) stats.food += 1 diff --git a/core/src/com/unciv/logic/city/IConstruction.kt b/core/src/com/unciv/logic/city/IConstruction.kt index 2230cc8127..74ca4d1a5c 100644 --- a/core/src/com/unciv/logic/city/IConstruction.kt +++ b/core/src/com/unciv/logic/city/IConstruction.kt @@ -73,7 +73,7 @@ interface INonPerpetualConstruction : IConstruction, INamed, IHasUniques { // Can be purchased with [Stat] [cityFilter] if (getMatchingUniques("Can be purchased with [] []") .any { it.params[0] == stat.name && cityInfo.matchesFilter(it.params[1])} - ) return cityInfo.civInfo.gameInfo.ruleSet.eras[cityInfo.civInfo.getEra()]!!.baseUnitBuyCost + ) return cityInfo.civInfo.getEra().baseUnitBuyCost return null } } diff --git a/core/src/com/unciv/logic/civilization/CityStateFunctions.kt b/core/src/com/unciv/logic/civilization/CityStateFunctions.kt index a5296fa628..077fef49fe 100644 --- a/core/src/com/unciv/logic/civilization/CityStateFunctions.kt +++ b/core/src/com/unciv/logic/civilization/CityStateFunctions.kt @@ -316,9 +316,8 @@ class CityStateFunctions(val civInfo: CivilizationInfo) { fun canGiveStat(statType: Stat): Boolean { if (!civInfo.isCityState()) return false - val eraInfo = civInfo.getEraObject() - val allyBonuses = if (eraInfo == null) null - else eraInfo.allyBonus[civInfo.cityStateType.name] + val eraInfo = civInfo.getEra() + val allyBonuses = eraInfo.allyBonus[civInfo.cityStateType.name] if (allyBonuses != null) { // Defined city states in json val bonuses = allyBonuses + eraInfo!!.friendBonus[civInfo.cityStateType.name]!! diff --git a/core/src/com/unciv/logic/civilization/CivInfoStats.kt b/core/src/com/unciv/logic/civilization/CivInfoStats.kt index b58376dede..11f40b4755 100644 --- a/core/src/com/unciv/logic/civilization/CivInfoStats.kt +++ b/core/src/com/unciv/logic/civilization/CivInfoStats.kt @@ -100,16 +100,12 @@ class CivInfoStats(val civInfo: CivilizationInfo) { .relationshipLevel() >= RelationshipLevel.Friend ) { val cityStateBonus = Stats() - val eraInfo = civInfo.getEraObject() + val eraInfo = civInfo.getEra() val relevantBonuses = - when { - eraInfo == null -> null - otherCiv.getDiplomacyManager(civInfo.civName) - .relationshipLevel() == RelationshipLevel.Friend -> - eraInfo.friendBonus[otherCiv.cityStateType.name] - else -> eraInfo.allyBonus[otherCiv.cityStateType.name] - } + if (otherCiv.getDiplomacyManager(civInfo.civName).relationshipLevel() == RelationshipLevel.Friend) + eraInfo.friendBonus[otherCiv.cityStateType.name] + else eraInfo.allyBonus[otherCiv.cityStateType.name] if (relevantBonuses != null) { for (bonus in relevantBonuses) { @@ -299,16 +295,11 @@ class CivInfoStats(val civInfo: CivilizationInfo) { if (otherCiv.isCityState() && otherCiv.getDiplomacyManager(civInfo) .relationshipLevel() >= RelationshipLevel.Friend ) { - val eraInfo = civInfo.getEraObject() + val eraInfo = civInfo.getEra() val relevantBonuses = - when { - eraInfo == null -> null - otherCiv.getDiplomacyManager(civInfo) - .relationshipLevel() == RelationshipLevel.Friend -> - eraInfo.friendBonus[otherCiv.cityStateType.name] - else -> - eraInfo.allyBonus[otherCiv.cityStateType.name] - } + if (otherCiv.getDiplomacyManager(civInfo).relationshipLevel() == RelationshipLevel.Friend) + eraInfo.friendBonus[otherCiv.cityStateType.name] + else eraInfo.allyBonus[otherCiv.cityStateType.name] if (relevantBonuses != null) { for (bonus in relevantBonuses) { diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index 10c9d50975..f948ce7058 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -428,20 +428,18 @@ class CivilizationInfo { else -> getCivUnits().none() } - fun getEra(): String { - if (gameInfo.ruleSet.technologies.isEmpty()) return "None" - if (tech.researchedTechnologies.isEmpty()) - return gameInfo.ruleSet.getEras().first() - return tech.researchedTechnologies + fun getEra(): Era { + if (gameInfo.ruleSet.technologies.isEmpty() || tech.researchedTechnologies.isEmpty()) + return Era() + val eraName = tech.researchedTechnologies .asSequence() .map { it.column!! } .maxByOrNull { it.columnNumber }!! .era + return gameInfo.ruleSet.eras[eraName]!! } - fun getEraNumber(): Int = gameInfo.ruleSet.getEraNumber(getEra()) - - fun getEraObject(): Era? = gameInfo.ruleSet.eras[getEra()] + fun getEraNumber(): Int = getEra().eraNumber fun isAtWarWith(otherCiv: CivilizationInfo): Boolean { if (otherCiv.civName == civName) return false // never at war with itself @@ -864,8 +862,9 @@ class CivilizationInfo { fun getResearchAgreementCost(): Int { // https://forums.civfanatics.com/resources/research-agreements-bnw.25568/ - val era = if (getEra() in gameInfo.ruleSet.eras) gameInfo.ruleSet.eras[getEra()]!! else Era() - return (era.researchAgreementCost * gameInfo.gameParameters.gameSpeed.modifier).toInt() + return ( + getEra().researchAgreementCost * gameInfo.gameParameters.gameSpeed.modifier + ).toInt() } //////////////////////// City State wrapper functions //////////////////////// diff --git a/core/src/com/unciv/logic/civilization/PolicyManager.kt b/core/src/com/unciv/logic/civilization/PolicyManager.kt index 13c4cac138..fa759c068e 100644 --- a/core/src/com/unciv/logic/civilization/PolicyManager.kt +++ b/core/src/com/unciv/logic/civilization/PolicyManager.kt @@ -114,7 +114,7 @@ class PolicyManager { if (isAdopted(policy.name)) return false if (policy.policyBranchType == PolicyBranchType.BranchComplete) return false if (!getAdoptedPolicies().containsAll(policy.requires!!)) return false - if (checkEra && civInfo.gameInfo.ruleSet.getEraNumber(policy.branch.era) > civInfo.getEraNumber()) return false + if (checkEra && civInfo.gameInfo.ruleSet.eras[policy.branch.era]!!.eraNumber > civInfo.getEraNumber()) return false if (policy.uniqueObjects.any { it.placeholderText == "Incompatible with []" && adoptedPolicies.contains(it.params[0]) }) return false return true } diff --git a/core/src/com/unciv/logic/civilization/TechManager.kt b/core/src/com/unciv/logic/civilization/TechManager.kt index 31e2a89819..c1d0999c12 100644 --- a/core/src/com/unciv/logic/civilization/TechManager.kt +++ b/core/src/com/unciv/logic/civilization/TechManager.kt @@ -255,7 +255,7 @@ class TechManager { knownCiv.addNotification("[${civInfo.civName}] has entered the [$currentEra]!", civInfo.civName, NotificationIcon.Science) } } - for (it in getRuleset().policyBranches.values.filter { it.era == currentEra && civInfo.policies.isAdoptable(it) }) { + for (it in getRuleset().policyBranches.values.filter { it.era == currentEra.name && civInfo.policies.isAdoptable(it) }) { civInfo.addNotification("[" + it.name + "] policy branch unlocked!", NotificationIcon.Culture) } } diff --git a/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt index 5b2f88b389..0f0bf00559 100644 --- a/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt +++ b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt @@ -531,18 +531,15 @@ class DiplomacyManager() { revertToZero(DiplomaticModifiers.DeclarationOfFriendship, 1 / 2f) //decreases slowly and will revert to full if it is declared later if (otherCiv().isCityState()) { - val eraInfo = civInfo.getEraObject() + val eraInfo = civInfo.getEra() if (relationshipLevel() < RelationshipLevel.Friend) { if (hasFlag(DiplomacyFlags.ProvideMilitaryUnit)) removeFlag(DiplomacyFlags.ProvideMilitaryUnit) } else { val relevantBonuses = - when { - eraInfo == null -> null - relationshipLevel() == RelationshipLevel.Friend -> - eraInfo.friendBonus[otherCiv().cityStateType.name] - else -> eraInfo.allyBonus[otherCiv().cityStateType.name] - } + if (relationshipLevel() == RelationshipLevel.Friend) + eraInfo.friendBonus[otherCiv().cityStateType.name] + else eraInfo.allyBonus[otherCiv().cityStateType.name] if (relevantBonuses == null && otherCiv().cityStateType == CityStateType.Militaristic) { // Deprecated, assume Civ V values for compatibility diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index 2ce81b2dfc..eda8934a71 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -504,9 +504,8 @@ class Building : NamedStats(), INonPerpetualConstruction, ICivilopediaText { ruleSet.policies.contains(filter) -> if (!civInfo.policies.isAdopted(filter)) rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text }) - // ToDo: Fix this when eras.json is required - ruleSet.getEraNumber(filter) != -1 -> - if (civInfo.getEraNumber() < ruleSet.getEraNumber(filter)) + ruleSet.eras.contains(filter) -> + if (civInfo.getEraNumber() < ruleSet.eras[filter]!!.eraNumber) rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text }) ruleSet.buildings.contains(filter) -> if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) }) @@ -526,7 +525,7 @@ class Building : NamedStats(), INonPerpetualConstruction, ICivilopediaText { rejectionReasons.add(RejectionReason.CityStateWonder) val startingEra = civInfo.gameInfo.gameParameters.startingEra - if (startingEra in ruleSet.eras && name in ruleSet.eras[startingEra]!!.startingObsoleteWonders) + if (name in ruleSet.eras[startingEra]!!.startingObsoleteWonders) rejectionReasons.add(RejectionReason.WonderDisabledEra) } diff --git a/core/src/com/unciv/models/ruleset/Era.kt b/core/src/com/unciv/models/ruleset/Era.kt index 3bd69c9ae0..84cf17150b 100644 --- a/core/src/com/unciv/models/ruleset/Era.kt +++ b/core/src/com/unciv/models/ruleset/Era.kt @@ -7,6 +7,7 @@ import com.unciv.ui.utils.colorFromRGB class Era : INamed { override var name: String = "" + var eraNumber: Int = -1 var researchAgreementCost = 300 var startingSettlerCount = 1 var startingSettlerUnit = "Settler" // For mods which have differently named settlers @@ -39,30 +40,4 @@ class Era : INamed { } fun getHexColor() = "#" + getColor().toString().substring(0, 6) - - companion object { - // User for CS bonuses in case the Eras file is missing (legacy mods) - fun getLegacyCityStateBonusEra(eraNumber: Int) = Era().apply { - val cultureBonus = if (eraNumber in 0..1) 3 else if (eraNumber in 2..3) 6 else 13 - val happinessBonus = if (eraNumber in 0..1) 2 else 3 - friendBonus[CityStateType.Militaristic.name] = - arrayListOf("Provides military units every [20] turns") - friendBonus[CityStateType.Cultured.name] = - arrayListOf("Provides [$cultureBonus] [Culture] per turn") - friendBonus[CityStateType.Mercantile.name] = - arrayListOf("Provides [$happinessBonus] Happiness") - friendBonus[CityStateType.Maritime.name] = - arrayListOf("Provides [2] [Food] [in capital]") - allyBonus[CityStateType.Militaristic.name] = - arrayListOf("Provides military units every [17] turns") - allyBonus[CityStateType.Cultured.name] = - arrayListOf("Provides [${cultureBonus * 2}] [Culture] per turn") - allyBonus[CityStateType.Mercantile.name] = - arrayListOf("Provides [$happinessBonus] Happiness", "Provides a unique luxury") - allyBonus[CityStateType.Maritime.name] = arrayListOf( - "Provides [2] [Food] [in capital]", - "Provides [1] [Food] [in all cities]" - ) - } - } } \ No newline at end of file diff --git a/core/src/com/unciv/models/ruleset/Nation.kt b/core/src/com/unciv/models/ruleset/Nation.kt index 76a2f9e94b..2ff9b4b8f4 100644 --- a/core/src/com/unciv/models/ruleset/Nation.kt +++ b/core/src/com/unciv/models/ruleset/Nation.kt @@ -248,7 +248,7 @@ class Nation : INamed, ICivilopediaText, IHasUniques { textList += FormattedLine("Type: [$cityStateType]", header = 4, color = cityStateType!!.color) val viewingCiv = UncivGame.Current.gameInfo.currentPlayerCiv - val era = viewingCiv.getEraObject() ?: Era.getLegacyCityStateBonusEra(viewingCiv.getEraNumber()) + val era = viewingCiv.getEra() var showResources = false val friendBonus = era.friendBonus[cityStateType!!.name] diff --git a/core/src/com/unciv/models/ruleset/Policy.kt b/core/src/com/unciv/models/ruleset/Policy.kt index 2224f41e9b..6675cf91b7 100644 --- a/core/src/com/unciv/models/ruleset/Policy.kt +++ b/core/src/com/unciv/models/ruleset/Policy.kt @@ -54,7 +54,7 @@ open class Policy : INamed, IHasUniques, ICivilopediaText { override fun replacesCivilopediaDescription() = true override fun hasCivilopediaTextLines() = true override fun getSortGroup(ruleset: Ruleset) = - ruleset.getEraNumber(branch.era) * 10000 + + ruleset.eras[branch.era]!!.eraNumber * 10000 + ruleset.policyBranches.keys.indexOf(branch.name) * 100 + policyBranchType.ordinal diff --git a/core/src/com/unciv/models/ruleset/Ruleset.kt b/core/src/com/unciv/models/ruleset/Ruleset.kt index 240ef7d15a..fe6b9135a6 100644 --- a/core/src/com/unciv/models/ruleset/Ruleset.kt +++ b/core/src/com/unciv/models/ruleset/Ruleset.kt @@ -179,6 +179,10 @@ class Ruleset { val erasFile = folderHandle.child("Eras.json") if (erasFile.exists()) eras += createHashmap(jsonParser.getFromJson(Array::class.java, erasFile)) + // While `eras.values.toList()` might seem more logical, eras.values is a MutableCollection and + // therefore does not guarantee keeping the order of elements like a LinkedHashMap does. + // Using a map sidesteps this problem + eras.map { it.value }.withIndex().forEach { it.value.eraNumber = it.index } val unitTypesFile = folderHandle.child("UnitTypes.json") if (unitTypesFile.exists()) unitTypes += createHashmap(jsonParser.getFromJson(Array::class.java, unitTypesFile)) @@ -251,10 +255,8 @@ class Ruleset { } } - fun getEras(): List = technologies.values.map { it.column!!.era }.distinct() fun hasReligion() = beliefs.any() && modWithReligionLoaded - - fun getEraNumber(era: String) = getEras().indexOf(era) + fun getSummary(): String { val stringList = ArrayList() if (modOptions.isBaseRuleset) stringList += "Base Ruleset" @@ -428,15 +430,15 @@ class Ruleset { warningCount++ } } - // eras.isNotEmpty() is only for mod compatibility, it should be removed at some point. - if (eras.isNotEmpty() && tech.era() !in eras) + if (tech.era() !in eras) lines += "Unknown era ${tech.era()} referenced in column of tech ${tech.name}" } - if(eras.isEmpty()){ - lines += "Eras file is empty! This mod will be unusable in the near future!" + if (eras.isEmpty()) { + lines += "Eras file is empty! This will likely lead to crashes. Ask the mod maker to update this mod!" warningCount++ } + for (era in eras) { for (wonder in era.value.startingObsoleteWonders) if (wonder !in buildings) diff --git a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt index 50f1470f9d..59eed18876 100644 --- a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt @@ -220,7 +220,7 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText { .any { matchesFilter(it.params[0]) && cityInfo.matchesFilter(it.params[3]) - && cityInfo.civInfo.getEraNumber() >= ruleset.getEraNumber(it.params[4]) + && cityInfo.civInfo.getEraNumber() >= ruleset.eras[it.params[4]]!!.eraNumber && it.params[2] == stat.name } ) return true @@ -241,7 +241,7 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText { .filter { matchesFilter(it.params[0]) && cityInfo.matchesFilter(it.params[3]) - && cityInfo.civInfo.getEraNumber() >= ruleset.getEraNumber(it.params[4]) + && cityInfo.civInfo.getEraNumber() >= ruleset.eras[it.params[4]]!!.eraNumber && it.params[2] == stat.name }.map { getCostForConstructionsIncreasingInPrice( @@ -334,9 +334,8 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText { ruleSet.policies.contains(filter) -> if (!civInfo.policies.isAdopted(filter)) rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text }) - // ToDo: Fix this when eras.json is required - ruleSet.getEraNumber(filter) != -1 -> - if (civInfo.getEraNumber() < ruleSet.getEraNumber(filter)) + ruleSet.eras.contains(filter) -> + if (civInfo.getEraNumber() < ruleSet.eras[filter]!!.eraNumber) rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text }) ruleSet.buildings.contains(filter) -> if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) }) @@ -392,7 +391,7 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText { .any { matchesFilter(it.params[0]) && cityConstructions.cityInfo.matchesFilter(it.params[3]) - && cityConstructions.cityInfo.civInfo.getEraNumber() >= ruleset.getEraNumber(it.params[4]) + && cityConstructions.cityInfo.civInfo.getEraNumber() >= ruleset.eras[it.params[4]]!!.eraNumber && it.params[2] == boughtWith.name } ) { diff --git a/core/src/com/unciv/ui/pickerscreens/ModManagementScreen.kt b/core/src/com/unciv/ui/pickerscreens/ModManagementScreen.kt index 1f0b223364..5d7841f8ea 100644 --- a/core/src/com/unciv/ui/pickerscreens/ModManagementScreen.kt +++ b/core/src/com/unciv/ui/pickerscreens/ModManagementScreen.kt @@ -177,6 +177,11 @@ class ModManagementScreen: PickerScreen(disableScroll = true) { for (repo in repoSearch.items) { if (stopBackgroundTasks) return@postRunnable repo.name = repo.name.replace('-', ' ') + + // Mods we have manually decided to remove for instability are removed here + // If at some later point these mods are updated, we should definitely remove + // this piece of code. This is a band-aid, not a full solution. + if (repo.html_url in modsToHide) continue modDescriptionsOnline[repo.name] = (repo.description ?: "-{No description provided}-".tr()) + @@ -503,4 +508,9 @@ class ModManagementScreen: PickerScreen(disableScroll = true) { game.setScreen(ModManagementScreen()) } } + + companion object { + private val blockedModsFile = FileHandle("jsons/ManuallyBlockedMods.json") + val modsToHide = JsonParser().getFromJson(Array::class.java, blockedModsFile) + } } diff --git a/core/src/com/unciv/ui/tilegroups/TileGroup.kt b/core/src/com/unciv/ui/tilegroups/TileGroup.kt index 23fc31a365..e853ac2c7f 100644 --- a/core/src/com/unciv/ui/tilegroups/TileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/TileGroup.kt @@ -239,7 +239,7 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings, var locationToCheck = baseLocation if (tileInfo.owningCity != null) { val ownersEra = tileInfo.getOwner()!!.getEra() - val eraSpecificLocation = tileSetStrings.getString(locationToCheck, tileSetStrings.tag, ownersEra) + val eraSpecificLocation = tileSetStrings.getString(locationToCheck, tileSetStrings.tag, ownersEra.name) if (ImageGetter.imageExists(eraSpecificLocation)) locationToCheck = eraSpecificLocation } diff --git a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt index ace6a63d0d..3803a852e3 100644 --- a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt +++ b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt @@ -177,7 +177,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() { diplomacyTable.add(nextLevelString.toLabel()).row() } - val eraInfo = viewingCiv.getEraObject() ?: Era.getLegacyCityStateBonusEra(viewingCiv.getEraNumber()) + val eraInfo = viewingCiv.getEra() var friendBonusText = "{When Friends:} ".tr() val friendBonuses = eraInfo.friendBonus[otherCiv.cityStateType.name] diff --git a/core/src/com/unciv/ui/utils/ImageGetter.kt b/core/src/com/unciv/ui/utils/ImageGetter.kt index bc74bb5cd7..f47fd52aa2 100644 --- a/core/src/com/unciv/ui/utils/ImageGetter.kt +++ b/core/src/com/unciv/ui/utils/ImageGetter.kt @@ -347,10 +347,7 @@ object ImageGetter { fun getTechIconGroup(techName: String, circleSize: Float) = getTechIcon(techName).surroundWithCircle(circleSize) fun getTechIcon(techName: String): Image { - val era = ruleset.technologies[techName]!!.era() - val techIconColor = - if (era !in ruleset.eras) Era().getColor() - else ruleset.eras[ruleset.technologies[techName]!!.era()]!!.getColor() + val techIconColor = ruleset.eras[ruleset.technologies[techName]!!.era()]!!.getColor() return getImage("TechIcons/$techName").apply { color = techIconColor.lerp(Color.BLACK, 0.6f) } } diff --git a/tests/src/com/unciv/testing/SerializationTests.kt b/tests/src/com/unciv/testing/SerializationTests.kt index 2e1239555b..a05ed5bde8 100644 --- a/tests/src/com/unciv/testing/SerializationTests.kt +++ b/tests/src/com/unciv/testing/SerializationTests.kt @@ -49,6 +49,7 @@ class SerializationTests { players.add(Player("Rome").apply { playerType = PlayerType.Human }) players.add(Player("Greece")) religionEnabled = true + startingEra = "Ancient era" } val mapParameters = MapParameters().apply { mapSize = MapSizeNew(MapSize.Tiny)