Fix crash caused by cascaded ruins unit gifts (#4133)

* Fix d1f6c5ac breaking builds

* Fix d1f6c5ac breaking builds - patch1

* Fix silent crash when ancient ruins cascade gifted units
This commit is contained in:
SomeTroglodyte 2021-06-14 13:44:43 +02:00 committed by GitHub
parent d1f6c5ac0a
commit 07a43f3f1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 52 additions and 36 deletions

View File

@ -2882,7 +2882,7 @@ Professional Army = Profesionální armáda
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = Kompletní Čest
Honor = Čest
+[amount]% Strength vs [param] = +[amount]% síly proti [unitType]
+[amount]% Strength vs [param] = +[amount]% síly proti [param]
Notified of new Barbarian encampments = Upozornění na nový Barbarský tábor
Organized Religion = Organizovaná víra

View File

@ -4101,7 +4101,7 @@ Gold cost of upgrading [unitType] units reduced by [amount]% =
# Requires translation!
Honor Complete =
Honor = Eer
+[amount]% Strength vs [param] = +[amount]% Kracht vs [unitType]
+[amount]% Strength vs [param] = +[amount]% Kracht vs [param]
# Requires translation!
Notified of new Barbarian encampments =

View File

@ -2859,7 +2859,7 @@ Professional Army = Berufsarmee
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = Ehre vollständig
Honor = Ehre
+[amount]% Strength vs [param] = +[amount]% Stärke gegen [unitType]
+[amount]% Strength vs [param] = +[amount]% Stärke gegen [param]
Notified of new Barbarian encampments = Benachrichtigungen über neue Barbarenlager
Organized Religion = Organisierte Religion

View File

@ -2885,7 +2885,7 @@ Professional Army = Prajurit Profesional
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = Kehormatan Lengkap
Honor = Kehormatan
+[amount]% Strength vs [param] = +[amount]% Kekuatan vs [unitType]
+[amount]% Strength vs [param] = +[amount]% Kekuatan vs [param]
Notified of new Barbarian encampments = Diberi tahu ketika muncul perkemahan orang Barbar baru
Organized Religion = Agama Terorganisasi

View File

@ -2859,7 +2859,7 @@ Professional Army = Esercito professionale
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = Onore Completo
Honor = Onore
+[amount]% Strength vs [param] = +[amount]% Strength contro [unitType]
+[amount]% Strength vs [param] = +[amount]% Strength contro [param]
Notified of new Barbarian encampments = Sarai notificato dei nuovi accampamenti barbari
Organized Religion = Religione Organizzata

View File

@ -2914,7 +2914,7 @@ Professional Army = 軍隊の常備
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = 名誉コンプリート
Honor = 名誉
+[amount]% Strength vs [param] = [unitType]に対して戦闘力+[amount]%
+[amount]% Strength vs [param] = [param]に対して戦闘力+[amount]%
Notified of new Barbarian encampments = 新たな蛮族の野営地が出現すると通知
Organized Religion = 宗教の組織化

View File

@ -2954,7 +2954,7 @@ Professional Army = Armia Zawodowa
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = Ukończony Honor
Honor = Honor
+[amount]% Strength vs [param] = +[amount]% Siły w wlace z [unitType]
+[amount]% Strength vs [param] = +[amount]% Siły w wlace z [param]
Notified of new Barbarian encampments = Powiadomiono o nowych obozach Barbarzyńców
Organized Religion = Hierarchia Kościelna

View File

@ -2902,7 +2902,7 @@ Professional Army = Профессиональная армия
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = Честь завершена
Honor = Честь
+[amount]% Strength vs [param] = +[amount]% Силы против [unitType]
+[amount]% Strength vs [param] = +[amount]% Силы против [param]
Notified of new Barbarian encampments = Вы будете получать извещение всякий раз, когда варвары будут ставить новый лагерь
Organized Religion = Организованная религия

View File

@ -2897,7 +2897,7 @@ Professional Army = 职业军队
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = 完整的荣誉政策
Honor = 荣誉政策
+[amount]% Strength vs [param] = 对战[unitType]时+[amount]%战斗力
+[amount]% Strength vs [param] = 对战[param]时+[amount]%战斗力
Notified of new Barbarian encampments = 新的蛮族营地出现时将会通知
Organized Religion = 教会组织

View File

@ -2859,7 +2859,7 @@ Professional Army = Ejercito Profesional
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = Honor Completado
Honor = Honor
+[amount]% Strength vs [param] = +[amount]% de Fuerza vs [unitType]
+[amount]% Strength vs [param] = +[amount]% de Fuerza vs [param]
Notified of new Barbarian encampments = Notificado de nuevos campamentos Bárbaros
Organized Religion = Religión Organizada

View File

@ -2885,7 +2885,7 @@ Professional Army = Professionell Armé
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = Heder Fullbordat
Honor = Heder
+[amount]% Strength vs [param] = +[amount]% Styrka mot [unitType]
+[amount]% Strength vs [param] = +[amount]% Styrka mot [param]
Notified of new Barbarian encampments = Uppmärksammas på nya Barbarläger
Organized Religion = Organiserad Religion

View File

@ -2917,7 +2917,7 @@ Professional Army = 職業軍隊
Gold cost of upgrading [unitType] units reduced by [amount]% =
Honor Complete = 完整的榮譽政策
Honor = 榮譽政策
+[amount]% Strength vs [param] = 對戰[unitType]時+[amount]%戰鬥力
+[amount]% Strength vs [param] = 對戰[param]時+[amount]%戰鬥力
Notified of new Barbarian encampments = 新的蠻族營地出現時將會通知
Organized Religion = 教會組織

View File

@ -607,6 +607,11 @@ class CivilizationInfo {
}
}
/** Tries to place the a [unitName] unit into the [TileInfo] closest to the given the [position]
* @param location where to try to place the unit
* @param unitName name of the [BaseUnit] to create and place
* @return created [MapUnit] or null if no suitable location was found
* */
fun placeUnitNearTile(location: Vector2, unitName: String): MapUnit? {
return gameInfo.tileMap.placeUnitNearTile(location, unitName, this)
}

