Resolved #3076 - automation now happens at the end of turn rather than the beginning

This commit is contained in:
Yair Morgenstern 2020-09-02 23:05:24 +03:00
parent def96071e7
commit 1b3469ea2e
4 changed files with 48 additions and 59 deletions

View File

@ -27,7 +27,7 @@ class WorkerAutomation(val unit: MapUnit) {
if (tileToWork != currentTile) { if (tileToWork != currentTile) {
val reachedTile = unit.movement.headTowards(tileToWork) val reachedTile = unit.movement.headTowards(tileToWork)
if (reachedTile != currentTile) unit.doPreTurnAction() // otherwise, we get a situation where the worker is automated, so it tries to move but doesn't, then tries to automate, then move, etc, forever. Stack overflow exception! if (reachedTile != currentTile) unit.doAction() // otherwise, we get a situation where the worker is automated, so it tries to move but doesn't, then tries to automate, then move, etc, forever. Stack overflow exception!
return return
} }
@ -52,7 +52,7 @@ class WorkerAutomation(val unit: MapUnit) {
if (mostUndevelopedCity != null && mostUndevelopedCity != unit.currentTile.owningCity) { if (mostUndevelopedCity != null && mostUndevelopedCity != unit.currentTile.owningCity) {
val reachedTile = unit.movement.headTowards(mostUndevelopedCity.getCenterTile()) val reachedTile = unit.movement.headTowards(mostUndevelopedCity.getCenterTile())
if (reachedTile != currentTile) unit.doPreTurnAction() // since we've moved, maybe we can do something here - automate if (reachedTile != currentTile) unit.doAction() // since we've moved, maybe we can do something here - automate
return return
} }

View File

@ -86,12 +86,10 @@ object Battle {
} }
if (attacker is MapUnitCombatant) { if (attacker is MapUnitCombatant) {
if (attacker.getUnitType()==UnitType.Missile) { if (attacker.getUnitType() == UnitType.Missile)
attacker.unit.destroy() attacker.unit.destroy()
} else if (attacker.unit.action != null else if (attacker.unit.isMoving())
&& attacker.unit.action!!.startsWith("moveTo")) {
attacker.unit.action = null attacker.unit.action = null
}
} }
} }

View File

