mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 13:55:54 -04:00
Solved bug where AI units could expend all movement trying to attack enemy units when moving through fog, and would still try and attack
This commit is contained in:
parent
c92381adba
commit
4ce8704969
@ -54,15 +54,14 @@ object BattleHelper {
|
||||
sequenceOf(Pair(unit.currentTile, unit.currentMovement))
|
||||
else
|
||||
unitDistanceToTiles.asSequence()
|
||||
.map {
|
||||
val tile = it.key
|
||||
.map { (tile, distance) ->
|
||||
val movementPointsToExpendAfterMovement = if (unitMustBeSetUp) 1 else 0
|
||||
val movementPointsToExpendHere =
|
||||
if (unitMustBeSetUp && !unit.isSetUpForSiege()) 1 else 0
|
||||
val movementPointsToExpendBeforeAttack =
|
||||
if (it.key == unit.currentTile) movementPointsToExpendHere else movementPointsToExpendAfterMovement
|
||||
if (tile == unit.currentTile) movementPointsToExpendHere else movementPointsToExpendAfterMovement
|
||||
val movementLeft =
|
||||
unit.currentMovement - it.value.totalDistance - movementPointsToExpendBeforeAttack
|
||||
unit.currentMovement - distance.totalDistance - movementPointsToExpendBeforeAttack
|
||||
Pair(tile, movementLeft)
|
||||
}
|
||||
// still got leftover movement points after all that, to attack (0.1 is because of Float nonsense, see MapUnit.moveToTile(...)
|
||||
@ -116,8 +115,8 @@ object BattleHelper {
|
||||
}
|
||||
|
||||
fun tryDisembarkUnitToAttackPosition(unit: MapUnit): Boolean {
|
||||
val unitDistanceToTiles = unit.movement.getDistanceToTiles()
|
||||
if (!unit.baseUnit.isMelee() || !unit.baseUnit.isLandUnit() || !unit.isEmbarked()) return false
|
||||
val unitDistanceToTiles = unit.movement.getDistanceToTiles()
|
||||
|
||||
val attackableEnemiesNextTurn = getAttackableEnemies(unit, unitDistanceToTiles)
|
||||
// Only take enemies we can fight without dying
|
||||
|
@ -29,6 +29,8 @@ object Battle {
|
||||
attacker.unit.movement.moveToTile(attackableTile.tileToAttackFrom)
|
||||
/** You might ask: When can this possibly happen?
|
||||
* We always receive an AttackableTile, which means that it was returned from getAttackableTiles!
|
||||
* And getAttackableTiles should ensure that we return only units that are in the range of movement!
|
||||
*
|
||||
* The answer is: when crossing a HIDDEN TILE.
|
||||
* When calculating movement distance, we assume that a hidden tile is 1 movement point,
|
||||
* which can lead to EXCEEDINGLY RARE edge cases where you think
|
||||
@ -36,6 +38,11 @@ object Battle {
|
||||
* but the hidden tile is actually IMPASSIBLE so you stop halfway!
|
||||
*/
|
||||
if (attacker.getTile() != attackableTile.tileToAttackFrom) return
|
||||
/** Alternatively, maybe we DID reach that tile, but it turned out to be a hill or something,
|
||||
* so we expended all of our movement points!
|
||||
*/
|
||||
if (attacker.unit.currentMovement != attackableTile.movementLeftAfterMovingToAttackTile)
|
||||
return
|
||||
if (attacker.unit.hasUnique(UniqueType.MustSetUp) && !attacker.unit.isSetUpForSiege()) {
|
||||
attacker.unit.action = UnitActionType.SetUp.value
|
||||
attacker.unit.useMovementPoints(1f)
|
||||
|
Loading…
x
Reference in New Issue
Block a user