mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-24 03:53:12 -04:00
Solved rare pillage-related crash
This commit is contained in:
parent
1bf75844a3
commit
15dfb892a7
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -14,10 +14,8 @@ import com.unciv.logic.civilization.NotificationCategory
|
|||||||
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||||
import com.unciv.logic.map.mapunit.MapUnit
|
import com.unciv.logic.map.mapunit.MapUnit
|
||||||
import com.unciv.logic.map.tile.Tile
|
import com.unciv.logic.map.tile.Tile
|
||||||
import com.unciv.models.UnitActionType
|
|
||||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActions
|
|
||||||
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsPillage
|
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsPillage
|
||||||
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsUpgrade
|
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsUpgrade
|
||||||
|
|
||||||
@ -379,7 +377,9 @@ object UnitAutomation {
|
|||||||
if (unit.getTile() != tileToPillage)
|
if (unit.getTile() != tileToPillage)
|
||||||
unit.movement.moveToTile(tileToPillage)
|
unit.movement.moveToTile(tileToPillage)
|
||||||
|
|
||||||
UnitActions.invokeUnitAction(unit, UnitActionType.Pillage)
|
// We CANNOT use invokeUnitAction, since the default unit action contains a popup, which - when automated -
|
||||||
|
// runs a UI action on a side thread leading to crash!
|
||||||
|
UnitActionsPillage.getPillageAction(unit, unit.currentTile)?.action?.invoke()
|
||||||
return unit.currentMovement == 0f
|
return unit.currentMovement == 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,8 +18,9 @@ import com.unciv.logic.map.mapunit.MapUnit
|
|||||||
import com.unciv.logic.map.tile.RoadStatus
|
import com.unciv.logic.map.tile.RoadStatus
|
||||||
import com.unciv.logic.map.tile.Tile
|
import com.unciv.logic.map.tile.Tile
|
||||||
import com.unciv.logic.map.tile.TileStatFunctions
|
import com.unciv.logic.map.tile.TileStatFunctions
|
||||||
import com.unciv.models.ruleset.tile.ResourceType
|
import com.unciv.logic.map.tile.toStats
|
||||||
import com.unciv.models.UnitActionType
|
import com.unciv.models.UnitActionType
|
||||||
|
import com.unciv.models.ruleset.tile.ResourceType
|
||||||
import com.unciv.models.ruleset.tile.Terrain
|
import com.unciv.models.ruleset.tile.Terrain
|
||||||
import com.unciv.models.ruleset.tile.TileImprovement
|
import com.unciv.models.ruleset.tile.TileImprovement
|
||||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||||
@ -28,7 +29,6 @@ import com.unciv.ui.screens.worldscreen.unit.actions.UnitActions
|
|||||||
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsFromUniques
|
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsFromUniques
|
||||||
import com.unciv.utils.Log
|
import com.unciv.utils.Log
|
||||||
import com.unciv.utils.debug
|
import com.unciv.utils.debug
|
||||||
import kotlin.IllegalStateException
|
|
||||||
|
|
||||||
private object WorkerAutomationConst {
|
private object WorkerAutomationConst {
|
||||||
/** BFS max size is determined by the aerial distance of two cities to connect, padded with this */
|
/** BFS max size is determined by the aerial distance of two cities to connect, padded with this */
|
||||||
@ -129,8 +129,8 @@ class WorkerAutomation(
|
|||||||
* The improvementPriority and bestImprovement are by default not set.
|
* The improvementPriority and bestImprovement are by default not set.
|
||||||
* Once improvementPriority is set we have already checked for the best improvement, repairImprovement.
|
* Once improvementPriority is set we have already checked for the best improvement, repairImprovement.
|
||||||
*/
|
*/
|
||||||
data class TileImprovementRank(val tilePriority: Float, var improvementPriority: Float? = null,
|
data class TileImprovementRank(val tilePriority: Float, var improvementPriority: Float? = null,
|
||||||
var bestImprovement: TileImprovement? = null,
|
var bestImprovement: TileImprovement? = null,
|
||||||
var repairImprovment: Boolean? = null)
|
var repairImprovment: Boolean? = null)
|
||||||
|
|
||||||
private val tileRankings = HashMap<Tile, TileImprovementRank>()
|
private val tileRankings = HashMap<Tile, TileImprovementRank>()
|
||||||
@ -273,14 +273,14 @@ class WorkerAutomation(
|
|||||||
*/
|
*/
|
||||||
fun automateWorkerAction(unit: MapUnit, dangerousTiles: HashSet<Tile>) {
|
fun automateWorkerAction(unit: MapUnit, dangerousTiles: HashSet<Tile>) {
|
||||||
val currentTile = unit.getTile()
|
val currentTile = unit.getTile()
|
||||||
|
|
||||||
// Shortcut, we are working a good tile (like resource) and don't need to check for other tiles to work
|
// Shortcut, we are working a good tile (like resource) and don't need to check for other tiles to work
|
||||||
if (!dangerousTiles.contains(currentTile) && getFullPriority(unit.getTile(), unit) >= 10
|
if (!dangerousTiles.contains(currentTile) && getFullPriority(unit.getTile(), unit) >= 10
|
||||||
&& currentTile.improvementInProgress != null) {
|
&& currentTile.improvementInProgress != null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val tileToWork = findTileToWork(unit, dangerousTiles)
|
val tileToWork = findTileToWork(unit, dangerousTiles)
|
||||||
|
|
||||||
// If we have < 20 GPT lets not spend time connecting roads
|
// If we have < 20 GPT lets not spend time connecting roads
|
||||||
if (civInfo.stats.statsForNextTurn.gold >= 20
|
if (civInfo.stats.statsForNextTurn.gold >= 20
|
||||||
&& tryConnectingCities(unit, getImprovementPriority(tileToWork, unit))) return
|
&& tryConnectingCities(unit, getImprovementPriority(tileToWork, unit))) return
|
||||||
@ -332,14 +332,14 @@ class WorkerAutomation(
|
|||||||
throw IllegalStateException("We didn't find anything to improve on this tile even though there was supposed to be something to improve!")
|
throw IllegalStateException("We didn't find anything to improve on this tile even though there was supposed to be something to improve!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unit.cache.hasUniqueToCreateWaterImprovements) {
|
if (unit.cache.hasUniqueToCreateWaterImprovements) {
|
||||||
// Support Alpha Frontier-Style Workers that _also_ have the "May create improvements on water resources" unique
|
// Support Alpha Frontier-Style Workers that _also_ have the "May create improvements on water resources" unique
|
||||||
if (automateWorkBoats(unit)) return
|
if (automateWorkBoats(unit)) return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Lets check again if we want to build roads because we don't have a tile nearby to improve
|
//Lets check again if we want to build roads because we don't have a tile nearby to improve
|
||||||
if (civInfo.stats.statsForNextTurn.gold > 15 && tryConnectingCities(unit, 0f)) return
|
if (civInfo.stats.statsForNextTurn.gold > 15 && tryConnectingCities(unit, 0f)) return
|
||||||
|
|
||||||
val citiesToNumberOfUnimprovedTiles = HashMap<String, Int>()
|
val citiesToNumberOfUnimprovedTiles = HashMap<String, Int>()
|
||||||
for (city in unit.civ.cities) {
|
for (city in unit.civ.cities) {
|
||||||
@ -360,7 +360,7 @@ class WorkerAutomation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Nothing to do, try again to connect cities
|
// Nothing to do, try again to connect cities
|
||||||
if (civInfo.stats.statsForNextTurn.gold > 10 && tryConnectingCities(unit, 0f)) return
|
if (civInfo.stats.statsForNextTurn.gold > 10 && tryConnectingCities(unit, 0f)) return
|
||||||
|
|
||||||
|
|
||||||
debug("WorkerAutomation: %s -> nothing to do", unit.label())
|
debug("WorkerAutomation: %s -> nothing to do", unit.label())
|
||||||
@ -386,7 +386,7 @@ class WorkerAutomation(
|
|||||||
else -> 20
|
else -> 20
|
||||||
}
|
}
|
||||||
if (maxDistanceWanted < 0) return false
|
if (maxDistanceWanted < 0) return false
|
||||||
|
|
||||||
// Since further away cities take longer to get to and - most importantly - the canReach() to them is very long,
|
// Since further away cities take longer to get to and - most importantly - the canReach() to them is very long,
|
||||||
// we order cities by their closeness to the worker first, and then check for each one whether there's a viable path
|
// we order cities by their closeness to the worker first, and then check for each one whether there's a viable path
|
||||||
// it can take to an existing connected city.
|
// it can take to an existing connected city.
|
||||||
@ -476,7 +476,7 @@ class WorkerAutomation(
|
|||||||
|
|
||||||
// Search through each group by priority
|
// Search through each group by priority
|
||||||
// If we can find an eligible best tile in the group lets return that
|
// If we can find an eligible best tile in the group lets return that
|
||||||
// under the assumption that best tile is better than tiles in all lower groups
|
// under the assumption that best tile is better than tiles in all lower groups
|
||||||
for (tilePriorityGroup in workableTilesPrioritized) {
|
for (tilePriorityGroup in workableTilesPrioritized) {
|
||||||
var bestTile: Tile? = null
|
var bestTile: Tile? = null
|
||||||
for (tileInGroup in tilePriorityGroup.value.sortedBy { unit.getTile().aerialDistanceTo(it) }) {
|
for (tileInGroup in tilePriorityGroup.value.sortedBy { unit.getTile().aerialDistanceTo(it) }) {
|
||||||
@ -494,19 +494,19 @@ class WorkerAutomation(
|
|||||||
}
|
}
|
||||||
return currentTile
|
return currentTile
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate a priority for the tile without accounting for the improvement it'self
|
* Calculate a priority for the tile without accounting for the improvement it'self
|
||||||
* This is a cheap guess on how helpful it might be to do work on this tile
|
* This is a cheap guess on how helpful it might be to do work on this tile
|
||||||
*/
|
*/
|
||||||
fun getBasePriority(tile: Tile, unit: MapUnit): Float {
|
fun getBasePriority(tile: Tile, unit: MapUnit): Float {
|
||||||
val unitSpecificPriority = 2 - (tile.aerialDistanceTo(unit.getTile()) / 2.0f).coerceIn(0f, 2f)
|
val unitSpecificPriority = 2 - (tile.aerialDistanceTo(unit.getTile()) / 2.0f).coerceIn(0f, 2f)
|
||||||
if (tileRankings.containsKey(tile))
|
if (tileRankings.containsKey(tile))
|
||||||
return tileRankings[tile]!!.tilePriority + unitSpecificPriority
|
return tileRankings[tile]!!.tilePriority + unitSpecificPriority
|
||||||
|
|
||||||
var priority = 0f
|
var priority = 0f
|
||||||
if (tile.getOwner() == civInfo) {
|
if (tile.getOwner() == civInfo) {
|
||||||
priority += Automation.rankStatsValue(tile.stats.getTerrainStats(), civInfo)
|
priority += Automation.rankStatsValue(tile.stats.getTerrainStatsBreakdown().toStats(), civInfo)
|
||||||
if (tile.providesYield()) priority += 2
|
if (tile.providesYield()) priority += 2
|
||||||
if (tile.isPillaged()) priority += 1
|
if (tile.isPillaged()) priority += 1
|
||||||
// TODO: Removing fallout is hardcoded for now, but what if we want to have other bad features on tiles?
|
// TODO: Removing fallout is hardcoded for now, but what if we want to have other bad features on tiles?
|
||||||
@ -519,8 +519,8 @@ class WorkerAutomation(
|
|||||||
if (priority <= 0 && tile.hasViewableResource(civInfo)) {
|
if (priority <= 0 && tile.hasViewableResource(civInfo)) {
|
||||||
priority += 1
|
priority += 1
|
||||||
// New Resources are great!
|
// New Resources are great!
|
||||||
if (tile.tileResource.resourceType != ResourceType.Bonus
|
if (tile.tileResource.resourceType != ResourceType.Bonus
|
||||||
&& !civInfo.hasResource(tile.resource!!))
|
&& !civInfo.hasResource(tile.resource!!))
|
||||||
priority += 2
|
priority += 2
|
||||||
}
|
}
|
||||||
tileRankings[tile] = TileImprovementRank(priority)
|
tileRankings[tile] = TileImprovementRank(priority)
|
||||||
@ -566,7 +566,7 @@ class WorkerAutomation(
|
|||||||
|
|
||||||
return rank.improvementPriority!!
|
return rank.improvementPriority!!
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the full priority of the tile
|
* Calculates the full priority of the tile
|
||||||
*/
|
*/
|
||||||
@ -579,7 +579,7 @@ class WorkerAutomation(
|
|||||||
*/
|
*/
|
||||||
private fun tileHasWorkToDo(tile: Tile, unit: MapUnit): Boolean {
|
private fun tileHasWorkToDo(tile: Tile, unit: MapUnit): Boolean {
|
||||||
if (getImprovementPriority(tile, unit) <= 0) return false
|
if (getImprovementPriority(tile, unit) <= 0) return false
|
||||||
if (!(tileRankings[tile]!!.bestImprovement != null || tileRankings[tile]!!.repairImprovment!!))
|
if (!(tileRankings[tile]!!.bestImprovement != null || tileRankings[tile]!!.repairImprovment!!))
|
||||||
throw IllegalStateException("There was an improvementPriority > 0 and nothing to do")
|
throw IllegalStateException("There was an improvementPriority > 0 and nothing to do")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user