CityStateType overhaul!!!!

This commit is contained in:
Yair Morgenstern
2022-11-21 20:30:52 +02:00
parent 7d9db1e119
commit 2e5e221158
15 changed files with 42 additions and 71 deletions

View File

@ -6,7 +6,7 @@
"color": [139, 96, 255]
},
{
"Maritime":"Maritime",
"name":"Maritime",
"friendBonusUniques": ["[+2 Food] [in capital]"],
"allyBonusUniques": ["[+2 Food] [in capital]", "[+1 Food] [in all cities]"],
"color": [56, 255, 112]

View File

@ -6,7 +6,7 @@
"color": [139, 96, 255]
},
{
"Maritime":"Maritime",
"name":"Maritime",
"friendBonusUniques": ["[+2 Food] [in capital]"],
"allyBonusUniques": ["[+2 Food] [in capital]", "[+1 Food] [in all cities]"],
"color": [56, 255, 112]

View File

@ -480,11 +480,12 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
for (civInfo in civilizations) civInfo.gameInfo = this
for (civInfo in civilizations) civInfo.setNationTransient()
// must be done before updating tileMap, since unit uniques depend on civ uniques depend on allied city-state uniques depend on diplomacy
for (civInfo in civilizations)
for (civInfo in civilizations) {
for (diplomacyManager in civInfo.diplomacy.values) {
diplomacyManager.civInfo = civInfo
diplomacyManager.updateHasOpenBorders()
}
}
tileMap.setTransients(ruleSet)

View File

@ -28,10 +28,11 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
civInfo.tech.techsResearched.add(tech.name) // can't be .addTechnology because the civInfo isn't assigned yet
val allMercantileResources = ruleset.tileResources.values.filter { it.hasUnique(UniqueType.CityStateOnlyResource) }.map { it.name }
val uniqueTypes = HashSet<UniqueType>() // We look through these to determine what kind of city state we are
for (era in ruleset.eras.values) {
for (unique in era.friendBonusObjects.values.map { it.getAllUniques() } + era.allyBonusObjects.values.map { it.getAllUniques() })
uniqueTypes.addAll(unique.mapNotNull { it.type })
val uniqueTypes = HashSet<UniqueType>() // We look through these to determine what kinds of city states we have
for (cityStateType in ruleset.cityStateTypes.values){
uniqueTypes.addAll(cityStateType.friendBonusUniqueMap.getAllUniques().mapNotNull { it.type })
uniqueTypes.addAll(cityStateType.allyBonusUniqueMap.getAllUniques().mapNotNull { it.type })
}
// CS Personality

View File

@ -1,13 +1,5 @@
package com.unciv.logic.civilization
enum class CityStateTypeOld(val color: String = "") {
Cultured("#8b60ff"),
Maritime("#38ff70"),
Mercantile("#ffd800"),
Militaristic("#ff0000"),
Religious("#FFFFFF")
}
enum class CityStatePersonality {
Friendly,
Neutral,

View File

@ -142,7 +142,7 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
for (unique in civInfo.getMatchingUniques(UniqueType.Stats))
if (unique.sourceObjectType != UniqueTarget.Building && unique.sourceObjectType != UniqueTarget.Wonder)
statMap.add(unique.sourceObjectName!!, unique.stats)
statMap.add(unique.sourceObjectType!!.name, unique.stats)
//City-States bonuses
for (otherCiv in civInfo.getKnownCivs()) {
@ -333,8 +333,9 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
for (unique in civInfo.getMatchingUniques(UniqueType.Stats))
if (unique.sourceObjectType != UniqueTarget.Building && unique.sourceObjectType != UniqueTarget.Wonder && unique.stats.happiness != 0f){
if (!statMap.containsKey(unique.sourceObjectName)) statMap[unique.sourceObjectName!!] = unique.stats.happiness
else statMap[unique.sourceObjectName!!] = statMap[unique.sourceObjectName]!! + unique.stats.happiness
val sourceObjectType = unique.sourceObjectType!!.name
if (!statMap.containsKey(sourceObjectType)) statMap[sourceObjectType] = unique.stats.happiness
else statMap[sourceObjectType] = statMap[sourceObjectType]!! + unique.stats.happiness
}
return statMap

View File

@ -22,6 +22,7 @@ import com.unciv.logic.trade.TradeEvaluation
import com.unciv.logic.trade.TradeRequest
import com.unciv.models.Counter
import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.CityStateType
import com.unciv.models.ruleset.Difficulty
import com.unciv.models.ruleset.Era
import com.unciv.models.ruleset.ModOptionsConstants
@ -346,7 +347,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
fun isBarbarian() = nation.isBarbarian()
fun isSpectator() = nation.isSpectator()
fun isCityState(): Boolean = nation.isCityState()
val cityStateType: CityStateTypeOld get() = nation.cityStateType!!
val cityStateType: CityStateType by lazy { gameInfo.ruleSet.cityStateTypes[nation.cityStateType!!]!! }
var cityStatePersonality: CityStatePersonality = CityStatePersonality.Neutral
var cityStateResource: String? = null
var cityStateUniqueUnit: String? = null // Unique unit for militaristic city state. Might still be null if there are no appropriate units

View File

@ -2,15 +2,16 @@ package com.unciv.models.ruleset
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueMap
import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.stats.INamed
import com.unciv.ui.utils.extensions.colorFromRGB
class CityStateType: INamed {
override var name = ""
var friendBonusUniques = ArrayList<String>()
val friendBonusUniqueMap by lazy { UniqueMap().addUniques(friendBonusUniques.map { Unique(it) }) }
val friendBonusUniqueMap by lazy { UniqueMap().apply { addUniques(friendBonusUniques.map { Unique(it, sourceObjectType = UniqueTarget.CityState) }) } }
var allyBonusUniques = ArrayList<String>()
val allyBonusUniqueMap by lazy { UniqueMap().addUniques(allyBonusUniques.map { Unique(it) }) }
val allyBonusUniqueMap by lazy { UniqueMap().apply { addUniques(allyBonusUniques.map { Unique(it, sourceObjectType = UniqueTarget.CityState) }) } }
lateinit var color:List<Int>
private val colorObject by lazy { colorFromRGB(color) }

View File

@ -1,11 +1,9 @@
package com.unciv.models.ruleset
import com.badlogic.gdx.graphics.Color
import com.unciv.logic.civilization.CityStateTypeOld
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.UniqueMap
import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.ui.civilopedia.FormattedLine
@ -33,10 +31,6 @@ class Era : RulesetObject() {
var friendBonus = HashMap<String, List<String>>()
var allyBonus = HashMap<String, List<String>>()
@Suppress("MemberVisibilityCanBePrivate")
val friendBonusObjects: Map<CityStateTypeOld, UniqueMap> by lazy { initBonuses(friendBonus) }
@Suppress("MemberVisibilityCanBePrivate")
val allyBonusObjects: Map<CityStateTypeOld, UniqueMap> by lazy { initBonuses(allyBonus) }
private var iconRGB: List<Int>? = null
@ -87,20 +81,10 @@ class Era : RulesetObject() {
}.map { it.first }.distinct()
}
private fun initBonuses(bonusMap: Map<String, List<String>>): Map<CityStateTypeOld, UniqueMap> {
val objectMap = HashMap<CityStateTypeOld, UniqueMap>()
for ((cityStateType, bonusList) in bonusMap) {
val cityStateTypeUniqueMap = UniqueMap()
cityStateTypeUniqueMap.addUniques(bonusList.map { Unique(it, UniqueTarget.CityState)})
objectMap[CityStateTypeOld.valueOf(cityStateType)] = cityStateTypeUniqueMap
}
return objectMap
}
fun getCityStateBonuses(cityStateType: CityStateTypeOld, relationshipLevel: RelationshipLevel, uniqueType:UniqueType?=null): Sequence<Unique> {
fun getCityStateBonuses(cityStateType: CityStateType, relationshipLevel: RelationshipLevel, uniqueType:UniqueType?=null): Sequence<Unique> {
val cityStateUniqueMap = when (relationshipLevel) {
RelationshipLevel.Ally -> allyBonusObjects[cityStateType]
RelationshipLevel.Friend -> friendBonusObjects[cityStateType]
RelationshipLevel.Ally -> cityStateType.allyBonusUniqueMap
RelationshipLevel.Friend -> cityStateType.friendBonusUniqueMap
else -> null
} ?: return emptySequence()
return if (uniqueType == null) cityStateUniqueMap.getAllUniques()

View File

@ -2,9 +2,6 @@
import com.badlogic.gdx.graphics.Color
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.civilization.CityStateTypeOld
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueFlag
import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType
@ -23,7 +20,7 @@ class Nation : RulesetObject() {
val style = ""
fun getStyleOrCivName() = style.ifEmpty { name }
var cityStateType: CityStateTypeOld? = null
var cityStateType: String? = null
var preferredVictoryType: String = Constants.neutralVictoryType
var declaringWar = ""
var attacked = ""
@ -140,32 +137,28 @@ class Nation : RulesetObject() {
private fun getCityStateInfo(ruleset: Ruleset): List<FormattedLine> {
val textList = ArrayList<FormattedLine>()
textList += FormattedLine("{Type}: {$cityStateType}", header = 4, color = cityStateType!!.color)
val cityStateType = ruleset.cityStateTypes[cityStateType]!!
textList += FormattedLine("{Type}: {$cityStateType}", header = 4, color = cityStateType.getColor().toString())
val era = if (UncivGame.isCurrentInitialized() && UncivGame.Current.gameInfo != null) {
UncivGame.Current.gameInfo!!.getCurrentPlayerCivilization().getEra()
} else {
ruleset.eras.values.first()
}
var showResources = false
val friendBonus = era.friendBonus[cityStateType!!.name]
if (friendBonus != null && friendBonus.isNotEmpty()) {
val friendBonus = cityStateType.friendBonusUniqueMap
if (friendBonus.isNotEmpty()) {
textList += FormattedLine()
textList += FormattedLine("{When Friends:} ")
friendBonus.forEach {
textList += FormattedLine(Unique(it), indent = 1)
if (it == "Provides a unique luxury") showResources = true
friendBonus.getAllUniques().forEach {
textList += FormattedLine(it, indent = 1)
if (it.text == "Provides a unique luxury") showResources = true
}
}
val allyBonus = era.allyBonus[cityStateType!!.name]
if (allyBonus != null && allyBonus.isNotEmpty()) {
val allyBonus = cityStateType.allyBonusUniqueMap
if (allyBonus.isNotEmpty()) {
textList += FormattedLine()
textList += FormattedLine("{When Allies:} ")
allyBonus.forEach {
textList += FormattedLine(Unique(it), indent = 1)
if (it == "Provides a unique luxury") showResources = true
allyBonus.getAllUniques().forEach {
textList += FormattedLine(it, indent = 1)
if (it.text == "Provides a unique luxury") showResources = true
}
}

View File

@ -367,7 +367,7 @@ class Ruleset {
victories += createHashmap(json().fromJsonFile(Array<Victory>::class.java, victoryTypesFile))
}
val cityStateTypesFile = folderHandle.child("VictoryTypes.json")
val cityStateTypesFile = folderHandle.child("CityStateTypes.json")
if (cityStateTypesFile.exists()) {
cityStateTypes += createHashmap(json().fromJsonFile(Array<CityStateType>::class.java, cityStateTypesFile))
}

View File

@ -243,13 +243,13 @@ class CapitalConnectionsFinderTests {
createCity(ourCiv, Vector2(0f, 4f), "Connected"))
val openCiv = civilizations["Germany"]!!
openCiv.nation.cityStateType = CityStateTypeOld.Cultured
openCiv.nation.cityStateType = "Cultured"
openCiv.cities = listOf( createCity(openCiv, Vector2(0f, 2f), "Berlin", true))
ourCiv.diplomacy["Germany"] = DiplomacyManager(ourCiv, "Germany")
.apply { diplomaticStatus = DiplomaticStatus.Peace }
val closedCiv = civilizations["Greece"]!!
closedCiv.nation.cityStateType = CityStateTypeOld.Cultured
closedCiv.nation.cityStateType = "Cultured"
closedCiv.cities = listOf( createCity(closedCiv, Vector2(0f, -2f), "Athens", true))
ourCiv.diplomacy["Greece"] = DiplomacyManager(ourCiv, "Greece")
.apply { diplomaticStatus = DiplomaticStatus.War }

View File

@ -3,7 +3,6 @@ package com.unciv.uniques
import com.badlogic.gdx.math.Vector2
import com.unciv.Constants
import com.unciv.logic.civilization.CityStateTypeOld
import com.unciv.logic.map.RoadStatus
import com.unciv.models.ruleset.BeliefType
import com.unciv.models.stats.Stats
@ -364,7 +363,7 @@ class GlobalUniquesTests {
fun bonusStatsFromCityStates() {
game.makeHexagonalMap(1)
val civInfo = game.addCiv()
val cityState = game.addCiv(cityState = CityStateTypeOld.Maritime)
val cityState = game.addCiv(cityStateType = "Maritime")
val tile = game.getTile(Vector2(0f,0f))
val city = game.addCity(civInfo, tile, true)

View File

@ -5,7 +5,6 @@ import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.GameInfo
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.CityStateTypeOld
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.PlayerType
import com.unciv.logic.map.MapSizeNew
@ -104,10 +103,10 @@ class TestGame {
return tile
}
fun addCiv(vararg uniques: String, isPlayer: Boolean = false, cityState: CityStateTypeOld? = null): CivilizationInfo {
fun addCiv(vararg uniques: String, isPlayer: Boolean = false, cityStateType: String? = null): CivilizationInfo {
fun nationFactory() = Nation().apply {
cities = arrayListOf("The Capital")
cityStateType = cityState
this.cityStateType = cityStateType
}
val nation = createRulesetObject(ruleset.nations, *uniques) {
nationFactory()
@ -121,7 +120,7 @@ class TestGame {
// Add 1 tech to the player so the era is computed correctly
civInfo.tech.addTechnology(ruleset.technologies.values.minBy { it.era() }.name)
if (cityState != null) {
if (cityStateType != null) {
civInfo.cityStateFunctions.initCityState(ruleset, "Ancient era", emptyList())
}
gameInfo.civilizations.add(civInfo)

View File

@ -1,7 +1,6 @@
package com.unciv.uniques
import com.badlogic.gdx.math.Vector2
import com.unciv.logic.civilization.CityStateTypeOld
import com.unciv.testing.GdxTestRunner
import com.unciv.ui.worldscreen.unit.UnitActions
import org.junit.Assert.assertNotNull
@ -22,7 +21,7 @@ class UnitUniquesTests {
fun `Sweden can gift Great Persons to City States`() {
// when
game.makeHexagonalMap(1)
val cityState = game.addCiv(cityState = CityStateTypeOld.Cultured)
val cityState = game.addCiv(cityStateType = "Cultured")
val cityStateCapitalTile = game.getTile(Vector2(0f, 0f))
val cityStateCapital = game.addCity(cityState, cityStateCapitalTile)