mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-06 16:28:40 +07:00
@ -3,6 +3,7 @@ package com.unciv.logic.map.mapunit
|
|||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.models.ruleset.tile.TerrainType
|
import com.unciv.models.ruleset.tile.TerrainType
|
||||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||||
|
import com.unciv.models.ruleset.unique.Unique
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
|
|
||||||
class MapUnitCache(val mapUnit: MapUnit) {
|
class MapUnitCache(val mapUnit: MapUnit) {
|
||||||
@ -47,9 +48,10 @@ class MapUnitCache(val mapUnit: MapUnit) {
|
|||||||
|
|
||||||
/** Used for getMovementCostBetweenAdjacentTiles only, based on order of testing */
|
/** Used for getMovementCostBetweenAdjacentTiles only, based on order of testing */
|
||||||
enum class DoubleMovementTerrainTarget { Feature, Base, Hill, Filter }
|
enum class DoubleMovementTerrainTarget { Feature, Base, Hill, Filter }
|
||||||
|
class DoubleMovement(val terrainTarget: DoubleMovementTerrainTarget, val unique: Unique)
|
||||||
/** Mod-friendly cache of double-movement terrains */
|
/** Mod-friendly cache of double-movement terrains */
|
||||||
@Transient
|
@Transient
|
||||||
val doubleMovementInTerrain = HashMap<String, DoubleMovementTerrainTarget>()
|
val doubleMovementInTerrain = HashMap<String, DoubleMovement>()
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
var canEnterIceTiles = false
|
var canEnterIceTiles = false
|
||||||
@ -86,24 +88,25 @@ class MapUnitCache(val mapUnit: MapUnit) {
|
|||||||
roughTerrainPenalty = mapUnit.hasUnique(UniqueType.RoughTerrainPenalty)
|
roughTerrainPenalty = mapUnit.hasUnique(UniqueType.RoughTerrainPenalty)
|
||||||
|
|
||||||
doubleMovementInTerrain.clear()
|
doubleMovementInTerrain.clear()
|
||||||
for (unique in mapUnit.getMatchingUniques(UniqueType.DoubleMovementOnTerrain)) {
|
for (unique in mapUnit.getMatchingUniques(UniqueType.DoubleMovementOnTerrain, stateForConditionals = StateForConditionals.IgnoreConditionals)) {
|
||||||
val param = unique.params[0]
|
val param = unique.params[0]
|
||||||
val terrain = mapUnit.civ.gameInfo.ruleset.terrains[param]
|
val terrain = mapUnit.civ.gameInfo.ruleset.terrains[param]
|
||||||
doubleMovementInTerrain[param] = when {
|
doubleMovementInTerrain[param] = DoubleMovement(unique = unique,
|
||||||
|
terrainTarget = when {
|
||||||
terrain == null -> DoubleMovementTerrainTarget.Filter
|
terrain == null -> DoubleMovementTerrainTarget.Filter
|
||||||
terrain.name == Constants.hill -> DoubleMovementTerrainTarget.Hill
|
terrain.name == Constants.hill -> DoubleMovementTerrainTarget.Hill
|
||||||
terrain.type == TerrainType.TerrainFeature -> DoubleMovementTerrainTarget.Feature
|
terrain.type == TerrainType.TerrainFeature -> DoubleMovementTerrainTarget.Feature
|
||||||
terrain.type.isBaseTerrain -> DoubleMovementTerrainTarget.Base
|
terrain.type.isBaseTerrain -> DoubleMovementTerrainTarget.Base
|
||||||
else -> DoubleMovementTerrainTarget.Filter
|
else -> DoubleMovementTerrainTarget.Filter
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
// Init shortcut flags
|
// Init shortcut flags
|
||||||
noTerrainMovementUniques = doubleMovementInTerrain.isEmpty() &&
|
noTerrainMovementUniques = doubleMovementInTerrain.isEmpty() &&
|
||||||
!roughTerrainPenalty && !mapUnit.civ.nation.ignoreHillMovementCost
|
!roughTerrainPenalty && !mapUnit.civ.nation.ignoreHillMovementCost
|
||||||
noBaseTerrainOrHillDoubleMovementUniques = doubleMovementInTerrain
|
noBaseTerrainOrHillDoubleMovementUniques = doubleMovementInTerrain
|
||||||
.none { it.value != DoubleMovementTerrainTarget.Feature }
|
.none { it.value.terrainTarget != DoubleMovementTerrainTarget.Feature }
|
||||||
noFilteredDoubleMovementUniques = doubleMovementInTerrain
|
noFilteredDoubleMovementUniques = doubleMovementInTerrain
|
||||||
.none { it.value == DoubleMovementTerrainTarget.Filter }
|
.none { it.value.terrainTarget == DoubleMovementTerrainTarget.Filter }
|
||||||
costToDisembark = (mapUnit.getMatchingUniques(UniqueType.ReducedDisembarkCost, checkCivInfoUniques = true))
|
costToDisembark = (mapUnit.getMatchingUniques(UniqueType.ReducedDisembarkCost, checkCivInfoUniques = true))
|
||||||
.minOfOrNull { it.params[0].toFloat() }
|
.minOfOrNull { it.params[0].toFloat() }
|
||||||
costToEmbark = mapUnit.getMatchingUniques(UniqueType.ReducedEmbarkCost, checkCivInfoUniques = true)
|
costToEmbark = mapUnit.getMatchingUniques(UniqueType.ReducedEmbarkCost, checkCivInfoUniques = true)
|
||||||
|
@ -8,6 +8,7 @@ import com.unciv.logic.map.HexMath.getDistance
|
|||||||
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.models.helpers.UnitMovementMemoryType
|
import com.unciv.models.helpers.UnitMovementMemoryType
|
||||||
|
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
|
|
||||||
class UnitMovement(val unit: MapUnit) {
|
class UnitMovement(val unit: MapUnit) {
|
||||||
@ -60,7 +61,8 @@ class UnitMovement(val unit: MapUnit) {
|
|||||||
// when entering territory of a city state
|
// when entering territory of a city state
|
||||||
val areConnectedByRoad = from.hasConnection(civInfo) && to.hasConnection(civInfo)
|
val areConnectedByRoad = from.hasConnection(civInfo) && to.hasConnection(civInfo)
|
||||||
|
|
||||||
val areConnectedByRiver = from.isAdjacentToRiver() && to.isAdjacentToRiver() && from.isConnectedByRiver(to)
|
val areConnectedByRiver =
|
||||||
|
from.isAdjacentToRiver() && to.isAdjacentToRiver() && from.isConnectedByRiver(to)
|
||||||
|
|
||||||
if (areConnectedByRoad && (!areConnectedByRiver || civInfo.tech.roadsConnectAcrossRivers))
|
if (areConnectedByRoad && (!areConnectedByRiver || civInfo.tech.roadsConnectAcrossRivers))
|
||||||
return unit.civ.tech.movementSpeedOnRoads + extraCost
|
return unit.civ.tech.movementSpeedOnRoads + extraCost
|
||||||
@ -73,7 +75,29 @@ class UnitMovement(val unit: MapUnit) {
|
|||||||
if (unit.cache.noTerrainMovementUniques)
|
if (unit.cache.noTerrainMovementUniques)
|
||||||
return terrainCost + extraCost
|
return terrainCost + extraCost
|
||||||
|
|
||||||
if (to.terrainFeatures.any { unit.cache.doubleMovementInTerrain[it] == MapUnitCache.DoubleMovementTerrainTarget.Feature })
|
val stateForConditionals = StateForConditionals(unit.civ, unit = unit, tile = to)
|
||||||
|
fun matchesTerrainTarget(
|
||||||
|
doubleMovement: MapUnitCache.DoubleMovement,
|
||||||
|
target: MapUnitCache.DoubleMovementTerrainTarget
|
||||||
|
): Boolean {
|
||||||
|
if (doubleMovement.terrainTarget != target) return false
|
||||||
|
if (doubleMovement.unique.conditionals.isNotEmpty()) {
|
||||||
|
if (!doubleMovement.unique.conditionalsApply(stateForConditionals)) return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun matchesTerrainTarget(
|
||||||
|
terrainName: String,
|
||||||
|
target: MapUnitCache.DoubleMovementTerrainTarget
|
||||||
|
): Boolean {
|
||||||
|
val doubleMovement = unit.cache.doubleMovementInTerrain[terrainName] ?: return false
|
||||||
|
return matchesTerrainTarget(doubleMovement, target)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (to.terrainFeatures.any { matchesTerrainTarget(it, MapUnitCache.DoubleMovementTerrainTarget.Feature) })
|
||||||
return terrainCost * 0.5f + extraCost
|
return terrainCost * 0.5f + extraCost
|
||||||
|
|
||||||
if (unit.cache.roughTerrainPenalty && to.isRoughTerrain())
|
if (unit.cache.roughTerrainPenalty && to.isRoughTerrain())
|
||||||
@ -86,16 +110,17 @@ class UnitMovement(val unit: MapUnit) {
|
|||||||
if (unit.cache.noBaseTerrainOrHillDoubleMovementUniques)
|
if (unit.cache.noBaseTerrainOrHillDoubleMovementUniques)
|
||||||
return terrainCost + extraCost
|
return terrainCost + extraCost
|
||||||
|
|
||||||
if (unit.cache.doubleMovementInTerrain[to.baseTerrain] == MapUnitCache.DoubleMovementTerrainTarget.Base)
|
if (matchesTerrainTarget(to.baseTerrain, MapUnitCache.DoubleMovementTerrainTarget.Base))
|
||||||
return terrainCost * 0.5f + extraCost
|
return terrainCost * 0.5f + extraCost
|
||||||
if (unit.cache.doubleMovementInTerrain[Constants.hill] == MapUnitCache.DoubleMovementTerrainTarget.Hill && to.isHill())
|
if (matchesTerrainTarget(Constants.hill, MapUnitCache.DoubleMovementTerrainTarget.Hill)
|
||||||
|
&& to.isHill())
|
||||||
return terrainCost * 0.5f + extraCost
|
return terrainCost * 0.5f + extraCost
|
||||||
|
|
||||||
if (unit.cache.noFilteredDoubleMovementUniques)
|
if (unit.cache.noFilteredDoubleMovementUniques)
|
||||||
return terrainCost + extraCost
|
return terrainCost + extraCost
|
||||||
if (unit.cache.doubleMovementInTerrain.any {
|
if (unit.cache.doubleMovementInTerrain.any {
|
||||||
it.value == MapUnitCache.DoubleMovementTerrainTarget.Filter &&
|
matchesTerrainTarget(it.value, MapUnitCache.DoubleMovementTerrainTarget.Filter)
|
||||||
to.matchesFilter(it.key)
|
&& to.matchesFilter(it.key)
|
||||||
})
|
})
|
||||||
return terrainCost * 0.5f + extraCost
|
return terrainCost * 0.5f + extraCost
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user