View File

@ -596,14 +596,15 @@ class MapUnit {
fun removeFromTile() = currentTile.removeUnit(this)
fun moveThroughTile(tile: TileInfo) {
// addPromotion requires currentTile to be valid because it accesses ruleset through it
// getAncientRuinBonus, if it places a new unit, does too
currentTile = tile
if (tile.improvement == Constants.ancientRuins && civInfo.isMajorCiv())
getAncientRuinBonus(tile)
if (tile.improvement == Constants.barbarianEncampment && !civInfo.isBarbarian())
clearEncampment(tile)
// addPromotion requires currentTile to be valid because it accesses ruleset through it
currentTile = tile
if (!hasUnique("All healing effects doubled") && type.isLandUnit() && type.isMilitary()) {
val gainDoubleHealPromotion = tile.neighbors
.any { it.hasUnique("Grants Rejuvenation (all healing effects doubled) to adjacent military land units for the rest of the game") }
@ -676,6 +677,17 @@ class MapUnit {
tile.improvement = null
val tileBasedRandom = Random(tile.position.toString().hashCode())
val actions: ArrayList<() -> Unit> = ArrayList()
fun goldBonus() {
val amount = listOf(25, 60, 100).random(tileBasedRandom)
civInfo.addGold(amount)
civInfo.addNotification(
"We have found a stash of [$amount] gold in the ruins!",
tile.position,
NotificationIcon.Gold
)
}
if (civInfo.cities.isNotEmpty()) actions.add {
val city = civInfo.cities.random(tileBasedRandom)
city.population.population++
@ -687,6 +699,7 @@ class MapUnit {
NotificationIcon.Growth
)
}
val researchableAncientEraTechs = tile.tileMap.gameInfo.ruleSet.technologies.values
.filter {
!civInfo.tech.isResearched(it.name)
@ -705,14 +718,19 @@ class MapUnit {
)
}
val possibleUnits = listOf(Constants.settler, Constants.worker, "Warrior")
.filter { civInfo.gameInfo.ruleSet.units.containsKey(it) }
val possibleUnits = (
//City-States and OCC don't get settler from ruins
listOf(Constants.settler).filterNot { civInfo.isCityState() || civInfo.isOneCityChallenger() }
+ listOf(Constants.worker, "Warrior")
).filter { civInfo.gameInfo.ruleSet.units.containsKey(it) }
if (possibleUnits.isNotEmpty())
actions.add {
val chosenUnit = possibleUnits.random(tileBasedRandom)
if (!(civInfo.isCityState() || civInfo.isOneCityChallenger()) || chosenUnit != Constants.settler) { //City-States and OCC don't get settler from ruins
civInfo.placeUnitNearTile(tile.position, chosenUnit)
// placeUnitNearTile _can_ fail, and since this code can run behind a try with empty
// catch inside nested thread switches - petter play it safe
if (civInfo.placeUnitNearTile(tile.position, chosenUnit) == null) {
goldBonus()
} else {
civInfo.addNotification(
"A [$chosenUnit] has joined us!",
tile.position,
@ -731,15 +749,7 @@ class MapUnit {
)
}
actions.add {
val amount = listOf(25, 60, 100).random(tileBasedRandom)
civInfo.addGold(amount)
civInfo.addNotification(
"We have found a stash of [$amount] gold in the ruins!",
tile.position,
NotificationIcon.Gold
)
}
actions.add { goldBonus() }
actions.add {
civInfo.policies.addCulture(20)

View File

@ -157,7 +157,9 @@ class TileMap {
}
/** Tries to place the [unitName] into the [TileInfo] closest to the given the [position]
/** Tries to place the [unitName] into the [TileInfo] closest to the given [position]
* @param position where to try to place the unit (or close - max 10 tiles distance)
* @param unitName name of the [BaseUnit] to create and place
* @param civInfo civilization to assign unit to
* @return created [MapUnit] or null if no suitable location was found
* */

View File

@ -4,7 +4,6 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.utils.Array
import com.unciv.JsonParser
import com.unciv.logic.battle.BattleDamage
import com.unciv.models.metadata.BaseRuleset
import com.unciv.models.ruleset.*
import com.unciv.models.ruleset.tech.TechColumn
@ -228,10 +227,6 @@ object TranslationFileWriter {
stringToTranslate = stringToTranslate.replace(parameter, parameterName)
}
} else {
// substitute the regex for "Bonus/Penalty vs ..."
val match = Regex(BattleDamage.BONUS_VS_UNIT_TYPE).matchEntire(string)
if (match != null) stringToTranslate = "${match.groupValues[1]} vs [unitType]"
}
resultStrings!!.add("$stringToTranslate = ")
return

View File

@ -202,6 +202,8 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
try {
tileToMoveTo = selectedUnit.movement.getTileToMoveToThisTurn(targetTile)
} catch (ex: Exception) {
println("Exception in getTileToMoveToThisTurn: ${ex.message}")
ex.printStackTrace()
return@thread
} // can't move here
@ -224,7 +226,9 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
if (selectedUnits.size > 1) { // We have more tiles to move
moveUnitToTargetTile(selectedUnits.subList(1, selectedUnits.size), targetTile)
} else removeUnitActionOverlay() //we're done here
} catch (e: Exception) {
} catch (ex: Exception) {
println("Exception in moveUnitToTargetTile: ${ex.message}")
ex.printStackTrace()
}
}
}