refactor: break large functions into smaller ones (#9406)

This commit is contained in:
alexban011
2023-05-18 22:02:26 +03:00
committed by GitHub
parent 54f651c2fb
commit 6603c6cfd0
3 changed files with 136 additions and 89 deletions

View File

@ -27,6 +27,17 @@ object BackwardCompatibility {
fun GameInfo.removeMissingModReferences() {
tileMap.removeMissingTerrainModReferences(ruleset)
removeUnitsAndPromotions()
// Mod decided you can't repair things anymore - get rid of old pillaged improvements
removeOldPillagedImprovements()
handleMissingReferencesForEachCity()
removeTechAndPolicies()
}
private fun GameInfo.removeUnitsAndPromotions() {
for (tile in tileMap.values) {
for (unit in tile.getUnits()) {
if (!ruleset.units.containsKey(unit.name)) tile.removeUnit(unit)
@ -36,8 +47,9 @@ object BackwardCompatibility {
unit.promotions.promotions.remove(promotion)
}
}
}
// Mod decided you can't repair things anymore - get rid of old pillaged improvements
private fun GameInfo.removeOldPillagedImprovements() {
if (!ruleset.tileImprovements.containsKey(Constants.repair))
for (tile in tileMap.values) {
if (tile.roadIsPillaged) {
@ -49,8 +61,9 @@ object BackwardCompatibility {
tile.improvementIsPillaged = false
}
}
}
private fun GameInfo.handleMissingReferencesForEachCity() {
for (city in civilizations.asSequence().flatMap { it.cities.asSequence() }) {
changeBuildingNameIfNotInRuleset(ruleset, city.cityConstructions, "Hanse", "Bank")
@ -63,8 +76,8 @@ object BackwardCompatibility {
fun isInvalidConstruction(construction: String) =
!ruleset.buildings.containsKey(construction)
&& !ruleset.units.containsKey(construction)
&& !PerpetualConstruction.perpetualConstructionsMap.containsKey(construction)
&& !ruleset.units.containsKey(construction)
&& !PerpetualConstruction.perpetualConstructionsMap.containsKey(construction)
// Remove invalid buildings or units from the queue - don't just check buildings and units because it might be a special construction as well
for (construction in city.cityConstructions.constructionQueue.toList()) {
@ -76,7 +89,9 @@ object BackwardCompatibility {
if (isInvalidConstruction(construction))
city.cityConstructions.inProgressConstructions.remove(construction)
}
}
private fun GameInfo.removeTechAndPolicies() {
for (civInfo in civilizations) {
for (tech in civInfo.tech.techsResearched.toList())
if (!ruleset.technologies.containsKey(tech))

View File

@ -506,11 +506,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
tileMap.gameInfo = this
// [TEMPORARY] Convert old saves to newer ones by moving base rulesets from the mod list to the base ruleset field
val baseRulesetInMods = gameParameters.mods.firstOrNull { RulesetCache[it]?.modOptions?.isBaseRuleset == true }
if (baseRulesetInMods != null) {
gameParameters.baseRuleset = baseRulesetInMods
gameParameters.mods = LinkedHashSet(gameParameters.mods.filter { it != baseRulesetInMods })
}
convertOldSavesToNewSaves()
ruleset = RulesetCache.getComplexRuleset(gameParameters)
@ -562,6 +558,24 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
convertFortify()
updateCivilizationState()
spaceResources.clear()
spaceResources.addAll(ruleset.buildings.values.filter { it.hasUnique(UniqueType.SpaceshipPart) }
.flatMap { it.getResourceRequirementsPerTurn().keys })
spaceResources.addAll(ruleset.victories.values.flatMap { it.requiredSpaceshipParts })
convertEncampmentData()
barbarians.setTransients(this)
cityDistances.game = this
guaranteeUnitPromotions()
migrateToTileHistory()
}
private fun updateCivilizationState() {
for (civInfo in civilizations.asSequence()
// update city-state resource first since the happiness of major civ depends on it.
// See issue: https://github.com/yairm210/Unciv/issues/7781
@ -604,20 +618,14 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
cityInfo.cityStats.update()
}
}
}
spaceResources.clear()
spaceResources.addAll(ruleset.buildings.values.filter { it.hasUnique(UniqueType.SpaceshipPart) }
.flatMap { it.getResourceRequirementsPerTurn().keys })
spaceResources.addAll(ruleset.victories.values.flatMap { it.requiredSpaceshipParts })
convertEncampmentData()
barbarians.setTransients(this)
cityDistances.game = this
guaranteeUnitPromotions()
migrateToTileHistory()
private fun convertOldSavesToNewSaves() {
val baseRulesetInMods = gameParameters.mods.firstOrNull { RulesetCache[it]?.modOptions?.isBaseRuleset == true }
if (baseRulesetInMods != null) {
gameParameters.baseRuleset = baseRulesetInMods
gameParameters.mods = LinkedHashSet(gameParameters.mods.filter { it != baseRulesetInMods })
}
}
//endregion

View File

@ -19,6 +19,7 @@ import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.RulesetCache
import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.models.stats.Stats
import com.unciv.models.translations.equalsPlaceholderText
import com.unciv.models.translations.getPlaceholderParameters
@ -365,9 +366,6 @@ object GameStarter {
val ruleSet = gameInfo.ruleset
val tileMap = gameInfo.tileMap
val startingEra = gameInfo.gameParameters.startingEra
var startingUnits: MutableList<String>
var eraUnitReplacement: String
val cityCenterMinStats = sequenceOf(ruleSet.tileImprovements[Constants.cityCenter])
.filterNotNull()
@ -395,81 +393,107 @@ object GameStarter {
val startingLocations = getStartingLocations(allCivs, tileMap, landTilesInBigEnoughGroup, startScores)
val settlerLikeUnits = ruleSet.units.filter {
it.value.hasUnique(UniqueType.FoundCity)
}
// no starting units for Barbarians and Spectators
determineStartingUnitsAndLocations(gameInfo, startingLocations, ruleSet)
}
private fun removeAncientRuinsNearStartingLocation(startingLocation: Tile) {
for (tile in startingLocation.getTilesInDistance(3)) {
if (tile.improvement != null
&& tile.getTileImprovement()!!.isAncientRuinsEquivalent()
) {
tile.changeImprovement(null) // Remove ancient ruins in immediate vicinity
}
}
}
private fun determineStartingUnitsAndLocations(
gameInfo: GameInfo,
startingLocations: HashMap<Civilization, Tile>,
ruleset: Ruleset
) {
val startingEra = gameInfo.gameParameters.startingEra
val settlerLikeUnits = ruleset.units.filter { it.value.hasUnique(UniqueType.FoundCity) }
for (civ in gameInfo.civilizations.filter { !it.isBarbarian() && !it.isSpectator() }) {
val startingLocation = startingLocations[civ]!!
for (tile in startingLocation.getTilesInDistance(3)) {
if (tile.improvement != null
&& tile.getTileImprovement()!!.isAncientRuinsEquivalent()
) {
tile.changeImprovement(null) // Remove ancient ruins in immediate vicinity
removeAncientRuinsNearStartingLocation(startingLocation)
val startingUnits = getStartingUnitsForEraAndDifficulty(civ, gameInfo, ruleset, startingEra)
adjustStartingUnitsForCityStatesAndOneCityChallenge(civ, gameInfo, startingUnits, settlerLikeUnits)
placeStartingUnits(civ, startingLocation, startingUnits, ruleset, ruleset.eras[startingEra]!!.startingMilitaryUnit, settlerLikeUnits)
}
}
private fun getStartingUnitsForEraAndDifficulty(civ: Civilization, gameInfo: GameInfo, ruleset: Ruleset, startingEra: String): MutableList<String> {
val startingUnits = ruleset.eras[startingEra]!!.getStartingUnits().toMutableList()
// Add extra units granted by difficulty
startingUnits.addAll(when {
civ.isHuman() -> gameInfo.getDifficulty().playerBonusStartingUnits
civ.isMajorCiv() -> gameInfo.getDifficulty().aiMajorCivBonusStartingUnits
else -> gameInfo.getDifficulty().aiCityStateBonusStartingUnits
})
return startingUnits
}
private fun getEquivalentUnit(
civ: Civilization,
unitParam: String,
ruleset: Ruleset,
eraUnitReplacement: String,
settlerLikeUnits: Map<String, BaseUnit>
): String? {
var unit = unitParam // We want to change it and this is the easiest way to do so
if (unit == Constants.eraSpecificUnit) unit = eraUnitReplacement
if (unit == Constants.settler && Constants.settler !in ruleset.units) {
val buildableSettlerLikeUnits =
settlerLikeUnits.filter {
it.value.isBuildable(civ)
&& it.value.isCivilian()
}
if (buildableSettlerLikeUnits.isEmpty()) return null // No settlers in this mod
return civ.getEquivalentUnit(buildableSettlerLikeUnits.keys.random()).name
}
if (unit == "Worker" && "Worker" !in ruleset.units) {
val buildableWorkerLikeUnits = ruleset.units.filter {
it.value.hasUnique(UniqueType.BuildImprovements) &&
it.value.isBuildable(civ) && it.value.isCivilian()
}
if (buildableWorkerLikeUnits.isEmpty()) return null // No workers in this mod
return civ.getEquivalentUnit(buildableWorkerLikeUnits.keys.random()).name
}
return civ.getEquivalentUnit(unit).name
}
fun placeNearStartingPosition(unitName: String) {
civ.units.placeUnitNearTile(startingLocation.position, unitName)
}
private fun adjustStartingUnitsForCityStatesAndOneCityChallenge(
civ: Civilization,
gameInfo: GameInfo,
startingUnits: MutableList<String>,
settlerLikeUnits: Map<String, BaseUnit>
) {
// Adjust starting units for city states
if (civ.isCityState() && !gameInfo.ruleset.modOptions.uniques.contains(ModOptionsConstants.allowCityStatesSpawnUnits)) {
val startingSettlers = startingUnits.filter { settlerLikeUnits.contains(it) }
// Determine starting units based on starting era
startingUnits = ruleSet.eras[startingEra]!!.getStartingUnits().toMutableList()
eraUnitReplacement = ruleSet.eras[startingEra]!!.startingMilitaryUnit
startingUnits.clear()
startingUnits.add(startingSettlers.random())
}
// Add extra units granted by difficulty
startingUnits.addAll(when {
civ.isHuman() -> gameInfo.getDifficulty().playerBonusStartingUnits
civ.isMajorCiv() -> gameInfo.getDifficulty().aiMajorCivBonusStartingUnits
else -> gameInfo.getDifficulty().aiCityStateBonusStartingUnits
})
// Adjust starting units for one city challenge
if (civ.playerType == PlayerType.Human && gameInfo.gameParameters.oneCityChallenge) {
val startingSettlers = startingUnits.filter { settlerLikeUnits.contains(it) }
startingUnits.removeAll(startingSettlers)
startingUnits.add(startingSettlers.random())
}
}
fun getEquivalentUnit(civ: Civilization, unitParam: String): String? {
var unit = unitParam // We want to change it and this is the easiest way to do so
if (unit == Constants.eraSpecificUnit) unit = eraUnitReplacement
if (unit == Constants.settler && Constants.settler !in ruleSet.units) {
val buildableSettlerLikeUnits =
settlerLikeUnits.filter {
it.value.isBuildable(civ)
&& it.value.isCivilian()
}
if (buildableSettlerLikeUnits.isEmpty()) return null // No settlers in this mod
return civ.getEquivalentUnit(buildableSettlerLikeUnits.keys.random()).name
}
if (unit == "Worker" && "Worker" !in ruleSet.units) {
val buildableWorkerLikeUnits = ruleSet.units.filter {
it.value.hasUnique(UniqueType.BuildImprovements) &&
it.value.isBuildable(civ) && it.value.isCivilian()
}
if (buildableWorkerLikeUnits.isEmpty()) return null // No workers in this mod
return civ.getEquivalentUnit(buildableWorkerLikeUnits.keys.random()).name
}
return civ.getEquivalentUnit(unit).name
}
// City states should only spawn with one settler regardless of difficulty, but this may be disabled in mods
if (civ.isCityState() && !ruleSet.modOptions.uniques.contains(ModOptionsConstants.allowCityStatesSpawnUnits)) {
val startingSettlers = startingUnits.filter { settlerLikeUnits.contains(it) }
startingUnits.clear()
startingUnits.add(startingSettlers.random())
}
// One city challengers should spawn with one settler only regardless of era and difficulty
if (civ.playerType == PlayerType.Human && gameInfo.gameParameters.oneCityChallenge) {
val startingSettlers = startingUnits.filter { settlerLikeUnits.contains(it) }
startingUnits.removeAll(startingSettlers)
startingUnits.add(startingSettlers.random())
}
for (unit in startingUnits) {
val unitToAdd = getEquivalentUnit(civ, unit)
if (unitToAdd != null) placeNearStartingPosition(unitToAdd)
}
private fun placeStartingUnits(civ: Civilization, startingLocation: Tile, startingUnits: MutableList<String>, ruleset: Ruleset, eraUnitReplacement: String, settlerLikeUnits: Map<String, BaseUnit>) {
for (unit in startingUnits) {
val unitToAdd = getEquivalentUnit(civ, unit, ruleset, eraUnitReplacement, settlerLikeUnits)
if (unitToAdd != null) civ.units.placeUnitNearTile(startingLocation.position, unitToAdd)
}
}