mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-28 22:37:02 -04:00
Deprecate all mods without an eras.json file (#4809)
* Enforce the existence of an eras.json file for mods * Merged `getEra()` and `getEraObject()` * Hide mods we have deemed outdated * Fixed compile errors that I didn't notice before * Fixed unit tests
This commit is contained in:
parent
8079a8dc7b
commit
486e2a7a8a
9
android/assets/jsons/ManuallyBlockedMods.json
Normal file
9
android/assets/jsons/ManuallyBlockedMods.json
Normal file
@ -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"
|
||||||
|
]
|
@ -143,7 +143,7 @@ object GameStarter {
|
|||||||
civInfo.tech.addTechnology(tech.name)
|
civInfo.tech.addTechnology(tech.name)
|
||||||
|
|
||||||
for (tech in ruleset.technologies.values
|
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))
|
if (!civInfo.tech.isResearched(tech.name))
|
||||||
civInfo.tech.addTechnology(tech.name)
|
civInfo.tech.addTechnology(tech.name)
|
||||||
|
|
||||||
@ -154,12 +154,7 @@ object GameStarter {
|
|||||||
private fun addCivStats(gameInfo: GameInfo) {
|
private fun addCivStats(gameInfo: GameInfo) {
|
||||||
val ruleSet = gameInfo.ruleSet
|
val ruleSet = gameInfo.ruleSet
|
||||||
val startingEra = gameInfo.gameParameters.startingEra
|
val startingEra = gameInfo.gameParameters.startingEra
|
||||||
val era =
|
val era = ruleSet.eras[startingEra]!!
|
||||||
if (startingEra in ruleSet.eras.keys) {
|
|
||||||
ruleSet.eras[startingEra]!!
|
|
||||||
} else {
|
|
||||||
Era()
|
|
||||||
}
|
|
||||||
for (civInfo in gameInfo.civilizations.filter { !it.isBarbarian() }) {
|
for (civInfo in gameInfo.civilizations.filter { !it.isBarbarian() }) {
|
||||||
civInfo.addGold((era.startingGold * gameInfo.gameParameters.gameSpeed.modifier).toInt())
|
civInfo.addGold((era.startingGold * gameInfo.gameParameters.gameSpeed.modifier).toInt())
|
||||||
civInfo.policies.addCulture((era.startingCulture * 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)
|
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
|
// Determine starting units based on starting era
|
||||||
if (startingEra in ruleSet.eras.keys) {
|
startingUnits = ruleSet.eras[startingEra]!!.getStartingUnits().toMutableList()
|
||||||
startingUnits = ruleSet.eras[startingEra]!!.getStartingUnits().toMutableList()
|
eraUnitReplacement = ruleSet.eras[startingEra]!!.startingMilitaryUnit
|
||||||
eraUnitReplacement = ruleSet.eras[startingEra]!!.startingMilitaryUnit
|
|
||||||
} else {
|
|
||||||
startingUnits = Era().getStartingUnits().toMutableList()
|
|
||||||
eraUnitReplacement = Era().startingMilitaryUnit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add extra units granted by difficulty
|
// Add extra units granted by difficulty
|
||||||
startingUnits.addAll(when {
|
startingUnits.addAll(when {
|
||||||
|
@ -120,8 +120,7 @@ class CityInfo {
|
|||||||
val ruleset = civInfo.gameInfo.ruleSet
|
val ruleset = civInfo.gameInfo.ruleSet
|
||||||
workedTiles = hashSetOf() //reassign 1st working tile
|
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) {
|
if (civInfo.religionManager.religionState == ReligionState.Pantheon) {
|
||||||
religion.addPressure(
|
religion.addPressure(
|
||||||
@ -141,13 +140,11 @@ class CityInfo {
|
|||||||
if (civInfo.cities.size == 1) cityConstructions.addBuilding(capitalCityIndicator())
|
if (civInfo.cities.size == 1) cityConstructions.addBuilding(capitalCityIndicator())
|
||||||
|
|
||||||
// Add buildings and pop we get from starting in this era
|
// Add buildings and pop we get from starting in this era
|
||||||
if (startingEra in ruleset.eras) {
|
for (buildingName in ruleset.eras[startingEra]!!.settlerBuildings) {
|
||||||
for (buildingName in ruleset.eras[startingEra]!!.settlerBuildings) {
|
val building = ruleset.buildings[buildingName] ?: continue
|
||||||
val building = ruleset.buildings[buildingName] ?: continue
|
val uniqueBuilding = civInfo.getEquivalentBuilding(building)
|
||||||
val uniqueBuilding = civInfo.getEquivalentBuilding(building)
|
if (uniqueBuilding.isBuildable(cityConstructions))
|
||||||
if (uniqueBuilding.isBuildable(cityConstructions))
|
cityConstructions.addBuilding(uniqueBuilding.name)
|
||||||
cityConstructions.addBuilding(uniqueBuilding.name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
civInfo.policies.tryToAddPolicyBuildings()
|
civInfo.policies.tryToAddPolicyBuildings()
|
||||||
|
@ -113,9 +113,9 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
|
|
||||||
for (otherCiv in cityInfo.civInfo.getKnownCivs()) {
|
for (otherCiv in cityInfo.civInfo.getKnownCivs()) {
|
||||||
if (otherCiv.isCityState() && otherCiv.getDiplomacyManager(cityInfo.civInfo).relationshipLevel() >= RelationshipLevel.Friend) {
|
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
|
// Deprecated, assume Civ V values for compatibility
|
||||||
if (otherCiv.cityStateType == CityStateType.Maritime && otherCiv.getDiplomacyManager(cityInfo.civInfo).relationshipLevel() == RelationshipLevel.Ally)
|
if (otherCiv.cityStateType == CityStateType.Maritime && otherCiv.getDiplomacyManager(cityInfo.civInfo).relationshipLevel() == RelationshipLevel.Ally)
|
||||||
stats.food += 1
|
stats.food += 1
|
||||||
|
@ -73,7 +73,7 @@ interface INonPerpetualConstruction : IConstruction, INamed, IHasUniques {
|
|||||||
// Can be purchased with [Stat] [cityFilter]
|
// Can be purchased with [Stat] [cityFilter]
|
||||||
if (getMatchingUniques("Can be purchased with [] []")
|
if (getMatchingUniques("Can be purchased with [] []")
|
||||||
.any { it.params[0] == stat.name && cityInfo.matchesFilter(it.params[1])}
|
.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
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,9 +316,8 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
|
|||||||
fun canGiveStat(statType: Stat): Boolean {
|
fun canGiveStat(statType: Stat): Boolean {
|
||||||
if (!civInfo.isCityState())
|
if (!civInfo.isCityState())
|
||||||
return false
|
return false
|
||||||
val eraInfo = civInfo.getEraObject()
|
val eraInfo = civInfo.getEra()
|
||||||
val allyBonuses = if (eraInfo == null) null
|
val allyBonuses = eraInfo.allyBonus[civInfo.cityStateType.name]
|
||||||
else eraInfo.allyBonus[civInfo.cityStateType.name]
|
|
||||||
if (allyBonuses != null) {
|
if (allyBonuses != null) {
|
||||||
// Defined city states in json
|
// Defined city states in json
|
||||||
val bonuses = allyBonuses + eraInfo!!.friendBonus[civInfo.cityStateType.name]!!
|
val bonuses = allyBonuses + eraInfo!!.friendBonus[civInfo.cityStateType.name]!!
|
||||||
|
@ -100,16 +100,12 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
|||||||
.relationshipLevel() >= RelationshipLevel.Friend
|
.relationshipLevel() >= RelationshipLevel.Friend
|
||||||
) {
|
) {
|
||||||
val cityStateBonus = Stats()
|
val cityStateBonus = Stats()
|
||||||
val eraInfo = civInfo.getEraObject()
|
val eraInfo = civInfo.getEra()
|
||||||
|
|
||||||
val relevantBonuses =
|
val relevantBonuses =
|
||||||
when {
|
if (otherCiv.getDiplomacyManager(civInfo.civName).relationshipLevel() == RelationshipLevel.Friend)
|
||||||
eraInfo == null -> null
|
eraInfo.friendBonus[otherCiv.cityStateType.name]
|
||||||
otherCiv.getDiplomacyManager(civInfo.civName)
|
else eraInfo.allyBonus[otherCiv.cityStateType.name]
|
||||||
.relationshipLevel() == RelationshipLevel.Friend ->
|
|
||||||
eraInfo.friendBonus[otherCiv.cityStateType.name]
|
|
||||||
else -> eraInfo.allyBonus[otherCiv.cityStateType.name]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (relevantBonuses != null) {
|
if (relevantBonuses != null) {
|
||||||
for (bonus in relevantBonuses) {
|
for (bonus in relevantBonuses) {
|
||||||
@ -299,16 +295,11 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
|||||||
if (otherCiv.isCityState() && otherCiv.getDiplomacyManager(civInfo)
|
if (otherCiv.isCityState() && otherCiv.getDiplomacyManager(civInfo)
|
||||||
.relationshipLevel() >= RelationshipLevel.Friend
|
.relationshipLevel() >= RelationshipLevel.Friend
|
||||||
) {
|
) {
|
||||||
val eraInfo = civInfo.getEraObject()
|
val eraInfo = civInfo.getEra()
|
||||||
val relevantBonuses =
|
val relevantBonuses =
|
||||||
when {
|
if (otherCiv.getDiplomacyManager(civInfo).relationshipLevel() == RelationshipLevel.Friend)
|
||||||
eraInfo == null -> null
|
eraInfo.friendBonus[otherCiv.cityStateType.name]
|
||||||
otherCiv.getDiplomacyManager(civInfo)
|
else eraInfo.allyBonus[otherCiv.cityStateType.name]
|
||||||
.relationshipLevel() == RelationshipLevel.Friend ->
|
|
||||||
eraInfo.friendBonus[otherCiv.cityStateType.name]
|
|
||||||
else ->
|
|
||||||
eraInfo.allyBonus[otherCiv.cityStateType.name]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (relevantBonuses != null) {
|
if (relevantBonuses != null) {
|
||||||
for (bonus in relevantBonuses) {
|
for (bonus in relevantBonuses) {
|
||||||
|
@ -428,20 +428,18 @@ class CivilizationInfo {
|
|||||||
else -> getCivUnits().none()
|
else -> getCivUnits().none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEra(): String {
|
fun getEra(): Era {
|
||||||
if (gameInfo.ruleSet.technologies.isEmpty()) return "None"
|
if (gameInfo.ruleSet.technologies.isEmpty() || tech.researchedTechnologies.isEmpty())
|
||||||
if (tech.researchedTechnologies.isEmpty())
|
return Era()
|
||||||
return gameInfo.ruleSet.getEras().first()
|
val eraName = tech.researchedTechnologies
|
||||||
return tech.researchedTechnologies
|
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.map { it.column!! }
|
.map { it.column!! }
|
||||||
.maxByOrNull { it.columnNumber }!!
|
.maxByOrNull { it.columnNumber }!!
|
||||||
.era
|
.era
|
||||||
|
return gameInfo.ruleSet.eras[eraName]!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEraNumber(): Int = gameInfo.ruleSet.getEraNumber(getEra())
|
fun getEraNumber(): Int = getEra().eraNumber
|
||||||
|
|
||||||
fun getEraObject(): Era? = gameInfo.ruleSet.eras[getEra()]
|
|
||||||
|
|
||||||
fun isAtWarWith(otherCiv: CivilizationInfo): Boolean {
|
fun isAtWarWith(otherCiv: CivilizationInfo): Boolean {
|
||||||
if (otherCiv.civName == civName) return false // never at war with itself
|
if (otherCiv.civName == civName) return false // never at war with itself
|
||||||
@ -864,8 +862,9 @@ class CivilizationInfo {
|
|||||||
|
|
||||||
fun getResearchAgreementCost(): Int {
|
fun getResearchAgreementCost(): Int {
|
||||||
// https://forums.civfanatics.com/resources/research-agreements-bnw.25568/
|
// https://forums.civfanatics.com/resources/research-agreements-bnw.25568/
|
||||||
val era = if (getEra() in gameInfo.ruleSet.eras) gameInfo.ruleSet.eras[getEra()]!! else Era()
|
return (
|
||||||
return (era.researchAgreementCost * gameInfo.gameParameters.gameSpeed.modifier).toInt()
|
getEra().researchAgreementCost * gameInfo.gameParameters.gameSpeed.modifier
|
||||||
|
).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////// City State wrapper functions ////////////////////////
|
//////////////////////// City State wrapper functions ////////////////////////
|
||||||
|
@ -114,7 +114,7 @@ class PolicyManager {
|
|||||||
if (isAdopted(policy.name)) return false
|
if (isAdopted(policy.name)) return false
|
||||||
if (policy.policyBranchType == PolicyBranchType.BranchComplete) return false
|
if (policy.policyBranchType == PolicyBranchType.BranchComplete) return false
|
||||||
if (!getAdoptedPolicies().containsAll(policy.requires!!)) 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
|
if (policy.uniqueObjects.any { it.placeholderText == "Incompatible with []" && adoptedPolicies.contains(it.params[0]) }) return false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ class TechManager {
|
|||||||
knownCiv.addNotification("[${civInfo.civName}] has entered the [$currentEra]!", civInfo.civName, NotificationIcon.Science)
|
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)
|
civInfo.addNotification("[" + it.name + "] policy branch unlocked!", NotificationIcon.Culture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,18 +531,15 @@ class DiplomacyManager() {
|
|||||||
revertToZero(DiplomaticModifiers.DeclarationOfFriendship, 1 / 2f) //decreases slowly and will revert to full if it is declared later
|
revertToZero(DiplomaticModifiers.DeclarationOfFriendship, 1 / 2f) //decreases slowly and will revert to full if it is declared later
|
||||||
|
|
||||||
if (otherCiv().isCityState()) {
|
if (otherCiv().isCityState()) {
|
||||||
val eraInfo = civInfo.getEraObject()
|
val eraInfo = civInfo.getEra()
|
||||||
|
|
||||||
if (relationshipLevel() < RelationshipLevel.Friend) {
|
if (relationshipLevel() < RelationshipLevel.Friend) {
|
||||||
if (hasFlag(DiplomacyFlags.ProvideMilitaryUnit)) removeFlag(DiplomacyFlags.ProvideMilitaryUnit)
|
if (hasFlag(DiplomacyFlags.ProvideMilitaryUnit)) removeFlag(DiplomacyFlags.ProvideMilitaryUnit)
|
||||||
} else {
|
} else {
|
||||||
val relevantBonuses =
|
val relevantBonuses =
|
||||||
when {
|
if (relationshipLevel() == RelationshipLevel.Friend)
|
||||||
eraInfo == null -> null
|
eraInfo.friendBonus[otherCiv().cityStateType.name]
|
||||||
relationshipLevel() == RelationshipLevel.Friend ->
|
else eraInfo.allyBonus[otherCiv().cityStateType.name]
|
||||||
eraInfo.friendBonus[otherCiv().cityStateType.name]
|
|
||||||
else -> eraInfo.allyBonus[otherCiv().cityStateType.name]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (relevantBonuses == null && otherCiv().cityStateType == CityStateType.Militaristic) {
|
if (relevantBonuses == null && otherCiv().cityStateType == CityStateType.Militaristic) {
|
||||||
// Deprecated, assume Civ V values for compatibility
|
// Deprecated, assume Civ V values for compatibility
|
||||||
|
@ -504,9 +504,8 @@ class Building : NamedStats(), INonPerpetualConstruction, ICivilopediaText {
|
|||||||
ruleSet.policies.contains(filter) ->
|
ruleSet.policies.contains(filter) ->
|
||||||
if (!civInfo.policies.isAdopted(filter))
|
if (!civInfo.policies.isAdopted(filter))
|
||||||
rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text })
|
rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text })
|
||||||
// ToDo: Fix this when eras.json is required
|
ruleSet.eras.contains(filter) ->
|
||||||
ruleSet.getEraNumber(filter) != -1 ->
|
if (civInfo.getEraNumber() < ruleSet.eras[filter]!!.eraNumber)
|
||||||
if (civInfo.getEraNumber() < ruleSet.getEraNumber(filter))
|
|
||||||
rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text })
|
rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text })
|
||||||
ruleSet.buildings.contains(filter) ->
|
ruleSet.buildings.contains(filter) ->
|
||||||
if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) })
|
if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) })
|
||||||
@ -526,7 +525,7 @@ class Building : NamedStats(), INonPerpetualConstruction, ICivilopediaText {
|
|||||||
rejectionReasons.add(RejectionReason.CityStateWonder)
|
rejectionReasons.add(RejectionReason.CityStateWonder)
|
||||||
|
|
||||||
val startingEra = civInfo.gameInfo.gameParameters.startingEra
|
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)
|
rejectionReasons.add(RejectionReason.WonderDisabledEra)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import com.unciv.ui.utils.colorFromRGB
|
|||||||
|
|
||||||
class Era : INamed {
|
class Era : INamed {
|
||||||
override var name: String = ""
|
override var name: String = ""
|
||||||
|
var eraNumber: Int = -1
|
||||||
var researchAgreementCost = 300
|
var researchAgreementCost = 300
|
||||||
var startingSettlerCount = 1
|
var startingSettlerCount = 1
|
||||||
var startingSettlerUnit = "Settler" // For mods which have differently named settlers
|
var startingSettlerUnit = "Settler" // For mods which have differently named settlers
|
||||||
@ -39,30 +40,4 @@ class Era : INamed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getHexColor() = "#" + getColor().toString().substring(0, 6)
|
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]"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -248,7 +248,7 @@ class Nation : INamed, ICivilopediaText, IHasUniques {
|
|||||||
|
|
||||||
textList += FormattedLine("Type: [$cityStateType]", header = 4, color = cityStateType!!.color)
|
textList += FormattedLine("Type: [$cityStateType]", header = 4, color = cityStateType!!.color)
|
||||||
val viewingCiv = UncivGame.Current.gameInfo.currentPlayerCiv
|
val viewingCiv = UncivGame.Current.gameInfo.currentPlayerCiv
|
||||||
val era = viewingCiv.getEraObject() ?: Era.getLegacyCityStateBonusEra(viewingCiv.getEraNumber())
|
val era = viewingCiv.getEra()
|
||||||
var showResources = false
|
var showResources = false
|
||||||
|
|
||||||
val friendBonus = era.friendBonus[cityStateType!!.name]
|
val friendBonus = era.friendBonus[cityStateType!!.name]
|
||||||
|
@ -54,7 +54,7 @@ open class Policy : INamed, IHasUniques, ICivilopediaText {
|
|||||||
override fun replacesCivilopediaDescription() = true
|
override fun replacesCivilopediaDescription() = true
|
||||||
override fun hasCivilopediaTextLines() = true
|
override fun hasCivilopediaTextLines() = true
|
||||||
override fun getSortGroup(ruleset: Ruleset) =
|
override fun getSortGroup(ruleset: Ruleset) =
|
||||||
ruleset.getEraNumber(branch.era) * 10000 +
|
ruleset.eras[branch.era]!!.eraNumber * 10000 +
|
||||||
ruleset.policyBranches.keys.indexOf(branch.name) * 100 +
|
ruleset.policyBranches.keys.indexOf(branch.name) * 100 +
|
||||||
policyBranchType.ordinal
|
policyBranchType.ordinal
|
||||||
|
|
||||||
|
@ -179,6 +179,10 @@ class Ruleset {
|
|||||||
|
|
||||||
val erasFile = folderHandle.child("Eras.json")
|
val erasFile = folderHandle.child("Eras.json")
|
||||||
if (erasFile.exists()) eras += createHashmap(jsonParser.getFromJson(Array<Era>::class.java, erasFile))
|
if (erasFile.exists()) eras += createHashmap(jsonParser.getFromJson(Array<Era>::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")
|
val unitTypesFile = folderHandle.child("UnitTypes.json")
|
||||||
if (unitTypesFile.exists()) unitTypes += createHashmap(jsonParser.getFromJson(Array<UnitType>::class.java, unitTypesFile))
|
if (unitTypesFile.exists()) unitTypes += createHashmap(jsonParser.getFromJson(Array<UnitType>::class.java, unitTypesFile))
|
||||||
@ -251,10 +255,8 @@ class Ruleset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEras(): List<String> = technologies.values.map { it.column!!.era }.distinct()
|
|
||||||
fun hasReligion() = beliefs.any() && modWithReligionLoaded
|
fun hasReligion() = beliefs.any() && modWithReligionLoaded
|
||||||
|
|
||||||
fun getEraNumber(era: String) = getEras().indexOf(era)
|
|
||||||
fun getSummary(): String {
|
fun getSummary(): String {
|
||||||
val stringList = ArrayList<String>()
|
val stringList = ArrayList<String>()
|
||||||
if (modOptions.isBaseRuleset) stringList += "Base Ruleset"
|
if (modOptions.isBaseRuleset) stringList += "Base Ruleset"
|
||||||
@ -428,15 +430,15 @@ class Ruleset {
|
|||||||
warningCount++
|
warningCount++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// eras.isNotEmpty() is only for mod compatibility, it should be removed at some point.
|
if (tech.era() !in eras)
|
||||||
if (eras.isNotEmpty() && tech.era() !in eras)
|
|
||||||
lines += "Unknown era ${tech.era()} referenced in column of tech ${tech.name}"
|
lines += "Unknown era ${tech.era()} referenced in column of tech ${tech.name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
if(eras.isEmpty()){
|
if (eras.isEmpty()) {
|
||||||
lines += "Eras file is empty! This mod will be unusable in the near future!"
|
lines += "Eras file is empty! This will likely lead to crashes. Ask the mod maker to update this mod!"
|
||||||
warningCount++
|
warningCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
for (era in eras) {
|
for (era in eras) {
|
||||||
for (wonder in era.value.startingObsoleteWonders)
|
for (wonder in era.value.startingObsoleteWonders)
|
||||||
if (wonder !in buildings)
|
if (wonder !in buildings)
|
||||||
|
@ -220,7 +220,7 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText {
|
|||||||
.any {
|
.any {
|
||||||
matchesFilter(it.params[0])
|
matchesFilter(it.params[0])
|
||||||
&& cityInfo.matchesFilter(it.params[3])
|
&& 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
|
&& it.params[2] == stat.name
|
||||||
}
|
}
|
||||||
) return true
|
) return true
|
||||||
@ -241,7 +241,7 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText {
|
|||||||
.filter {
|
.filter {
|
||||||
matchesFilter(it.params[0])
|
matchesFilter(it.params[0])
|
||||||
&& cityInfo.matchesFilter(it.params[3])
|
&& 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
|
&& it.params[2] == stat.name
|
||||||
}.map {
|
}.map {
|
||||||
getCostForConstructionsIncreasingInPrice(
|
getCostForConstructionsIncreasingInPrice(
|
||||||
@ -334,9 +334,8 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText {
|
|||||||
ruleSet.policies.contains(filter) ->
|
ruleSet.policies.contains(filter) ->
|
||||||
if (!civInfo.policies.isAdopted(filter))
|
if (!civInfo.policies.isAdopted(filter))
|
||||||
rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text })
|
rejectionReasons.add(RejectionReason.RequiresPolicy.apply { errorMessage = unique.text })
|
||||||
// ToDo: Fix this when eras.json is required
|
ruleSet.eras.contains(filter) ->
|
||||||
ruleSet.getEraNumber(filter) != -1 ->
|
if (civInfo.getEraNumber() < ruleSet.eras[filter]!!.eraNumber)
|
||||||
if (civInfo.getEraNumber() < ruleSet.getEraNumber(filter))
|
|
||||||
rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text })
|
rejectionReasons.add(RejectionReason.UnlockedWithEra.apply { errorMessage = unique.text })
|
||||||
ruleSet.buildings.contains(filter) ->
|
ruleSet.buildings.contains(filter) ->
|
||||||
if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) })
|
if (civInfo.cities.none { it.cityConstructions.containsBuildingOrEquivalent(filter) })
|
||||||
@ -392,7 +391,7 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText {
|
|||||||
.any {
|
.any {
|
||||||
matchesFilter(it.params[0])
|
matchesFilter(it.params[0])
|
||||||
&& cityConstructions.cityInfo.matchesFilter(it.params[3])
|
&& 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
|
&& it.params[2] == boughtWith.name
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
@ -177,6 +177,11 @@ class ModManagementScreen: PickerScreen(disableScroll = true) {
|
|||||||
for (repo in repoSearch.items) {
|
for (repo in repoSearch.items) {
|
||||||
if (stopBackgroundTasks) return@postRunnable
|
if (stopBackgroundTasks) return@postRunnable
|
||||||
repo.name = repo.name.replace('-', ' ')
|
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] =
|
modDescriptionsOnline[repo.name] =
|
||||||
(repo.description ?: "-{No description provided}-".tr()) +
|
(repo.description ?: "-{No description provided}-".tr()) +
|
||||||
@ -503,4 +508,9 @@ class ModManagementScreen: PickerScreen(disableScroll = true) {
|
|||||||
game.setScreen(ModManagementScreen())
|
game.setScreen(ModManagementScreen())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val blockedModsFile = FileHandle("jsons/ManuallyBlockedMods.json")
|
||||||
|
val modsToHide = JsonParser().getFromJson(Array<String>::class.java, blockedModsFile)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings,
|
|||||||
var locationToCheck = baseLocation
|
var locationToCheck = baseLocation
|
||||||
if (tileInfo.owningCity != null) {
|
if (tileInfo.owningCity != null) {
|
||||||
val ownersEra = tileInfo.getOwner()!!.getEra()
|
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))
|
if (ImageGetter.imageExists(eraSpecificLocation))
|
||||||
locationToCheck = eraSpecificLocation
|
locationToCheck = eraSpecificLocation
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
|
|||||||
diplomacyTable.add(nextLevelString.toLabel()).row()
|
diplomacyTable.add(nextLevelString.toLabel()).row()
|
||||||
}
|
}
|
||||||
|
|
||||||
val eraInfo = viewingCiv.getEraObject() ?: Era.getLegacyCityStateBonusEra(viewingCiv.getEraNumber())
|
val eraInfo = viewingCiv.getEra()
|
||||||
|
|
||||||
var friendBonusText = "{When Friends:} ".tr()
|
var friendBonusText = "{When Friends:} ".tr()
|
||||||
val friendBonuses = eraInfo.friendBonus[otherCiv.cityStateType.name]
|
val friendBonuses = eraInfo.friendBonus[otherCiv.cityStateType.name]
|
||||||
|
@ -347,10 +347,7 @@ object ImageGetter {
|
|||||||
fun getTechIconGroup(techName: String, circleSize: Float) = getTechIcon(techName).surroundWithCircle(circleSize)
|
fun getTechIconGroup(techName: String, circleSize: Float) = getTechIcon(techName).surroundWithCircle(circleSize)
|
||||||
|
|
||||||
fun getTechIcon(techName: String): Image {
|
fun getTechIcon(techName: String): Image {
|
||||||
val era = ruleset.technologies[techName]!!.era()
|
val techIconColor = ruleset.eras[ruleset.technologies[techName]!!.era()]!!.getColor()
|
||||||
val techIconColor =
|
|
||||||
if (era !in ruleset.eras) Era().getColor()
|
|
||||||
else ruleset.eras[ruleset.technologies[techName]!!.era()]!!.getColor()
|
|
||||||
return getImage("TechIcons/$techName").apply { color = techIconColor.lerp(Color.BLACK, 0.6f) }
|
return getImage("TechIcons/$techName").apply { color = techIconColor.lerp(Color.BLACK, 0.6f) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ class SerializationTests {
|
|||||||
players.add(Player("Rome").apply { playerType = PlayerType.Human })
|
players.add(Player("Rome").apply { playerType = PlayerType.Human })
|
||||||
players.add(Player("Greece"))
|
players.add(Player("Greece"))
|
||||||
religionEnabled = true
|
religionEnabled = true
|
||||||
|
startingEra = "Ancient era"
|
||||||
}
|
}
|
||||||
val mapParameters = MapParameters().apply {
|
val mapParameters = MapParameters().apply {
|
||||||
mapSize = MapSizeNew(MapSize.Tiny)
|
mapSize = MapSizeNew(MapSize.Tiny)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user