@ -179,16 +179,14 @@ class MapUnit {
civInfo.updateViewableTiles() // for the civ civInfo.updateViewableTiles() // for the civ
} }
fun isFortified(): Boolean { fun isFortified() = action?.startsWith("Fortify") == true
return action?.startsWith("Fortify") == true
}
fun isSleeping(): Boolean { fun isSleeping() = action?.startsWith("Sleep") == true
return action?.startsWith("Sleep") == true
} fun isMoving() = action?.startsWith("moveTo") == true
fun getFortificationTurns(): Int { fun getFortificationTurns(): Int {
if(!isFortified()) return 0 if (!isFortified()) return 0
return action!!.split(" ")[1].toInt() return action!!.split(" ")[1].toInt()
} }
@ -200,17 +198,17 @@ class MapUnit {
fun isIdle(): Boolean { fun isIdle(): Boolean {
if (currentMovement == 0f) return false if (currentMovement == 0f) return false
if (hasUnique(Constants.workerUnique) && getTile().improvementInProgress != null) return false if (hasUnique(Constants.workerUnique) && getTile().improvementInProgress != null) return false
if (hasUnique("Can construct roads") && currentTile.improvementInProgress=="Road") return false if (hasUnique("Can construct roads") && currentTile.improvementInProgress == "Road") return false
if (isFortified()) return false if (isFortified()) return false
if (action==Constants.unitActionExplore || isSleeping() if (action == Constants.unitActionExplore || isSleeping()
|| action == Constants.unitActionAutomation) return false || action == Constants.unitActionAutomation || isMoving()) return false
return true return true
} }
fun canAttack(): Boolean { fun canAttack(): Boolean {
if(currentMovement==0f) return false if (currentMovement == 0f) return false
if(attacksThisTurn>0 && !hasUnique("1 additional attack per turn")) return false if (attacksThisTurn > 0 && !hasUnique("1 additional attack per turn")) return false
if(attacksThisTurn>1) return false if (attacksThisTurn > 1) return false
return true return true
} }
@ -235,9 +233,9 @@ class MapUnit {
} }
fun getEmbarkedMovement(): Int { fun getEmbarkedMovement(): Int {
var movement=2 var movement = 2
movement += civInfo.tech.getTechUniques().count { it == "Increases embarked movement +1" } movement += civInfo.tech.getTechUniques().count { it == "Increases embarked movement +1" }
if (civInfo.hasUnique("+1 Movement for all embarked units")) movement +=1 if (civInfo.hasUnique("+1 Movement for all embarked units")) movement += 1
return movement return movement
} }
@ -267,30 +265,26 @@ class MapUnit {
fun getCostOfUpgrade(): Int { fun getCostOfUpgrade(): Int {
val unitToUpgradeTo = getUnitToUpgradeTo() val unitToUpgradeTo = getUnitToUpgradeTo()
var goldCostOfUpgrade = (unitToUpgradeTo.cost - baseUnit().cost) * 2 + 10 var goldCostOfUpgrade = (unitToUpgradeTo.cost - baseUnit().cost) * 2 + 10
for(unique in civInfo.getMatchingUniques("Gold cost of upgrading military units reduced by 33%")) for (unique in civInfo.getMatchingUniques("Gold cost of upgrading military units reduced by 33%"))
goldCostOfUpgrade = (goldCostOfUpgrade * 0.66f).toInt() goldCostOfUpgrade = (goldCostOfUpgrade * 0.66f).toInt()
if(goldCostOfUpgrade<0) return 0 // For instance, Landsknecht costs less than Spearman, so upgrading would cost negative gold if (goldCostOfUpgrade < 0) return 0 // For instance, Landsknecht costs less than Spearman, so upgrading would cost negative gold
return goldCostOfUpgrade return goldCostOfUpgrade
} }
fun canFortify(): Boolean { fun canFortify(): Boolean {
if(type.isWaterUnit()) return false if (type.isWaterUnit()) return false
if(type.isCivilian()) return false if (type.isCivilian()) return false
if(type.isAirUnit()) return false if (type.isAirUnit()) return false
if(isEmbarked()) return false if (isEmbarked()) return false
if(hasUnique("No defensive terrain bonus")) return false if (hasUnique("No defensive terrain bonus")) return false
if(isFortified()) return false if (isFortified()) return false
return true return true
} }
fun fortify() { fun fortify() { action = "Fortify 0" }
action = "Fortify 0"
}
fun fortifyUntilHealed() { fun fortifyUntilHealed() { action = "Fortify 0 until healed" }
action = "Fortify 0 until healed"
}
fun fortifyIfCan() { fun fortifyIfCan() {
if (canFortify()) { if (canFortify()) {
@ -323,9 +317,8 @@ class MapUnit {
if(currentMovement<0) currentMovement = 0f if(currentMovement<0) currentMovement = 0f
} }
fun doPreTurnAction() { fun doAction() {
if (action == null) return if (action == null) return
val currentTile = getTile()
if (currentMovement == 0f) return // We've already done stuff this turn, and can't do any more stuff if (currentMovement == 0f) return // We've already done stuff this turn, and can't do any more stuff
val enemyUnitsInWalkingDistance = movement.getDistanceToTiles().keys val enemyUnitsInWalkingDistance = movement.getDistanceToTiles().keys
@ -338,16 +331,17 @@ class MapUnit {
mapUnitAction?.doPreTurnAction() mapUnitAction?.doPreTurnAction()
if (action != null && action!!.startsWith("moveTo")) { val currentTile = getTile()
if (isMoving()) {
val destination = action!!.replace("moveTo ", "").split(",").dropLastWhile { it.isEmpty() }.toTypedArray() val destination = action!!.replace("moveTo ", "").split(",").dropLastWhile { it.isEmpty() }.toTypedArray()
val destinationVector = Vector2(Integer.parseInt(destination[0]).toFloat(), Integer.parseInt(destination[1]).toFloat()) val destinationVector = Vector2(destination[0].toFloat(), destination[1].toFloat())
val destinationTile = currentTile.tileMap[destinationVector] val destinationTile = currentTile.tileMap[destinationVector]
if (!movement.canReach(destinationTile)) return // That tile that we were moving towards is now unreachable if (!movement.canReach(destinationTile)) return // That tile that we were moving towards is now unreachable
val gotTo = movement.headTowards(destinationTile) val gotTo = movement.headTowards(destinationTile)
if (gotTo == currentTile) // We didn't move at all if (gotTo == currentTile) // We didn't move at all
return return
if (gotTo.position == destinationVector) action = null if (gotTo.position == destinationVector) action = null
if (currentMovement > 0) doPreTurnAction() if (currentMovement > 0) doAction()
return return
} }
@ -356,18 +350,6 @@ class MapUnit {
if (action == Constants.unitActionExplore) UnitAutomation.automatedExplore(this) if (action == Constants.unitActionExplore) UnitAutomation.automatedExplore(this)
} }
private fun doPostTurnAction() {
if (hasUnique(Constants.workerUnique) && getTile().improvementInProgress != null) workOnImprovement()
if(hasUnique("Can construct roads") && currentTile.improvementInProgress=="Road") workOnImprovement()
if(currentMovement == getMaxMovement().toFloat()
&& isFortified()){
val currentTurnsFortified = getFortificationTurns()
if(currentTurnsFortified<2)
action = action!!.replace(currentTurnsFortified.toString(),(currentTurnsFortified+1).toString(), true)
}
if (hasUnique("Heal adjacent units for an additional 15 HP per turn"))
currentTile.neighbors.flatMap{ it.getUnits() }.forEach{ it.healBy(15) }
}
private fun workOnImprovement() { private fun workOnImprovement() {
val tile = getTile() val tile = getTile()
@ -462,12 +444,22 @@ class MapUnit {
} }
fun endTurn() { fun endTurn() {
doPostTurnAction() doAction()
if (currentMovement == getMaxMovement().toFloat() // didn't move this turn
|| hasUnique("Unit will heal every turn, even if it performs an action")){ if (hasUnique(Constants.workerUnique) && getTile().improvementInProgress != null) workOnImprovement()
heal() if (hasUnique("Can construct roads") && currentTile.improvementInProgress == "Road") workOnImprovement()
if (currentMovement == getMaxMovement().toFloat() && isFortified()) {
val currentTurnsFortified = getFortificationTurns()
if (currentTurnsFortified < 2)
action = action!!.replace(currentTurnsFortified.toString(), (currentTurnsFortified + 1).toString(), true)
} }
if(action != null && health > 99) if (hasUnique("Heal adjacent units for an additional 15 HP per turn"))
currentTile.neighbors.flatMap { it.getUnits() }.forEach { it.healBy(15) }
if (currentMovement == getMaxMovement().toFloat() // didn't move this turn
|| hasUnique("Unit will heal every turn, even if it performs an action")) heal()
if (action != null && health > 99)
if (action!!.endsWith(" until healed")) { if (action!!.endsWith(" until healed")) {
action = null // wake up when healed action = null // wake up when healed
} }
@ -490,7 +482,6 @@ class MapUnit {
val tileOwner = getTile().getOwner() val tileOwner = getTile().getOwner()
if (tileOwner != null && !civInfo.canEnterTiles(tileOwner) && !tileOwner.isCityState()) // if an enemy city expanded onto this tile while I was in it if (tileOwner != null && !civInfo.canEnterTiles(tileOwner) && !tileOwner.isCityState()) // if an enemy city expanded onto this tile while I was in it
movement.teleportToClosestMoveableTile() movement.teleportToClosestMoveableTile()
doPreTurnAction()
} }
fun destroy(){ fun destroy(){

View File

@ -32,7 +32,7 @@ object UnitActions {
val unitTable = worldScreen.bottomUnitTable val unitTable = worldScreen.bottomUnitTable
val actionList = ArrayList<UnitAction>() val actionList = ArrayList<UnitAction>()
if (unit.action != null && unit.action!!.startsWith("moveTo")) { if (unit.isMoving()) {
actionList += UnitAction( actionList += UnitAction(
type = UnitActionType.StopMovement, type = UnitActionType.StopMovement,
action = { unit.action = null } action = { unit.action = null }