Solved 2 edge cases - one where Unciv.resume() is called with an empty GameInfo, and the other where the MoveHereButton in TileMapHolder can throw an exception if the board changed between 2 actions.

Both impossible to replicate, both will work if the user tries again, but still better solved than unsolved.
This commit is contained in:
Yair Morgenstern
2018-12-04 20:47:37 +02:00
parent bb78673edc
commit d087a3f69a
4 changed files with 24 additions and 8 deletions

View File

@ -67,6 +67,14 @@ class UnCivGame : Game() {
override fun resume() {
ImageGetter.refreshAltas()
// This is to solve a rare problem that I still on't understand its cause -
// Sometimes, resume() is called and the gameInfo doesn't have any civilizations.
// My guess is that resume() was called but create() wasn't, or perhaps was aborted too early,
// and the original (and empty) initial GameInfo remained.
if(gameInfo.civilizations.isEmpty())
return create()
worldScreen = WorldScreen()
setWorldScreen()
}

View File

@ -2,7 +2,7 @@ package com.unciv.logic.battle
import com.unciv.logic.map.MapUnit
import com.unciv.models.gamebasics.unit.UnitType
import kotlin.math.max
import kotlin.math.min
class BattleDamageModifier(val vs:String,val modificationAmount:Float){
fun getText(): String = "vs $vs"
@ -44,10 +44,10 @@ class BattleDamage{
if(BDM.vs == "land units" && enemy.getUnitType().isLandUnit())
addToModifiers(BDM)
}
//https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php
if (combatant.getCivilization().happiness < 0)
modifiers["Unhappiness"] = max(0.02f * combatant.getCivilization().happiness,0.9f)
modifiers["Unhappiness"] = min(0.02f * combatant.getCivilization().happiness,0.9f) // otherwise it could exceed 100% and start healing enemy units...
if(combatant.getCivilization().policies.isAdopted("Populism"))
modifiers["Populism"] = 0.25f

View File

@ -126,9 +126,17 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
// this can take a long time, because of the unit-to-tile calculation needed, so we put it in a different thread
kotlin.concurrent.thread {
if (selectedUnit.movementAlgs().canReach(tileInfo)) {
selectedUnit.movementAlgs().headTowards(tileInfo)
if (selectedUnit.currentTile != tileInfo)
selectedUnit.action = "moveTo " + tileInfo.position.x.toInt() + "," + tileInfo.position.y.toInt()
try {
// Because this is darned concurrent (as it MUST be to avoid ANRs),
// there are edge cases where the canReach is true,
// but until it reaches the headTowards the board has changed and so the headTowards fails.
// I can't think of any way to avoid this,
// but it's so rare and edge-case-y that ignoring its failure is actually acceptable, hence the empty catch
selectedUnit.movementAlgs().headTowards(tileInfo)
if (selectedUnit.currentTile != tileInfo)
selectedUnit.action = "moveTo " + tileInfo.position.x.toInt() + "," + tileInfo.position.y.toInt()
}
catch (e:Exception){}
}
// we don't update it directly because we're on a different thread; instead, we tell it to update itself

View File

@ -59,8 +59,8 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
private fun getUnitActionButton(unitAction: UnitAction): Button {
val actionButton = Button(CameraStageBaseScreen.skin)
actionButton.add(getIconForUnitAction(unitAction.name)).size(20f).pad(5f)
actionButton.add(Label(unitAction.name.tr(),CameraStageBaseScreen.skin)
.setFontColor(Color.WHITE)).pad(5f)
actionButton.add(Label(unitAction.name.tr(),CameraStageBaseScreen.skin).setFontColor(Color.WHITE))
.pad(5f)
actionButton.pack()
actionButton.onClick { unitAction.action(); UnCivGame.Current.worldScreen.shouldUpdate=true }
if (!unitAction.canAct) actionButton.disable()