From 4c113a9abaf3d7d69c18a9eb6509b1329a44abd2 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Fri, 1 Dec 2023 11:32:04 +0200 Subject: [PATCH] RFC: Direction for converting unit actions to map (#10632) * Direction for converting unit actions, so that invokeUnitAction() doesn't try to generate *all* possible unit actions just to choose one * Mapped many unit actions --- .../worldscreen/unit/actions/UnitActions.kt | 26 +++++--- .../unit/actions/UnitActionsFromUniques.kt | 61 +++++++++---------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActions.kt b/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActions.kt index f2483f695d..24f8559e5a 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActions.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActions.kt @@ -23,29 +23,37 @@ object UnitActions { /** Returns whether the action was invoked */ fun invokeUnitAction(unit: MapUnit, unitActionType: UnitActionType): Boolean { - val unitAction = getNormalActions(unit).firstOrNull { it.type == unitActionType } + val unitAction = actionTypeToFunctions[unitActionType]?.invoke(unit, unit.getTile())?.firstOrNull() + ?: getNormalActions(unit).firstOrNull { it.type == unitActionType } ?: getAdditionalActions(unit).firstOrNull { it.type == unitActionType } val internalAction = unitAction?.action ?: return false internalAction.invoke() return true } + private val actionTypeToFunctions = linkedMapOf Iterable>( + // Determined by unit uniques + UnitActionType.Transform to UnitActionsFromUniques::getTransformActions, + UnitActionType.Paradrop to UnitActionsFromUniques::getParadropActions, + UnitActionType.AirSweep to UnitActionsFromUniques::getAirSweepActions, + UnitActionType.SetUp to UnitActionsFromUniques::getSetupActions, + UnitActionType.FoundCity to UnitActionsFromUniques::getFoundCityActions, + UnitActionType.ConstructImprovement to UnitActionsFromUniques::getBuildingImprovementsActions, + UnitActionType.Repair to UnitActionsFromUniques::getRepairActions + ) + private fun getNormalActions(unit: MapUnit): List { val tile = unit.getTile() val actionList = ArrayList() + for (getActionsFunction in actionTypeToFunctions.values) + actionList.addAll(getActionsFunction(unit, tile)) + // Determined by unit uniques - UnitActionsFromUniques.addTransformActions(unit, actionList) - UnitActionsFromUniques.addParadropAction(unit, actionList) - UnitActionsFromUniques.addAirSweepAction(unit, actionList) - UnitActionsFromUniques.addSetupAction(unit, actionList) - UnitActionsFromUniques.addFoundCityAction(unit, actionList, tile) - UnitActionsFromUniques.addBuildingImprovementsAction(unit, actionList, tile) - UnitActionsFromUniques.addRepairAction(unit, actionList) - UnitActionsFromUniques.addCreateWaterImprovements(unit, actionList) UnitActionsGreatPerson.addGreatPersonActions(unit, actionList, tile) UnitActionsReligion.addFoundReligionAction(unit, actionList) UnitActionsReligion.addEnhanceReligionAction(unit, actionList) + UnitActionsFromUniques.addCreateWaterImprovements(unit, actionList) actionList += UnitActionsFromUniques.getImprovementConstructionActions(unit, tile) UnitActionsReligion.addSpreadReligionActions(unit, actionList) UnitActionsReligion.addRemoveHeresyActions(unit, actionList) diff --git a/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActionsFromUniques.kt b/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActionsFromUniques.kt index 518a47b8d6..fab7e1c010 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActionsFromUniques.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActionsFromUniques.kt @@ -46,9 +46,10 @@ object UnitActionsFromUniques { } - fun addFoundCityAction(unit: MapUnit, actionList: ArrayList, tile: Tile) { - val getFoundCityAction = getFoundCityAction(unit, tile) - if (getFoundCityAction != null) actionList += getFoundCityAction + + fun getFoundCityActions(unit: MapUnit, tile: Tile): List { + val getFoundCityAction = getFoundCityAction(unit, tile) ?: return emptyList() + return listOf(getFoundCityAction) } /** Produce a [UnitAction] for founding a city. @@ -135,39 +136,41 @@ object UnitActionsFromUniques { return if(brokenPromises.isEmpty()) null else brokenPromises.joinToString(", ") } - fun addSetupAction(unit: MapUnit, actionList: ArrayList) { - if (!unit.hasUnique(UniqueType.MustSetUp) || unit.isEmbarked()) return + fun getSetupActions(unit: MapUnit, tile: Tile): List { + if (!unit.hasUnique(UniqueType.MustSetUp) || unit.isEmbarked()) return emptyList() val isSetUp = unit.isSetUpForSiege() - actionList += UnitAction(UnitActionType.SetUp, + return listOf(UnitAction(UnitActionType.SetUp, isCurrentAction = isSetUp, action = { unit.action = UnitActionType.SetUp.value unit.useMovementPoints(1f) }.takeIf { unit.currentMovement > 0 && !isSetUp }) + ) } - fun addParadropAction(unit: MapUnit, actionList: ArrayList) { + fun getParadropActions(unit: MapUnit, tile: Tile): List { val paradropUniques = unit.getMatchingUniques(UniqueType.MayParadrop) - if (!paradropUniques.any() || unit.isEmbarked()) return + if (!paradropUniques.any() || unit.isEmbarked()) return emptyList() unit.cache.paradropRange = paradropUniques.maxOfOrNull { it.params[0] }!!.toInt() - actionList += UnitAction(UnitActionType.Paradrop, + return listOf(UnitAction(UnitActionType.Paradrop, isCurrentAction = unit.isPreparingParadrop(), action = { if (unit.isPreparingParadrop()) unit.action = null else unit.action = UnitActionType.Paradrop.value }.takeIf { !unit.hasUnitMovedThisTurn() && - unit.currentTile.isFriendlyTerritory(unit.civ) && - !unit.isEmbarked() + tile.isFriendlyTerritory(unit.civ) && + !tile.isWater }) + ) } - fun addAirSweepAction(unit: MapUnit, actionList: ArrayList) { + fun getAirSweepActions(unit: MapUnit, tile: Tile): List { val airsweepUniques = unit.getMatchingUniques(UniqueType.CanAirsweep) - if (!airsweepUniques.any()) return - actionList += UnitAction(UnitActionType.AirSweep, + if (!airsweepUniques.any()) return emptyList() + return listOf(UnitAction(UnitActionType.AirSweep, isCurrentAction = unit.isPreparingAirSweep(), action = { if (unit.isPreparingAirSweep()) unit.action = null @@ -175,7 +178,7 @@ object UnitActionsFromUniques { }.takeIf { unit.canAttack() } - ) + )) } fun addTriggerUniqueActions(unit: MapUnit, actionList: ArrayList) { for (unique in unit.getUniques()) { @@ -271,16 +274,9 @@ object UnitActionsFromUniques { return finalActions } - fun addTransformActions( - unit: MapUnit, - actionList: ArrayList - ) { - val upgradeAction = getTransformActions(unit) - actionList += upgradeAction - } - private fun getTransformActions( - unit: MapUnit + fun getTransformActions( + unit: MapUnit, tile: Tile ): ArrayList { val unitTile = unit.getTile() val civInfo = unit.civ @@ -342,12 +338,11 @@ object UnitActionsFromUniques { return transformList } - fun addBuildingImprovementsAction( + fun getBuildingImprovementsActions( unit: MapUnit, - actionList: ArrayList, tile: Tile - ) { - if (!unit.cache.hasUniqueToBuildImprovements) return + ): List { + if (!unit.cache.hasUniqueToBuildImprovements) return emptyList() val couldConstruct = unit.currentMovement > 0 && !tile.isCityCenter() @@ -361,7 +356,7 @@ object UnitActionsFromUniques { && unit.canBuildImprovement(it) } - actionList += UnitAction(UnitActionType.ConstructImprovement, + return listOf(UnitAction(UnitActionType.ConstructImprovement, isCurrentAction = unit.currentTile.hasImprovementInProgress(), action = { GUI.pushScreen(ImprovementPickerScreen(tile, unit) { @@ -369,7 +364,7 @@ object UnitActionsFromUniques { GUI.getWorldScreen().switchToNextUnit() }) }.takeIf { couldConstruct } - ) + )) } private fun getRepairTurns(unit: MapUnit): Int { @@ -385,9 +380,9 @@ object UnitActionsFromUniques { return repairTurns } - fun addRepairAction(unit: MapUnit, actionList: ArrayList) { - val repairAction = getRepairAction(unit) - if (repairAction != null) actionList.add(repairAction) + fun getRepairActions(unit: MapUnit, tile: Tile): List { + val repairAction = getRepairAction(unit) ?: return emptyList() + return listOf(repairAction) } fun getRepairAction(unit: MapUnit) : UnitAction? { if (!unit.currentTile.ruleset.tileImprovements.containsKey(Constants.repair)) return null