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:
yairm210 2021-11-11 23:34:43 +02:00
parent c92381adba
commit 4ce8704969
2 changed files with 11 additions and 5 deletions

View File

@ -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

View File

@ -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)