mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-26 05:14:32 -04:00
Ranged capture (#5975)
* Initial attempt * Allow Ranged to move into unguarded Civilian Unit * Comment for clarity * Fix unit test so that it doesn't segfault and checks you can't move into military units * Unify that all units can move on to (and through) unguarded civilians that you are at war with Add TileInfo.getUnguardedCivilian() to quickly respond if there is an unguarded Civilian on the tile Something is bugged in movement code * Fix MapUnit.moveThroughTile() so that it doesn't segfault by fixing getUnguardedCivilian() * captureCivilianUnit() call is now redundant in postBattleMoveToAttackedTile() since canMoveTo() will now return true and capture will happen during the moveToTile() call Co-authored-by: temurakami <spellman23@gmail.com>
This commit is contained in:
parent
336e190ff0
commit
1fd65b9ffa
@ -361,11 +361,6 @@ object Battle {
|
||||
if (!attacker.isMelee()) return
|
||||
if (!defender.isDefeated() && defender.getCivInfo() != attacker.getCivInfo()) return
|
||||
|
||||
// we destroyed an enemy military unit and there was a civilian unit in the same tile as well
|
||||
// this has to be checked before canMoveTo, otherwise it will return false
|
||||
if (attackedTile.civilianUnit != null && attackedTile.civilianUnit!!.civInfo != attacker.getCivInfo())
|
||||
captureCivilianUnit(attacker, MapUnitCombatant(attackedTile.civilianUnit!!))
|
||||
|
||||
// This is so that if we attack e.g. a barbarian in enemy territory that we can't enter, we won't enter it
|
||||
if ((attacker as MapUnitCombatant).unit.movement.canMoveTo(attackedTile)) {
|
||||
// Units that can move after attacking are not affected by zone of control if the
|
||||
@ -504,7 +499,7 @@ object Battle {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun captureCivilianUnit(attacker: ICombatant, defender: MapUnitCombatant, checkDefeat: Boolean = true) {
|
||||
fun captureCivilianUnit(attacker: ICombatant, defender: MapUnitCombatant, checkDefeat: Boolean = true) {
|
||||
// need to save this because if the unit is captured its owner wil be overwritten
|
||||
val defenderCiv = defender.getCivInfo()
|
||||
|
||||
|
@ -5,6 +5,8 @@ import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.automation.UnitAutomation
|
||||
import com.unciv.logic.automation.WorkerAutomation
|
||||
import com.unciv.logic.battle.Battle
|
||||
import com.unciv.logic.battle.MapUnitCombatant
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.city.RejectionReason
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
@ -876,6 +878,10 @@ class MapUnit {
|
||||
}
|
||||
if (tile.improvement == Constants.barbarianEncampment && !civInfo.isBarbarian())
|
||||
clearEncampment(tile)
|
||||
// Capture Enemy Civilian Unit if you move on top of it
|
||||
if (tile.getUnguardedCivilian() != null && civInfo.isAtWarWith(tile.getUnguardedCivilian()!!.civInfo)) {
|
||||
Battle.captureCivilianUnit(MapUnitCombatant(this), MapUnitCombatant(tile.civilianUnit!!))
|
||||
}
|
||||
|
||||
val promotionUniques = tile.neighbors
|
||||
.flatMap { it.getAllTerrains() }
|
||||
|
@ -128,6 +128,14 @@ open class TileInfo {
|
||||
return null
|
||||
}
|
||||
|
||||
/** Return null if military/air units on tile, or no civilian */
|
||||
fun getUnguardedCivilian(): MapUnit? {
|
||||
if (militaryUnit != null) return null
|
||||
if (airUnits.isNotEmpty()) return null
|
||||
if (civilianUnit != null) return civilianUnit!!
|
||||
return null
|
||||
}
|
||||
|
||||
fun getCity(): CityInfo? = owningCity
|
||||
|
||||
fun getLastTerrain(): Terrain = when {
|
||||
|
@ -553,7 +553,8 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||
return if (unit.isCivilian())
|
||||
tile.civilianUnit == null && (tile.militaryUnit == null || tile.militaryUnit!!.owner == unit.owner)
|
||||
else
|
||||
tile.militaryUnit == null && (tile.civilianUnit == null || tile.civilianUnit!!.owner == unit.owner)
|
||||
// can skip checking for airUnit since not a city
|
||||
tile.militaryUnit == null && (tile.civilianUnit == null || tile.civilianUnit!!.owner == unit.owner || unit.civInfo.isAtWarWith(tile.civilianUnit!!.civInfo))
|
||||
}
|
||||
|
||||
private fun canAirUnitMoveTo(tile: TileInfo, unit: MapUnit): Boolean {
|
||||
@ -618,8 +619,14 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||
if (!unit.canEnterForeignTerrain && !tile.canCivPassThrough(unit.civInfo)) return false
|
||||
|
||||
val firstUnit = tile.getFirstUnit()
|
||||
if (firstUnit != null && firstUnit.civInfo != unit.civInfo && unit.civInfo.isAtWarWith(firstUnit.civInfo))
|
||||
return false
|
||||
if (firstUnit != null) {
|
||||
// Allow movement through unguarded, at-war Civilian Unit. Capture on the way
|
||||
if (tile.getUnguardedCivilian() != null && unit.civInfo != firstUnit.civInfo && unit.civInfo.isAtWarWith(tile.civilianUnit!!.civInfo))
|
||||
return true
|
||||
// Cannot enter hostile tile with any unit in there
|
||||
if (firstUnit.civInfo != unit.civInfo && unit.civInfo.isAtWarWith(firstUnit.civInfo))
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -215,6 +215,18 @@ class UnitMovementAlgorithmsTests {
|
||||
otherCiv.nation = Nation().apply { name = Constants.barbarians }
|
||||
val otherUnit = MapUnit()
|
||||
otherUnit.civInfo = otherCiv
|
||||
otherUnit.baseUnit = BaseUnit()
|
||||
// melee check
|
||||
otherUnit.baseUnit.strength = 1
|
||||
tile.militaryUnit = otherUnit
|
||||
|
||||
for (type in ruleSet.unitTypes) {
|
||||
unit.baseUnit = BaseUnit().apply { unitType = type.key; ruleset = ruleSet }
|
||||
|
||||
Assert.assertFalse("$type must not enter occupied tile", unit.movement.canPassThrough(tile))
|
||||
}
|
||||
// ranged check
|
||||
otherUnit.baseUnit.rangedStrength = 1 // make non-Civilian ranged
|
||||
tile.militaryUnit = otherUnit
|
||||
|
||||
for (type in ruleSet.unitTypes) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user