mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-09 15:29:32 +07:00
Game can deal gracefully wth mods removing certain units and technologies
This commit is contained in:
@ -262,35 +262,7 @@ class GameInfo {
|
||||
throw UncivShowableException("Missing mods: [$missingMods]")
|
||||
}
|
||||
|
||||
// Mods can change, leading to things on the map that are no longer defined in the mod.
|
||||
// So we remove them so the game doesn't crash when it tries to access them.
|
||||
for (tile in tileMap.values) {
|
||||
if (tile.resource != null && !ruleSet.tileResources.containsKey(tile.resource!!))
|
||||
tile.resource = null
|
||||
if (tile.improvement != null && !ruleSet.tileImprovements.containsKey(tile.improvement!!)
|
||||
&& !tile.improvement!!.startsWith("StartingLocation ")) // To not remove the starting locations in GameStarter.startNewGame()
|
||||
tile.improvement = null
|
||||
|
||||
for (unit in tile.getUnits())
|
||||
for (promotion in unit.promotions.promotions.toList())
|
||||
if (!ruleSet.unitPromotions.containsKey(promotion))
|
||||
unit.promotions.promotions.remove(promotion)
|
||||
|
||||
for (city in civilizations.asSequence().flatMap { it.cities.asSequence() }) {
|
||||
for (building in city.cityConstructions.builtBuildings.toHashSet())
|
||||
if (!ruleSet.buildings.containsKey(building))
|
||||
city.cityConstructions.builtBuildings.remove(building)
|
||||
|
||||
// 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()) {
|
||||
if (!ruleSet.buildings.containsKey(construction) && !ruleSet.units.containsKey(construction)
|
||||
&& !PerpetualConstruction.perpetualConstructionsMap.containsKey(construction))
|
||||
city.cityConstructions.constructionQueue.remove(construction)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
removeMissingModReferences()
|
||||
|
||||
tileMap.setTransients(ruleSet)
|
||||
|
||||
@ -347,6 +319,46 @@ class GameInfo {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mods can change, leading to things on the map that are no longer defined in the mod.
|
||||
// So we remove them so the game doesn't crash when it tries to access them.
|
||||
private fun removeMissingModReferences() {
|
||||
for (tile in tileMap.values) {
|
||||
if (tile.resource != null && !ruleSet.tileResources.containsKey(tile.resource!!))
|
||||
tile.resource = null
|
||||
if (tile.improvement != null && !ruleSet.tileImprovements.containsKey(tile.improvement!!)
|
||||
&& !tile.improvement!!.startsWith("StartingLocation ")) // To not remove the starting locations in GameStarter.startNewGame()
|
||||
tile.improvement = null
|
||||
|
||||
for (unit in tile.getUnits()) {
|
||||
if (!ruleSet.units.containsKey(unit.name)) tile.removeUnit(unit)
|
||||
|
||||
for (promotion in unit.promotions.promotions.toList())
|
||||
if (!ruleSet.unitPromotions.containsKey(promotion))
|
||||
unit.promotions.promotions.remove(promotion)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (city in civilizations.asSequence().flatMap { it.cities.asSequence() }) {
|
||||
for (building in city.cityConstructions.builtBuildings.toHashSet())
|
||||
if (!ruleSet.buildings.containsKey(building))
|
||||
city.cityConstructions.builtBuildings.remove(building)
|
||||
|
||||
// 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()) {
|
||||
if (!ruleSet.buildings.containsKey(construction) && !ruleSet.units.containsKey(construction)
|
||||
&& !PerpetualConstruction.perpetualConstructionsMap.containsKey(construction))
|
||||
city.cityConstructions.constructionQueue.remove(construction)
|
||||
}
|
||||
}
|
||||
for (civinfo in civilizations) {
|
||||
for (tech in civinfo.tech.techsResearched.toList())
|
||||
if (!ruleSet.technologies.containsKey(tech))
|
||||
civinfo.tech.techsResearched.remove(tech)
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeBuildingName(cityConstructions: CityConstructions, oldBuildingName: String, newBuildingName: String) {
|
||||
if (cityConstructions.builtBuildings.contains(oldBuildingName)) {
|
||||
cityConstructions.builtBuildings.remove(oldBuildingName)
|
||||
|
@ -18,6 +18,7 @@ import kotlin.math.min
|
||||
class TechManager {
|
||||
@Transient
|
||||
lateinit var civInfo: CivilizationInfo
|
||||
/** This is the Transient list of Technologies */
|
||||
@Transient
|
||||
var researchedTechnologies = ArrayList<Technology>()
|
||||
@Transient
|
||||
@ -42,6 +43,7 @@ class TechManager {
|
||||
/** For calculating Great Scientist yields - see https://civilization.fandom.com/wiki/Great_Scientist_(Civ5) */
|
||||
var scienceOfLast8Turns = IntArray(8) { 0 }
|
||||
var scienceFromResearchAgreements = 0
|
||||
/** This is the lit of strings, which is serialized */
|
||||
var techsResearched = HashSet<String>()
|
||||
|
||||
/** When moving towards a certain tech, the user doesn't have to manually pick every one. */
|
||||
|
@ -495,13 +495,7 @@ class MapUnit {
|
||||
.forEach { unit -> unit.destroy() }
|
||||
}
|
||||
|
||||
fun removeFromTile() {
|
||||
when {
|
||||
type.isAirUnit() -> currentTile.airUnits.remove(this)
|
||||
type.isCivilian() -> getTile().civilianUnit = null
|
||||
else -> getTile().militaryUnit = null
|
||||
}
|
||||
}
|
||||
fun removeFromTile() = currentTile.removeUnit(this)
|
||||
|
||||
fun moveThroughTile(tile: TileInfo) {
|
||||
if (tile.improvement == Constants.ancientRuins && civInfo.isMajorCiv())
|
||||
|
@ -483,7 +483,19 @@ open class TileInfo {
|
||||
}
|
||||
|
||||
fun stripUnits() {
|
||||
for (unit in this.getUnits()) unit.removeFromTile()
|
||||
for (unit in this.getUnits()) removeUnit(unit)
|
||||
}
|
||||
|
||||
|
||||
/** If the unit isn't in the ruleset we can't even know what type of unit this is! So check each place
|
||||
* This works with no transients so can be called from gameInfo.setTransients with no fear
|
||||
*/
|
||||
fun removeUnit(mapUnit: MapUnit){
|
||||
when {
|
||||
airUnits.contains(mapUnit) -> airUnits.remove(mapUnit)
|
||||
civilianUnit == mapUnit -> civilianUnit = null
|
||||
else -> militaryUnit = null
|
||||
}
|
||||
}
|
||||
|
||||
fun startWorkingOnImprovement(improvement: TileImprovement, civInfo: CivilizationInfo) {
|
||||
|
Reference in New Issue
Block a user