From 0088ddd18b63e6577e96d8061f8f80eba756dc94 Mon Sep 17 00:00:00 2001 From: yairm210 Date: Mon, 6 Dec 2021 19:19:37 +0200 Subject: [PATCH] Solved bug that made civilian units uncapturable --- .../unciv/logic/automation/BattleHelper.kt | 7 +- .../unciv/ui/worldscreen/unit/UnitActions.kt | 106 ++++++++---------- 2 files changed, 54 insertions(+), 59 deletions(-) diff --git a/core/src/com/unciv/logic/automation/BattleHelper.kt b/core/src/com/unciv/logic/automation/BattleHelper.kt index 96cdff5107..d9c31d6613 100644 --- a/core/src/com/unciv/logic/automation/BattleHelper.kt +++ b/core/src/com/unciv/logic/automation/BattleHelper.kt @@ -39,11 +39,14 @@ object BattleHelper { ): ArrayList { val tilesWithEnemies = (tilesToCheck ?: unit.civInfo.viewableTiles) .filter { containsAttackableEnemy(it, MapUnitCombatant(unit)) } - .filterNot { val mapCombatant = Battle.getMapCombatantOfTile(it) + .filterNot { + val mapCombatant = Battle.getMapCombatantOfTile(it) // IF all of these are true, THEN the action we'll be taking is in fact CAPTURING the civilian. unit.baseUnit.isMelee() && mapCombatant is MapUnitCombatant && mapCombatant.unit.isCivilian() // If we can't pass though that tile, we can't capture the civilian "remotely" - && !unit.movement.canPassThrough(it) + // DO NOT use "!unit.movement.canPassThrough(it)" since then we won't be able to + // capture enemy units since we can't move through them! + && !it.canCivPassThrough(unit.civInfo) } val rangeOfAttack = unit.getRange() diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt index f77526faea..dd57018889 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt @@ -48,7 +48,7 @@ object UnitActions { addSleepActions(actionList, unit, false) addFortifyActions(actionList, unit, false) - + addPromoteAction(unit, actionList) addUnitUpgradeAction(unit, actionList) addPillageAction(unit, actionList, worldScreen) @@ -63,7 +63,7 @@ object UnitActions { actionList += getImprovementConstructionActions(unit, tile) addActionsWithLimitedUses(unit, actionList, tile) - + addToggleActionsAction(unit, actionList, unitTable) return actionList @@ -285,8 +285,8 @@ object UnitActions { tile.improvement = null if (tile.resource != null) tile.getOwner()?.updateDetailedCivResources() // this might take away a resource - val freePillage = unit.hasUnique("No movement cost to pillage") - || unit.civInfo.hasUnique("No movement cost to pillage") + val freePillage = unit.hasUnique("No movement cost to pillage") + || unit.civInfo.hasUnique("No movement cost to pillage") || (unit.baseUnit.isMelee() && unit.civInfo.hasUnique("Melee units pay no movement cost to pillage")) if (!freePillage) unit.useMovementPoints(1f) @@ -312,7 +312,7 @@ object UnitActions { val tile = unit.currentTile if (unit.baseUnit().upgradesTo == null || !unit.canUpgrade()) return null if (tile.getOwner() != unit.civInfo && !isFree) return null - val goldCostOfUpgrade = + val goldCostOfUpgrade = if (isFree) 0 else unit.getCostOfUpgrade() val upgradedUnit = unit.getUnitToUpgradeTo() @@ -345,7 +345,7 @@ object UnitActions { } ) } - + fun getAncientRuinsUpgradeAction(unit: MapUnit): UnitAction? { val upgradedUnitName = when { @@ -353,12 +353,12 @@ object UnitActions { unit.baseUnit.upgradesTo != null -> unit.baseUnit.upgradesTo else -> return null } - val upgradedUnit = + val upgradedUnit = unit.civInfo.getEquivalentUnit( unit.civInfo.gameInfo.ruleSet.units[upgradedUnitName]!! ) if (!unit.canUpgrade(upgradedUnit,true)) return null - + return UnitAction(UnitActionType.Upgrade, title = "Upgrade to [${upgradedUnit.name}] (free)", action = { @@ -366,7 +366,7 @@ object UnitActions { unit.destroy() val newUnit = unit.civInfo.placeUnitNearTile(unitTile.position, upgradedUnit.name)!! unit.copyStatisticsTo(newUnit) - + newUnit.currentMovement = 0f } ) @@ -428,7 +428,7 @@ object UnitActions { val canHurryWonder = if (!tile.isCityCenter()) false else tile.getCity()!!.cityConstructions.isBuildingWonder() - + actionList += UnitAction(UnitActionType.HurryWonder, action = { @@ -437,21 +437,21 @@ object UnitActions { addProductionPoints(((300 + 30 * tile.getCity()!!.population.population) * unit.civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt()) constructIfEnough() } - + addStatsPerGreatPersonUsage(unit) unit.destroy() }.takeIf { canHurryWonder } ) } - + "Can speed up construction of a building" -> { if (!tile.isCityCenter()) { actionList += UnitAction(UnitActionType.HurryBuilding, action = null) continue } - + val canHurryConstruction = tile.getCity()!!.cityConstructions.getCurrentConstruction() is Building - + val cityConstructions = tile.getCity()!!.cityConstructions //http://civilization.wikia.com/wiki/Great_engineer_(Civ5) @@ -459,15 +459,15 @@ object UnitActions { (300 + 30 * tile.getCity()!!.population.population) * unit.civInfo.gameInfo.gameParameters.gameSpeed.modifier, cityConstructions.getRemainingWork(cityConstructions.currentConstructionFromQueue).toFloat() - 1 ).toInt() - + actionList += UnitAction(UnitActionType.HurryBuilding, title = "Hurry Construction (+[$productionPointsToAdd]⚙)", action = { cityConstructions.apply { - addProductionPoints(productionPointsToAdd) + addProductionPoints(productionPointsToAdd) constructIfEnough() } - + addStatsPerGreatPersonUsage(unit) unit.destroy() }.takeIf { canHurryConstruction } @@ -502,7 +502,7 @@ object UnitActions { action = getFoundReligionAction(unit).takeIf { unit.civInfo.religionManager.mayFoundReligionNow(unit) } ) } - + fun getFoundReligionAction(unit: MapUnit): () -> Unit { return { addStatsPerGreatPersonUsage(unit) @@ -519,7 +519,7 @@ object UnitActions { action = getEnhanceReligionAction(unit).takeIf { unit.civInfo.religionManager.mayEnhanceReligionNow(unit) } ) } - + fun getEnhanceReligionAction(unit: MapUnit): () -> Unit { return { addStatsPerGreatPersonUsage(unit) @@ -542,7 +542,7 @@ object UnitActions { } } } - + private fun useActionWithLimitedUses(unit: MapUnit, action: String) { unit.abilityUsesLeft[action] = unit.abilityUsesLeft[action]!! - 1 if (unit.abilityUsesLeft[action]!! <= 0) { @@ -573,10 +573,10 @@ object UnitActions { city.religion.removeAllPressuresExceptFor(unit.religion!!) unit.currentMovement = 0f useActionWithLimitedUses(unit, Constants.spreadReligionAbilityCount) - }.takeIf { unit.currentMovement > 0 && !blockedByInquisitor } + }.takeIf { unit.currentMovement > 0 && !blockedByInquisitor } ) } - + private fun addRemoveHeresyActions(unit: MapUnit, actionList: ArrayList, city: CityInfo) { if (!unit.civInfo.gameInfo.isReligionEnabled()) return if (city.civInfo != unit.civInfo) return @@ -599,18 +599,18 @@ object UnitActions { if (unit.religiousActionsUnitCanDo().all { unit.abilityUsesLeft[it] == unit.maxAbilityUses[it] }) uniquesToCheck += unit.getMatchingUniques("Can construct [] if it hasn't used other actions yet") val civResources = unit.civInfo.getCivResourcesByName() - + for (unique in uniquesToCheck) { val improvementName = unique.params[0] val improvement = tile.ruleset.tileImprovements[improvementName] ?: continue - + var resourcesAvailable = true - if (improvement.uniqueObjects.any { + if (improvement.uniqueObjects.any { it.isOfType(UniqueType.ConsumesResources) && civResources[unique.params[1]] ?: 0 < unique.params[0].toInt() - }) + }) resourcesAvailable = false - + finalActions += UnitAction(UnitActionType.Create, title = "Create [$improvementName]", action = { @@ -630,8 +630,8 @@ object UnitActions { addStatsPerGreatPersonUsage(unit) unit.destroy() }.takeIf { - resourcesAvailable - && unit.currentMovement > 0f + resourcesAvailable + && unit.currentMovement > 0f && tile.canBuildImprovement(improvement, unit.civInfo) && !tile.isImpassible() // Not 100% sure that this check is necessary... }) @@ -685,9 +685,9 @@ object UnitActions { fun addStatsPerGreatPersonUsage(unit: MapUnit) { if (!unit.isGreatPerson()) return - + val civInfo = unit.civInfo - + val gainedStats = Stats() for (unique in civInfo.getMatchingUniques("Provides a sum of gold each time you spend a Great Person")) { gainedStats.gold += (100 * civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt() @@ -695,9 +695,9 @@ object UnitActions { for (unique in civInfo.getMatchingUniques("[] whenever a Great Person is expended")) { gainedStats.add(unique.stats) } - + if (gainedStats.isEmpty()) return - + for (stat in gainedStats) civInfo.addStat(stat.key, stat.value.toInt()) civInfo.addNotification("By expending your [${unit.name}] you gained [${gainedStats}]!", unit.getTile().position, unit.name) @@ -723,36 +723,27 @@ object UnitActions { if (isDamaged && !showingAdditionalActions && unit.rankTileForHealing(unit.currentTile) != 0) actionList += UnitAction(UnitActionType.FortifyUntilHealed, - action = { - unit.fortifyUntilHealed() - }.takeIf { !unit.isFortifyingUntilHealed() } - ) + action = { unit.fortifyUntilHealed() }.takeIf { !unit.isFortifyingUntilHealed() }) else if (isDamaged || !showingAdditionalActions) actionList += UnitAction(UnitActionType.Fortify, - action = { - unit.fortify() - }.takeIf { !isFortified } - ) + action = { unit.fortify() }.takeIf { !isFortified }) } private fun addSleepActions(actionList: ArrayList, unit: MapUnit, showingAdditionalActions: Boolean) { if (unit.isFortified() || unit.canFortify() || unit.currentMovement == 0f) return // If this unit is working on an improvement, it cannot sleep - if ((unit.currentTile.hasImprovementInProgress() && unit.canBuildImprovement(unit.currentTile.getTileImprovementInProgress()!!))) return + if (unit.currentTile.hasImprovementInProgress() && unit.canBuildImprovement(unit.currentTile.getTileImprovementInProgress()!!)) return val isSleeping = unit.isSleeping() val isDamaged = unit.health < 100 if (isDamaged && !showingAdditionalActions) { actionList += UnitAction(UnitActionType.SleepUntilHealed, - action = { - unit.action = UnitActionType.SleepUntilHealed.value - }.takeIf { !unit.isSleepingUntilHealed() } + action = { unit.action = UnitActionType.SleepUntilHealed.value } + .takeIf { !unit.isSleepingUntilHealed() } ) } else if (isDamaged || !showingAdditionalActions) { actionList += UnitAction(UnitActionType.Sleep, - action = { - unit.action = UnitActionType.Sleep.value - }.takeIf { !isSleeping } + action = { unit.action = UnitActionType.Sleep.value }.takeIf { !isSleeping } ) } } @@ -778,7 +769,7 @@ object UnitActions { // City States only take military units (and units specifically allowed by uniques) if (recipient.isCityState()) { - if (!unit.matchesFilter("Military") + if (!unit.matchesFilter("Military") && unit.getMatchingUniques("Gain [] Influence with a [] gift to a City-State") .none { unit.matchesFilter(it.params[1]) } ) return null @@ -792,18 +783,18 @@ object UnitActions { val giftAction = { if (recipient.isCityState()) { for (unique in unit.civInfo.getMatchingUniques("Gain [] Influence with a [] gift to a City-State")) { - if (unit.matchesFilter(unique.params[1]) - ) { - recipient.getDiplomacyManager(unit.civInfo).addInfluence(unique.params[0].toFloat() - 5f) + if (unit.matchesFilter(unique.params[1])) { + recipient.getDiplomacyManager(unit.civInfo) + .addInfluence(unique.params[0].toFloat() - 5f) break } } recipient.getDiplomacyManager(unit.civInfo).addInfluence(5f) - } - else recipient.getDiplomacyManager(unit.civInfo).addModifier(DiplomaticModifiers.GaveUsUnits, 5f) + } else recipient.getDiplomacyManager(unit.civInfo) + .addModifier(DiplomaticModifiers.GaveUsUnits, 5f) - if(recipient.isCityState() && unit.isGreatPerson()) + if (recipient.isCityState() && unit.isGreatPerson()) unit.destroy() // City states dont get GPs else unit.gift(recipient) @@ -815,7 +806,8 @@ object UnitActions { private fun addToggleActionsAction(unit: MapUnit, actionList: ArrayList, unitTable: UnitTable) { actionList += UnitAction( - type = if (unit.showAdditionalActions) UnitActionType.HideAdditionalActions else UnitActionType.ShowAdditionalActions, + type = if (unit.showAdditionalActions) UnitActionType.HideAdditionalActions + else UnitActionType.ShowAdditionalActions, action = { unit.showAdditionalActions = !unit.showAdditionalActions unitTable.update() @@ -823,4 +815,4 @@ object UnitActions { ) } -} +} \ No newline at end of file