mirror of
https://github.com/yairm210/Unciv.git
synced 2025-03-03 22:22:51 +07:00
Resolved #8563 - ultra-rare 'destroy civilian unit before attack' crash
This commit is contained in:
parent
bf1850cf2e
commit
328cf56a22
@ -1,6 +1,8 @@
|
||||
package com.unciv.logic.automation.unit
|
||||
|
||||
import com.unciv.logic.battle.ICombatant
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
|
||||
class AttackableTile(val tileToAttackFrom: Tile, val tileToAttack: Tile,
|
||||
val movementLeftAfterMovingToAttackTile:Float)
|
||||
val movementLeftAfterMovingToAttackTile:Float,
|
||||
/** This is only for debug purposes */ val combatant:ICombatant)
|
||||
|
@ -73,18 +73,23 @@ object BattleHelper {
|
||||
if (tile in tilesWithEnemies) attackableTiles += AttackableTile(
|
||||
reachableTile,
|
||||
tile,
|
||||
movementLeft
|
||||
movementLeft,
|
||||
Battle.getMapCombatantOfTile(tile)!!
|
||||
)
|
||||
else if (tile in tilesWithoutEnemies) continue // avoid checking the same empty tile multiple times
|
||||
else if (checkTile(unit, tile, tilesToCheck)) {
|
||||
tilesWithEnemies += tile
|
||||
attackableTiles += AttackableTile(reachableTile, tile, movementLeft)
|
||||
} else if (unit.isPreparingAirSweep()){
|
||||
attackableTiles += AttackableTile(
|
||||
reachableTile, tile, movementLeft,
|
||||
Battle.getMapCombatantOfTile(tile)!!
|
||||
)
|
||||
} else if (unit.isPreparingAirSweep()) {
|
||||
tilesWithEnemies += tile
|
||||
attackableTiles += AttackableTile(reachableTile, tile, movementLeft)
|
||||
} else {
|
||||
tilesWithoutEnemies += tile
|
||||
}
|
||||
attackableTiles += AttackableTile(
|
||||
reachableTile, tile, movementLeft,
|
||||
Battle.getMapCombatantOfTile(tile)!!
|
||||
)
|
||||
} else tilesWithoutEnemies += tile
|
||||
}
|
||||
}
|
||||
return attackableTiles
|
||||
|
@ -62,12 +62,14 @@ object Battle {
|
||||
*/
|
||||
if (attacker.getTile() != attackableTile.tileToAttackFrom) return false
|
||||
/** Rarely, a melee unit will target a civilian then move through the civilian to get
|
||||
* to attackableTile.tileToAttackFrom, meaning that they take the civilian. This check stops
|
||||
* the melee unit from trying to capture their own unit if this happens */
|
||||
if (getMapCombatantOfTile(attackableTile.tileToAttack)!!.getCivInfo() == attacker.getCivInfo()) return false
|
||||
* to attackableTile.tileToAttackFrom, meaning that they take the civilian.
|
||||
* This can lead to:
|
||||
* A. the melee unit from trying to capture their own unit (see #7282)
|
||||
* B. The civilian unit disappearing entirely (e.g. Great Person) and trying to capture a non-existent unit (see #8563) */
|
||||
val combatant = getMapCombatantOfTile(attackableTile.tileToAttack)
|
||||
if (combatant == null || combatant.getCivInfo() == attacker.getCivInfo()) return false
|
||||
/** Alternatively, maybe we DID reach that tile, but it turned out to be a hill or something,
|
||||
* so we expended all of our movement points!
|
||||
*/
|
||||
* so we expended all of our movement points! */
|
||||
if (attacker.hasUnique(UniqueType.MustSetUp)
|
||||
&& !attacker.unit.isSetUpForSiege()
|
||||
&& attacker.unit.currentMovement > 0f
|
||||
|
@ -341,9 +341,9 @@ class UncivFiles(
|
||||
/** @throws IncompatibleGameInfoVersionException if the [gameData] was created by a version of this game that is incompatible with the current one. */
|
||||
fun gameInfoFromString(gameData: String): GameInfo {
|
||||
val unzippedJson = try {
|
||||
Gzip.unzip(gameData)
|
||||
Gzip.unzip(gameData.trim())
|
||||
} catch (ex: Exception) {
|
||||
gameData
|
||||
gameData.trim()
|
||||
}
|
||||
val gameInfo = try {
|
||||
json().fromJson(GameInfo::class.java, unzippedJson)
|
||||
|
@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.automation.unit.AttackableTile
|
||||
import com.unciv.logic.automation.unit.BattleHelper
|
||||
import com.unciv.logic.automation.unit.UnitAutomation
|
||||
import com.unciv.logic.battle.Battle
|
||||
@ -13,7 +14,6 @@ import com.unciv.logic.battle.CityCombatant
|
||||
import com.unciv.logic.battle.ICombatant
|
||||
import com.unciv.logic.battle.MapUnitCombatant
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
import com.unciv.logic.automation.unit.AttackableTile
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.translations.tr
|
||||
@ -267,7 +267,7 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
|
||||
} else if (attacker is CityCombatant) {
|
||||
val canBombard = UnitAutomation.getBombardableTiles(attacker.city).contains(defender.getTile())
|
||||
if (canBombard) {
|
||||
attackableTile = AttackableTile(attacker.getTile(), defender.getTile(), 0f)
|
||||
attackableTile = AttackableTile(attacker.getTile(), defender.getTile(), 0f, defender)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user