mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-07 14:02:48 +07:00
parent
936b9e34ef
commit
fe1b5825bb
@ -3,6 +3,7 @@ package com.unciv.logic.map.mapunit
|
||||
import com.unciv.Constants
|
||||
import com.unciv.models.ruleset.tile.TerrainType
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
|
||||
class MapUnitCache(val mapUnit: MapUnit) {
|
||||
@ -47,9 +48,10 @@ class MapUnitCache(val mapUnit: MapUnit) {
|
||||
|
||||
/** Used for getMovementCostBetweenAdjacentTiles only, based on order of testing */
|
||||
enum class DoubleMovementTerrainTarget { Feature, Base, Hill, Filter }
|
||||
class DoubleMovement(val terrainTarget: DoubleMovementTerrainTarget, val unique: Unique)
|
||||
/** Mod-friendly cache of double-movement terrains */
|
||||
@Transient
|
||||
val doubleMovementInTerrain = HashMap<String, DoubleMovementTerrainTarget>()
|
||||
val doubleMovementInTerrain = HashMap<String, DoubleMovement>()
|
||||
|
||||
@Transient
|
||||
var canEnterIceTiles = false
|
||||
@ -86,24 +88,25 @@ class MapUnitCache(val mapUnit: MapUnit) {
|
||||
roughTerrainPenalty = mapUnit.hasUnique(UniqueType.RoughTerrainPenalty)
|
||||
|
||||
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 terrain = mapUnit.civ.gameInfo.ruleset.terrains[param]
|
||||
doubleMovementInTerrain[param] = when {
|
||||
terrain == null -> DoubleMovementTerrainTarget.Filter
|
||||
terrain.name == Constants.hill -> DoubleMovementTerrainTarget.Hill
|
||||
terrain.type == TerrainType.TerrainFeature -> DoubleMovementTerrainTarget.Feature
|
||||
terrain.type.isBaseTerrain -> DoubleMovementTerrainTarget.Base
|
||||
else -> DoubleMovementTerrainTarget.Filter
|
||||
}
|
||||
doubleMovementInTerrain[param] = DoubleMovement(unique = unique,
|
||||
terrainTarget = when {
|
||||
terrain == null -> DoubleMovementTerrainTarget.Filter
|
||||
terrain.name == Constants.hill -> DoubleMovementTerrainTarget.Hill
|
||||
terrain.type == TerrainType.TerrainFeature -> DoubleMovementTerrainTarget.Feature
|
||||
terrain.type.isBaseTerrain -> DoubleMovementTerrainTarget.Base
|
||||
else -> DoubleMovementTerrainTarget.Filter
|
||||
})
|
||||
}
|
||||
// Init shortcut flags
|
||||
noTerrainMovementUniques = doubleMovementInTerrain.isEmpty() &&
|
||||
!roughTerrainPenalty && !mapUnit.civ.nation.ignoreHillMovementCost
|
||||
noBaseTerrainOrHillDoubleMovementUniques = doubleMovementInTerrain
|
||||
.none { it.value != DoubleMovementTerrainTarget.Feature }
|
||||
.none { it.value.terrainTarget != DoubleMovementTerrainTarget.Feature }
|
||||
noFilteredDoubleMovementUniques = doubleMovementInTerrain
|
||||
.none { it.value == DoubleMovementTerrainTarget.Filter }
|
||||
.none { it.value.terrainTarget == DoubleMovementTerrainTarget.Filter }
|
||||
costToDisembark = (mapUnit.getMatchingUniques(UniqueType.ReducedDisembarkCost, checkCivInfoUniques = true))
|
||||
.minOfOrNull { it.params[0].toFloat() }
|
||||
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.Tile
|
||||
import com.unciv.models.helpers.UnitMovementMemoryType
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
|
||||
class UnitMovement(val unit: MapUnit) {
|
||||
@ -60,7 +61,8 @@ class UnitMovement(val unit: MapUnit) {
|
||||
// when entering territory of a city state
|
||||
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))
|
||||
return unit.civ.tech.movementSpeedOnRoads + extraCost
|
||||
@ -73,7 +75,29 @@ class UnitMovement(val unit: MapUnit) {
|
||||
if (unit.cache.noTerrainMovementUniques)
|
||||
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
|
||||
|
||||
if (unit.cache.roughTerrainPenalty && to.isRoughTerrain())
|
||||
@ -86,17 +110,18 @@ class UnitMovement(val unit: MapUnit) {
|
||||
if (unit.cache.noBaseTerrainOrHillDoubleMovementUniques)
|
||||
return terrainCost + extraCost
|
||||
|
||||
if (unit.cache.doubleMovementInTerrain[to.baseTerrain] == MapUnitCache.DoubleMovementTerrainTarget.Base)
|
||||
if (matchesTerrainTarget(to.baseTerrain, MapUnitCache.DoubleMovementTerrainTarget.Base))
|
||||
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
|
||||
|
||||
if (unit.cache.noFilteredDoubleMovementUniques)
|
||||
return terrainCost + extraCost
|
||||
if (unit.cache.doubleMovementInTerrain.any {
|
||||
it.value == MapUnitCache.DoubleMovementTerrainTarget.Filter &&
|
||||
to.matchesFilter(it.key)
|
||||
})
|
||||
matchesTerrainTarget(it.value, MapUnitCache.DoubleMovementTerrainTarget.Filter)
|
||||
&& to.matchesFilter(it.key)
|
||||
})
|
||||
return terrainCost * 0.5f + extraCost
|
||||
|
||||
return terrainCost + extraCost // no road or other movement cost reduction
|
||||
|
Loading…
Reference in New Issue
Block a user