mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-19 20:28:56 +07:00
UnitActionType now knows keys, sounds and most icons (#4607)
* Removed Char-only restriction in keyboard support for unit actions, remap a few keys, key tooltips for non-ascii keys * UnitActionType now knows keys, sounds and most icons * UnitActionType empower - fix Prophets spreading Pantheons
This commit is contained in:
@ -1,42 +1,144 @@
|
|||||||
package com.unciv.models
|
package com.unciv.models
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Input
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||||
|
import com.unciv.ui.utils.KeyCharAndCode
|
||||||
|
import com.unciv.ui.utils.ImageGetter
|
||||||
|
import com.unciv.Constants
|
||||||
|
import com.unciv.models.translations.equalsPlaceholderText
|
||||||
|
import com.unciv.models.translations.getPlaceholderParameters
|
||||||
|
|
||||||
|
|
||||||
|
/** Unit Actions - class - carries dynamic data and actual execution.
|
||||||
|
* Static properties are in [UnitActionType].
|
||||||
|
* Note this is for the buttons offering actions, not the ongoing action stored with a [MapUnit][com.unciv.logic.map.MapUnit]
|
||||||
|
*/
|
||||||
data class UnitAction(
|
data class UnitAction(
|
||||||
val type: UnitActionType,
|
val type: UnitActionType,
|
||||||
val title: String = type.value,
|
val title: String = type.value,
|
||||||
val isCurrentAction: Boolean = false,
|
val isCurrentAction: Boolean = false,
|
||||||
val uncivSound: UncivSound = UncivSound.Click,
|
val uncivSound: UncivSound = type.uncivSound,
|
||||||
val action: (() -> Unit)? = null
|
val action: (() -> Unit)? = null
|
||||||
)
|
) {
|
||||||
|
fun getIcon(): Actor {
|
||||||
|
if (type.imageGetter != null) return type.imageGetter.invoke()
|
||||||
|
return when {
|
||||||
|
type == UnitActionType.Upgrade
|
||||||
|
&& title.equalsPlaceholderText("Upgrade to [] ([] gold)") -> {
|
||||||
|
ImageGetter.getUnitIcon(title.getPlaceholderParameters()[0])
|
||||||
|
}
|
||||||
|
type == UnitActionType.Create
|
||||||
|
&& title.equalsPlaceholderText("Create []") -> {
|
||||||
|
ImageGetter.getImprovementIcon(title.getPlaceholderParameters()[0])
|
||||||
|
}
|
||||||
|
type == UnitActionType.SpreadReligion
|
||||||
|
&& title.equalsPlaceholderText("Spread []") -> {
|
||||||
|
val religionName = title.getPlaceholderParameters()[0]
|
||||||
|
ImageGetter.getReligionIcon(
|
||||||
|
if (ImageGetter.religionIconExists(religionName)) religionName else "Pantheon"
|
||||||
|
).apply { color = Color.BLACK }
|
||||||
|
}
|
||||||
|
type == UnitActionType.Fortify || type == UnitActionType.FortifyUntilHealed -> {
|
||||||
|
val match = fortificationRegex.matchEntire(title)
|
||||||
|
val percentFortified = match?.groups?.get(1)?.value?.toInt() ?: 0
|
||||||
|
ImageGetter.getImage("OtherIcons/Shield").apply {
|
||||||
|
color = Color.BLACK.cpy().lerp(Color.GREEN, percentFortified / 80f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> ImageGetter.getImage("OtherIcons/Star")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
companion object {
|
||||||
|
private val fortificationRegex = Regex(""".* (\d+)%""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum class UnitActionType(val value: String) {
|
/** Unit Actions - generic enum with static properties
|
||||||
SwapUnits("Swap units"),
|
*
|
||||||
Automate("Automate"),
|
* @param value _default_ label to display, can be overridden in UnitAction instantiation
|
||||||
StopAutomation("Stop automation"),
|
* @param imageGetter optional lambda to get an Icon - `null` if icon is dependent on outside factors and needs special handling
|
||||||
StopMovement("Stop movement"),
|
* @param key keyboard binding - can be a [KeyCharAndCode], a [Char], or omitted.
|
||||||
Sleep("Sleep"),
|
* @param uncivSound _default_ sound, can be overridden in UnitAction instantiation
|
||||||
SleepUntilHealed("Sleep until healed"),
|
*/
|
||||||
Fortify("Fortify"),
|
enum class UnitActionType(
|
||||||
FortifyUntilHealed("Fortify until healed"),
|
val value: String,
|
||||||
Explore("Explore"),
|
val imageGetter: (()-> Actor)?,
|
||||||
StopExploration("Stop exploration"),
|
val key: KeyCharAndCode,
|
||||||
Promote("Promote"),
|
val uncivSound: UncivSound = UncivSound.Click
|
||||||
Upgrade("Upgrade"),
|
) {
|
||||||
Pillage("Pillage"),
|
SwapUnits("Swap units",
|
||||||
Paradrop("Paradrop"),
|
{ ImageGetter.getImage("OtherIcons/Swap") }, 'y'),
|
||||||
SetUp("Set up"),
|
Automate("Automate",
|
||||||
FoundCity("Found city"),
|
{ ImageGetter.getUnitIcon("Great Engineer") }, 'm'),
|
||||||
ConstructImprovement("Construct improvement"),
|
StopAutomation("Stop automation",
|
||||||
|
{ ImageGetter.getImage("OtherIcons/Stop") }, 'm'),
|
||||||
|
StopMovement("Stop movement",
|
||||||
|
{ imageGetStopMove() }, '.'),
|
||||||
|
Sleep("Sleep",
|
||||||
|
{ ImageGetter.getImage("OtherIcons/Sleep") }, 'f'),
|
||||||
|
SleepUntilHealed("Sleep until healed",
|
||||||
|
{ ImageGetter.getImage("OtherIcons/Sleep") }, 'h'),
|
||||||
|
Fortify("Fortify",
|
||||||
|
null, 'f', UncivSound.Fortify),
|
||||||
|
FortifyUntilHealed("Fortify until healed",
|
||||||
|
null, 'h', UncivSound.Fortify),
|
||||||
|
Explore("Explore",
|
||||||
|
{ ImageGetter.getUnitIcon("Scout") }, 'x'),
|
||||||
|
StopExploration("Stop exploration",
|
||||||
|
{ ImageGetter.getImage("OtherIcons/Stop") }, 'x'),
|
||||||
|
Promote("Promote",
|
||||||
|
{ imageGetPromote() }, 'o', UncivSound.Promote),
|
||||||
|
Upgrade("Upgrade",
|
||||||
|
null, 'u', UncivSound.Upgrade),
|
||||||
|
Pillage("Pillage",
|
||||||
|
{ ImageGetter.getImage("OtherIcons/Pillage") }, 'p'),
|
||||||
|
Paradrop("Paradrop",
|
||||||
|
{ ImageGetter.getUnitIcon("Paratrooper") }, 'p'),
|
||||||
|
SetUp("Set up",
|
||||||
|
{ ImageGetter.getUnitIcon("Catapult") }, 't', UncivSound.Setup),
|
||||||
|
FoundCity("Found city",
|
||||||
|
{ ImageGetter.getUnitIcon(Constants.settler) }, 'c', UncivSound.Silent),
|
||||||
|
ConstructImprovement("Construct improvement",
|
||||||
|
{ ImageGetter.getUnitIcon(Constants.worker) }, 'i'),
|
||||||
// Deprecated since 3.15.4
|
// Deprecated since 3.15.4
|
||||||
ConstructRoad("Construct road"),
|
ConstructRoad("Construct road", {ImageGetter.getImprovementIcon("Road")}, 'r'),
|
||||||
//
|
//
|
||||||
Create("Create"),
|
Create("Create",
|
||||||
SpreadReligion("Spread Religion"),
|
null, 'i', UncivSound.Chimes),
|
||||||
HurryResearch("Hurry Research"),
|
SpreadReligion("Spread Religion",
|
||||||
StartGoldenAge("Start Golden Age"),
|
null, 'g', UncivSound.Choir),
|
||||||
HurryWonder("Hurry Wonder"),
|
HurryResearch("Hurry Research",
|
||||||
ConductTradeMission("Conduct Trade Mission"),
|
{ ImageGetter.getUnitIcon("Great Scientist") }, 'g', UncivSound.Chimes),
|
||||||
FoundReligion("Found a Religion"),
|
StartGoldenAge("Start Golden Age",
|
||||||
DisbandUnit("Disband unit"),
|
{ ImageGetter.getUnitIcon("Great Artist") }, 'g', UncivSound.Chimes),
|
||||||
GiftUnit("Gift unit"),
|
HurryWonder("Hurry Wonder",
|
||||||
ShowAdditionalActions("Show more"),
|
{ ImageGetter.getUnitIcon("Great Engineer") }, 'g', UncivSound.Chimes),
|
||||||
}
|
ConductTradeMission("Conduct Trade Mission",
|
||||||
|
{ ImageGetter.getUnitIcon("Great Merchant") }, 'g', UncivSound.Chimes),
|
||||||
|
FoundReligion("Found a Religion",
|
||||||
|
{ ImageGetter.getUnitIcon("Great Prophet") }, 'g', UncivSound.Choir),
|
||||||
|
DisbandUnit("Disband unit",
|
||||||
|
{ ImageGetter.getImage("OtherIcons/DisbandUnit") }, KeyCharAndCode.DEL),
|
||||||
|
GiftUnit("Gift unit",
|
||||||
|
{ ImageGetter.getImage("OtherIcons/Present") }, UncivSound.Silent),
|
||||||
|
ShowAdditionalActions("Show more",
|
||||||
|
{ imageGetShowMore() }, KeyCharAndCode(Input.Keys.PAGE_DOWN)),
|
||||||
|
HideAdditionalActions("Back",
|
||||||
|
{ imageGetHideMore() }, KeyCharAndCode(Input.Keys.PAGE_UP)),
|
||||||
|
;
|
||||||
|
|
||||||
|
// Allow shorter initializations
|
||||||
|
constructor(value: String, imageGetter: (() -> Actor)?, key: Char, uncivSound: UncivSound = UncivSound.Click)
|
||||||
|
: this(value, imageGetter, KeyCharAndCode(key), uncivSound)
|
||||||
|
constructor(value: String, imageGetter: (() -> Actor)?, uncivSound: UncivSound = UncivSound.Click)
|
||||||
|
: this(value, imageGetter, KeyCharAndCode.UNKNOWN, uncivSound)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// readability factories
|
||||||
|
private fun imageGetStopMove() = ImageGetter.getStatIcon("Movement").apply { color = Color.RED }
|
||||||
|
private fun imageGetPromote() = ImageGetter.getImage("OtherIcons/Star").apply { color = Color.GOLD }
|
||||||
|
private fun imageGetShowMore() = ImageGetter.getImage("OtherIcons/ArrowRight").apply { color = Color.BLACK }
|
||||||
|
private fun imageGetHideMore() = ImageGetter.getImage("OtherIcons/ArrowLeft").apply { color = Color.BLACK }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -291,6 +291,7 @@ object ImageGetter {
|
|||||||
return circle
|
return circle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun religionIconExists(iconName: String) = imageExists("ReligionIcons/$iconName")
|
||||||
fun getReligionIcon(iconName: String): Image {
|
fun getReligionIcon(iconName: String): Image {
|
||||||
return getImage("ReligionIcons/$iconName")
|
return getImage("ReligionIcons/$iconName")
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ object UnitActions {
|
|||||||
if (!unit.hasUnique("Founds a new city") || tile.isWater) return null
|
if (!unit.hasUnique("Founds a new city") || tile.isWater) return null
|
||||||
|
|
||||||
if (unit.currentMovement <= 0 || tile.getTilesInDistance(3).any { it.isCityCenter() })
|
if (unit.currentMovement <= 0 || tile.getTilesInDistance(3).any { it.isCityCenter() })
|
||||||
return UnitAction(UnitActionType.FoundCity, uncivSound = UncivSound.Silent, action = null)
|
return UnitAction(UnitActionType.FoundCity, action = null)
|
||||||
|
|
||||||
val foundAction = {
|
val foundAction = {
|
||||||
UncivGame.Current.settings.addCompletedTutorialTask("Found city")
|
UncivGame.Current.settings.addCompletedTutorialTask("Found city")
|
||||||
@ -168,14 +168,14 @@ object UnitActions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unit.civInfo.playerType == PlayerType.AI)
|
if (unit.civInfo.playerType == PlayerType.AI)
|
||||||
return UnitAction(UnitActionType.FoundCity, uncivSound = UncivSound.Silent, action = foundAction)
|
return UnitAction(UnitActionType.FoundCity, action = foundAction)
|
||||||
|
|
||||||
return UnitAction(
|
return UnitAction(
|
||||||
type = UnitActionType.FoundCity,
|
type = UnitActionType.FoundCity,
|
||||||
uncivSound = UncivSound.Chimes,
|
uncivSound = UncivSound.Chimes,
|
||||||
action = {
|
action = {
|
||||||
// check if we would be breaking a promise
|
// check if we would be breaking a promise
|
||||||
val leaders = TestPromiseNotToSettle(unit.civInfo, tile)
|
val leaders = testPromiseNotToSettle(unit.civInfo, tile)
|
||||||
if (leaders == null)
|
if (leaders == null)
|
||||||
foundAction()
|
foundAction()
|
||||||
else {
|
else {
|
||||||
@ -193,7 +193,7 @@ object UnitActions {
|
|||||||
* @param tile The tile where the new city would go
|
* @param tile The tile where the new city would go
|
||||||
* @return null if no promises broken, else a String listing the leader(s) we would p* off.
|
* @return null if no promises broken, else a String listing the leader(s) we would p* off.
|
||||||
*/
|
*/
|
||||||
private fun TestPromiseNotToSettle(civInfo: CivilizationInfo, tile: TileInfo): String? {
|
private fun testPromiseNotToSettle(civInfo: CivilizationInfo, tile: TileInfo): String? {
|
||||||
val brokenPromises = HashSet<String>()
|
val brokenPromises = HashSet<String>()
|
||||||
for (otherCiv in civInfo.getKnownCivs().filter { it.isMajorCiv() && !civInfo.isAtWarWith(it) }) {
|
for (otherCiv in civInfo.getKnownCivs().filter { it.isMajorCiv() && !civInfo.isAtWarWith(it) }) {
|
||||||
val diplomacyManager = otherCiv.getDiplomacyManager(civInfo)
|
val diplomacyManager = otherCiv.getDiplomacyManager(civInfo)
|
||||||
@ -211,7 +211,6 @@ object UnitActions {
|
|||||||
if (unit.isCivilian() || !unit.promotions.canBePromoted()) return
|
if (unit.isCivilian() || !unit.promotions.canBePromoted()) return
|
||||||
// promotion does not consume movement points, so we can do it always
|
// promotion does not consume movement points, so we can do it always
|
||||||
actionList += UnitAction(UnitActionType.Promote,
|
actionList += UnitAction(UnitActionType.Promote,
|
||||||
uncivSound = UncivSound.Promote,
|
|
||||||
action = {
|
action = {
|
||||||
UncivGame.Current.setScreen(PromotionPickerScreen(unit))
|
UncivGame.Current.setScreen(PromotionPickerScreen(unit))
|
||||||
})
|
})
|
||||||
@ -222,7 +221,6 @@ object UnitActions {
|
|||||||
val isSetUp = unit.action == "Set Up"
|
val isSetUp = unit.action == "Set Up"
|
||||||
actionList += UnitAction(UnitActionType.SetUp,
|
actionList += UnitAction(UnitActionType.SetUp,
|
||||||
isCurrentAction = isSetUp,
|
isCurrentAction = isSetUp,
|
||||||
uncivSound = UncivSound.Setup,
|
|
||||||
action = {
|
action = {
|
||||||
unit.action = Constants.unitActionSetUp
|
unit.action = Constants.unitActionSetUp
|
||||||
unit.useMovementPoints(1f)
|
unit.useMovementPoints(1f)
|
||||||
@ -251,7 +249,7 @@ object UnitActions {
|
|||||||
|
|
||||||
private fun addPillageAction(unit: MapUnit, actionList: ArrayList<UnitAction>, worldScreen: WorldScreen) {
|
private fun addPillageAction(unit: MapUnit, actionList: ArrayList<UnitAction>, worldScreen: WorldScreen) {
|
||||||
val pillageAction = getPillageAction(unit)
|
val pillageAction = getPillageAction(unit)
|
||||||
if (pillageAction == null) return
|
?: return
|
||||||
if (pillageAction.action == null)
|
if (pillageAction.action == null)
|
||||||
actionList += UnitAction(UnitActionType.Pillage, action = null)
|
actionList += UnitAction(UnitActionType.Pillage, action = null)
|
||||||
else actionList += UnitAction(type = UnitActionType.Pillage) {
|
else actionList += UnitAction(type = UnitActionType.Pillage) {
|
||||||
@ -268,7 +266,7 @@ object UnitActions {
|
|||||||
|
|
||||||
return UnitAction(UnitActionType.Pillage,
|
return UnitAction(UnitActionType.Pillage,
|
||||||
action = {
|
action = {
|
||||||
// http://well-of-souls.com/civ/civ5_improvements.html says that naval improvements are destroyed upon pilllage
|
// http://well-of-souls.com/civ/civ5_improvements.html says that naval improvements are destroyed upon pillage
|
||||||
// and I can't find any other sources so I'll go with that
|
// and I can't find any other sources so I'll go with that
|
||||||
if (tile.isLand) {
|
if (tile.isLand) {
|
||||||
tile.improvementInProgress = tile.improvement
|
tile.improvementInProgress = tile.improvement
|
||||||
@ -309,23 +307,22 @@ object UnitActions {
|
|||||||
|
|
||||||
return UnitAction(UnitActionType.Upgrade,
|
return UnitAction(UnitActionType.Upgrade,
|
||||||
title = "Upgrade to [${upgradedUnit.name}] ([$goldCostOfUpgrade] gold)",
|
title = "Upgrade to [${upgradedUnit.name}] ([$goldCostOfUpgrade] gold)",
|
||||||
uncivSound = UncivSound.Upgrade,
|
|
||||||
action = {
|
action = {
|
||||||
unit.civInfo.addGold(-goldCostOfUpgrade)
|
unit.civInfo.addGold(-goldCostOfUpgrade)
|
||||||
val unitTile = unit.getTile()
|
val unitTile = unit.getTile()
|
||||||
unit.destroy()
|
unit.destroy()
|
||||||
val newunit = unit.civInfo.placeUnitNearTile(unitTile.position, upgradedUnit.name)!!
|
val newUnit = unit.civInfo.placeUnitNearTile(unitTile.position, upgradedUnit.name)!!
|
||||||
newunit.health = unit.health
|
newUnit.health = unit.health
|
||||||
newunit.promotions = unit.promotions
|
newUnit.promotions = unit.promotions
|
||||||
newunit.instanceName = unit.instanceName
|
newUnit.instanceName = unit.instanceName
|
||||||
|
|
||||||
for (promotion in newunit.baseUnit.promotions)
|
for (promotion in newUnit.baseUnit.promotions)
|
||||||
if (promotion !in newunit.promotions.promotions)
|
if (promotion !in newUnit.promotions.promotions)
|
||||||
newunit.promotions.addPromotion(promotion, true)
|
newUnit.promotions.addPromotion(promotion, true)
|
||||||
|
|
||||||
newunit.updateUniques()
|
newUnit.updateUniques()
|
||||||
newunit.updateVisibleTiles()
|
newUnit.updateVisibleTiles()
|
||||||
newunit.currentMovement = 0f
|
newUnit.currentMovement = 0f
|
||||||
}.takeIf {
|
}.takeIf {
|
||||||
unit.civInfo.gold >= goldCostOfUpgrade && !unit.isEmbarked()
|
unit.civInfo.gold >= goldCostOfUpgrade && !unit.isEmbarked()
|
||||||
&& unit.currentMovement == unit.getMaxMovement().toFloat()
|
&& unit.currentMovement == unit.getMaxMovement().toFloat()
|
||||||
@ -367,7 +364,6 @@ object UnitActions {
|
|||||||
if (unit.currentMovement > 0) for (unique in unit.getUniques()) when (unique.placeholderText) {
|
if (unit.currentMovement > 0) for (unique in unit.getUniques()) when (unique.placeholderText) {
|
||||||
"Can hurry technology research" -> {
|
"Can hurry technology research" -> {
|
||||||
actionList += UnitAction(UnitActionType.HurryResearch,
|
actionList += UnitAction(UnitActionType.HurryResearch,
|
||||||
uncivSound = UncivSound.Chimes,
|
|
||||||
action = {
|
action = {
|
||||||
unit.civInfo.tech.addScience(unit.civInfo.tech.getScienceFromGreatScientist())
|
unit.civInfo.tech.addScience(unit.civInfo.tech.getScienceFromGreatScientist())
|
||||||
addGoldPerGreatPersonUsage(unit.civInfo)
|
addGoldPerGreatPersonUsage(unit.civInfo)
|
||||||
@ -378,7 +374,6 @@ object UnitActions {
|
|||||||
"Can start an []-turn golden age" -> {
|
"Can start an []-turn golden age" -> {
|
||||||
val turnsToGoldenAge = unique.params[0].toInt()
|
val turnsToGoldenAge = unique.params[0].toInt()
|
||||||
actionList += UnitAction(UnitActionType.StartGoldenAge,
|
actionList += UnitAction(UnitActionType.StartGoldenAge,
|
||||||
uncivSound = UncivSound.Chimes,
|
|
||||||
action = {
|
action = {
|
||||||
unit.civInfo.goldenAges.enterGoldenAge(turnsToGoldenAge)
|
unit.civInfo.goldenAges.enterGoldenAge(turnsToGoldenAge)
|
||||||
addGoldPerGreatPersonUsage(unit.civInfo)
|
addGoldPerGreatPersonUsage(unit.civInfo)
|
||||||
@ -394,7 +389,6 @@ object UnitActions {
|
|||||||
else currentConstruction.isAnyWonder()
|
else currentConstruction.isAnyWonder()
|
||||||
}
|
}
|
||||||
actionList += UnitAction(UnitActionType.HurryWonder,
|
actionList += UnitAction(UnitActionType.HurryWonder,
|
||||||
uncivSound = UncivSound.Chimes,
|
|
||||||
action = {
|
action = {
|
||||||
tile.getCity()!!.cityConstructions.apply {
|
tile.getCity()!!.cityConstructions.apply {
|
||||||
addProductionPoints(300 + 30 * tile.getCity()!!.population.population) //http://civilization.wikia.com/wiki/Great_engineer_(Civ5)
|
addProductionPoints(300 + 30 * tile.getCity()!!.population.population) //http://civilization.wikia.com/wiki/Great_engineer_(Civ5)
|
||||||
@ -410,7 +404,6 @@ object UnitActions {
|
|||||||
&& tile.owningCity?.civInfo?.isAtWarWith(unit.civInfo) == false
|
&& tile.owningCity?.civInfo?.isAtWarWith(unit.civInfo) == false
|
||||||
val influenceEarned = unique.params[0].toInt()
|
val influenceEarned = unique.params[0].toInt()
|
||||||
actionList += UnitAction(UnitActionType.ConductTradeMission,
|
actionList += UnitAction(UnitActionType.ConductTradeMission,
|
||||||
uncivSound = UncivSound.Chimes,
|
|
||||||
action = {
|
action = {
|
||||||
// http://civilization.wikia.com/wiki/Great_Merchant_(Civ5)
|
// http://civilization.wikia.com/wiki/Great_Merchant_(Civ5)
|
||||||
var goldEarned = ((350 + 50 * unit.civInfo.getEraNumber()) * unit.civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt()
|
var goldEarned = ((350 + 50 * unit.civInfo.getEraNumber()) * unit.civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt()
|
||||||
@ -432,7 +425,6 @@ object UnitActions {
|
|||||||
if (!unit.hasUnique("May found a religion")) return // should later also include enhance religion
|
if (!unit.hasUnique("May found a religion")) return // should later also include enhance religion
|
||||||
if (!unit.civInfo.religionManager.mayUseGreatProphetAtAll(unit)) return
|
if (!unit.civInfo.religionManager.mayUseGreatProphetAtAll(unit)) return
|
||||||
actionList += UnitAction(UnitActionType.FoundReligion,
|
actionList += UnitAction(UnitActionType.FoundReligion,
|
||||||
uncivSound = UncivSound.Choir,
|
|
||||||
action = {
|
action = {
|
||||||
addGoldPerGreatPersonUsage(unit.civInfo)
|
addGoldPerGreatPersonUsage(unit.civInfo)
|
||||||
unit.civInfo.religionManager.useGreatProphet(unit)
|
unit.civInfo.religionManager.useGreatProphet(unit)
|
||||||
@ -450,7 +442,6 @@ object UnitActions {
|
|||||||
val city = tile.getCity()
|
val city = tile.getCity()
|
||||||
actionList += UnitAction(UnitActionType.SpreadReligion,
|
actionList += UnitAction(UnitActionType.SpreadReligion,
|
||||||
title = "Spread [${unit.religion!!}]",
|
title = "Spread [${unit.religion!!}]",
|
||||||
uncivSound = UncivSound.Choir,
|
|
||||||
action = {
|
action = {
|
||||||
unit.abilityUsedCount["Religion Spread"] = unit.abilityUsedCount["Religion Spread"]!! + 1
|
unit.abilityUsedCount["Religion Spread"] = unit.abilityUsedCount["Religion Spread"]!! + 1
|
||||||
city!!.religion[unit.religion!!] = 100
|
city!!.religion[unit.religion!!] = 100
|
||||||
@ -471,10 +462,9 @@ object UnitActions {
|
|||||||
for (unique in uniquesToCheck) {
|
for (unique in uniquesToCheck) {
|
||||||
val improvementName = unique.params[0]
|
val improvementName = unique.params[0]
|
||||||
val improvement = tile.ruleset.tileImprovements[improvementName]
|
val improvement = tile.ruleset.tileImprovements[improvementName]
|
||||||
if (improvement == null) continue
|
?: continue
|
||||||
finalActions += UnitAction(UnitActionType.Create,
|
finalActions += UnitAction(UnitActionType.Create,
|
||||||
title = "Create [$improvementName]",
|
title = "Create [$improvementName]",
|
||||||
uncivSound = UncivSound.Chimes,
|
|
||||||
action = {
|
action = {
|
||||||
val unitTile = unit.getTile()
|
val unitTile = unit.getTile()
|
||||||
for (terrainFeature in tile.terrainFeatures.filter { unitTile.ruleset.tileImprovements.containsKey("Remove $it") })
|
for (terrainFeature in tile.terrainFeatures.filter { unitTile.ruleset.tileImprovements.containsKey("Remove $it") })
|
||||||
@ -575,14 +565,12 @@ object UnitActions {
|
|||||||
|
|
||||||
if (isDamaged && !showingAdditionalActions)
|
if (isDamaged && !showingAdditionalActions)
|
||||||
actionList += UnitAction(UnitActionType.FortifyUntilHealed,
|
actionList += UnitAction(UnitActionType.FortifyUntilHealed,
|
||||||
title = UnitActionType.FortifyUntilHealed.value,
|
|
||||||
action = {
|
action = {
|
||||||
unit.fortifyUntilHealed()
|
unit.fortifyUntilHealed()
|
||||||
}.takeIf { !unit.isFortifyingUntilHealed() }
|
}.takeIf { !unit.isFortifyingUntilHealed() }
|
||||||
)
|
)
|
||||||
else if (isDamaged || !showingAdditionalActions)
|
else if (isDamaged || !showingAdditionalActions)
|
||||||
actionList += UnitAction(UnitActionType.Fortify,
|
actionList += UnitAction(UnitActionType.Fortify,
|
||||||
uncivSound = UncivSound.Fortify,
|
|
||||||
action = {
|
action = {
|
||||||
unit.fortify()
|
unit.fortify()
|
||||||
}.takeIf { !isFortified }
|
}.takeIf { !isFortified }
|
||||||
@ -630,7 +618,7 @@ object UnitActions {
|
|||||||
// We need to be in another civs territory.
|
// We need to be in another civs territory.
|
||||||
if (recipient == null || recipient.isCurrentPlayer()) return null
|
if (recipient == null || recipient.isCurrentPlayer()) return null
|
||||||
|
|
||||||
// City States only take miliary units (and GPs for certain civs)
|
// City States only take military units (and GPs for certain civs)
|
||||||
if (recipient.isCityState()) {
|
if (recipient.isCityState()) {
|
||||||
if (unit.isGreatPerson()) {
|
if (unit.isGreatPerson()) {
|
||||||
// Do we have a unique ability to gift GPs?
|
// Do we have a unique ability to gift GPs?
|
||||||
@ -643,7 +631,7 @@ object UnitActions {
|
|||||||
else if (!tile.isFriendlyTerritory(unit.civInfo)) return null
|
else if (!tile.isFriendlyTerritory(unit.civInfo)) return null
|
||||||
|
|
||||||
if (unit.currentMovement <= 0)
|
if (unit.currentMovement <= 0)
|
||||||
return UnitAction(UnitActionType.GiftUnit, uncivSound = UncivSound.Silent, action = null)
|
return UnitAction(UnitActionType.GiftUnit, action = null)
|
||||||
|
|
||||||
val giftAction = {
|
val giftAction = {
|
||||||
if (recipient.isCityState()) {
|
if (recipient.isCityState()) {
|
||||||
@ -667,12 +655,12 @@ object UnitActions {
|
|||||||
UncivGame.Current.worldScreen.shouldUpdate = true
|
UncivGame.Current.worldScreen.shouldUpdate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return UnitAction(UnitActionType.GiftUnit, uncivSound = UncivSound.Silent, action = giftAction)
|
return UnitAction(UnitActionType.GiftUnit, action = giftAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addToggleActionsAction(unit: MapUnit, actionList: ArrayList<UnitAction>, unitTable: UnitTable) {
|
private fun addToggleActionsAction(unit: MapUnit, actionList: ArrayList<UnitAction>, unitTable: UnitTable) {
|
||||||
actionList += UnitAction(UnitActionType.ShowAdditionalActions,
|
actionList += UnitAction(
|
||||||
title = if (unit.showAdditionalActions) "Back" else "Show more",
|
type = if (unit.showAdditionalActions) UnitActionType.HideAdditionalActions else UnitActionType.ShowAdditionalActions,
|
||||||
action = {
|
action = {
|
||||||
unit.showAdditionalActions = !unit.showAdditionalActions
|
unit.showAdditionalActions = !unit.showAdditionalActions
|
||||||
unitTable.update()
|
unitTable.update()
|
||||||
|
@ -1,87 +1,19 @@
|
|||||||
package com.unciv.ui.worldscreen.unit
|
package com.unciv.ui.worldscreen.unit
|
||||||
|
|
||||||
import com.badlogic.gdx.Input
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Button
|
import com.badlogic.gdx.scenes.scene2d.ui.Button
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
import com.unciv.Constants
|
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.map.MapUnit
|
import com.unciv.logic.map.MapUnit
|
||||||
import com.unciv.logic.map.RoadStatus
|
|
||||||
import com.unciv.models.UnitAction
|
import com.unciv.models.UnitAction
|
||||||
import com.unciv.models.translations.equalsPlaceholderText
|
|
||||||
import com.unciv.models.translations.getPlaceholderParameters
|
|
||||||
import com.unciv.ui.utils.*
|
import com.unciv.ui.utils.*
|
||||||
import com.unciv.ui.utils.KeyPressDispatcher.Companion.keyboardAvailable
|
import com.unciv.ui.utils.KeyPressDispatcher.Companion.keyboardAvailable
|
||||||
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
|
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
|
||||||
import com.unciv.ui.worldscreen.WorldScreen
|
import com.unciv.ui.worldscreen.WorldScreen
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
private data class UnitIconAndKey(val icon: Actor, var key: KeyCharAndCode = KeyCharAndCode.UNKNOWN) {
|
|
||||||
constructor(icon: Actor, key: Char) : this(icon, KeyCharAndCode(key))
|
|
||||||
}
|
|
||||||
|
|
||||||
class UnitActionsTable(val worldScreen: WorldScreen) : Table() {
|
class UnitActionsTable(val worldScreen: WorldScreen) : Table() {
|
||||||
|
|
||||||
|
|
||||||
private fun getIconAndKeyForUnitAction(unitAction: String): UnitIconAndKey {
|
|
||||||
when {
|
|
||||||
unitAction.equalsPlaceholderText("Upgrade to [] ([] gold)") -> {
|
|
||||||
// Regexplaination: start with a [, take as many non-] chars as you can, until you reach a ].
|
|
||||||
// What you find between the first [ and the first ] that comes after it, will be group no. 0
|
|
||||||
val unitToUpgradeTo = unitAction.getPlaceholderParameters()[0]
|
|
||||||
return UnitIconAndKey(ImageGetter.getUnitIcon(unitToUpgradeTo), 'u')
|
|
||||||
}
|
|
||||||
unitAction.equalsPlaceholderText("Create []") -> {
|
|
||||||
// Regexplaination: start with a [, take as many non-] chars as you can, until you reach a ].
|
|
||||||
// What you find between the first [ and the first ] that comes after it, will be group no. 0
|
|
||||||
val improvementName = unitAction.getPlaceholderParameters()[0]
|
|
||||||
return UnitIconAndKey(ImageGetter.getImprovementIcon(improvementName), 'i')
|
|
||||||
}
|
|
||||||
unitAction.equalsPlaceholderText("Spread []") -> {
|
|
||||||
// This should later include icons for the different religions. For now, just use the great prophet icon
|
|
||||||
return UnitIconAndKey(ImageGetter.getUnitIcon("Great Prophet"), 'g')
|
|
||||||
}
|
|
||||||
else -> when (unitAction) {
|
|
||||||
"Sleep" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Sleep"), 'f')
|
|
||||||
"Sleep until healed" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Sleep"), 'h')
|
|
||||||
"Fortify" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Shield").apply { color = Color.BLACK }, 'f')
|
|
||||||
"Fortify until healed" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Shield").apply { color = Color.BLACK }, 'h')
|
|
||||||
// Move unit is not actually used anywhere
|
|
||||||
"Move unit" -> return UnitIconAndKey(ImageGetter.getStatIcon("Movement"))
|
|
||||||
"Stop movement" -> return UnitIconAndKey(ImageGetter.getStatIcon("Movement").apply { color = Color.RED }, KeyCharAndCode(Input.Keys.END))
|
|
||||||
"Swap units" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Swap"), 'y')
|
|
||||||
"Promote" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Star").apply { color = Color.GOLD }, 'o')
|
|
||||||
"Construct improvement" -> return UnitIconAndKey(ImageGetter.getUnitIcon(Constants.worker), 'i')
|
|
||||||
"Automate" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Great Engineer"), 'm')
|
|
||||||
"Stop automation" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Stop"), KeyCharAndCode(Input.Keys.END))
|
|
||||||
"Found city" -> return UnitIconAndKey(ImageGetter.getUnitIcon(Constants.settler), 'c')
|
|
||||||
"Hurry Research" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Great Scientist"), 'g')
|
|
||||||
"Start Golden Age" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Great Artist"), 'g')
|
|
||||||
"Hurry Wonder" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Great Engineer"), 'g')
|
|
||||||
"Conduct Trade Mission" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Great Merchant"), 'g')
|
|
||||||
// Deprecated since 3.15.4
|
|
||||||
"Construct road" -> return UnitIconAndKey(ImageGetter.getImprovementIcon(RoadStatus.Road.name), 'r')
|
|
||||||
//
|
|
||||||
"Paradrop" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Paratrooper"), 'p')
|
|
||||||
"Set up" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Catapult"), 't')
|
|
||||||
"Explore" -> return UnitIconAndKey(ImageGetter.getUnitIcon("Scout"), 'x')
|
|
||||||
"Stop exploration" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Stop"), 'x')
|
|
||||||
"Pillage" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Pillage"), 'p')
|
|
||||||
"Disband unit" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/DisbandUnit"), KeyCharAndCode.DEL)
|
|
||||||
"Gift unit" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Present"))
|
|
||||||
"Show more" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/ArrowRight"), KeyCharAndCode(Input.Keys.PAGE_DOWN))
|
|
||||||
"Back" -> return UnitIconAndKey(ImageGetter.getImage("OtherIcons/ArrowLeft"), KeyCharAndCode(Input.Keys.PAGE_UP))
|
|
||||||
else -> {
|
|
||||||
// If the unit has been fortifying for some turns
|
|
||||||
if (unitAction.startsWith("Fortification")) return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Shield"))
|
|
||||||
return UnitIconAndKey(ImageGetter.getImage("OtherIcons/Star"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun update(unit: MapUnit?) {
|
fun update(unit: MapUnit?) {
|
||||||
clear()
|
clear()
|
||||||
if (unit == null) return
|
if (unit == null) return
|
||||||
@ -93,16 +25,15 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table() {
|
|||||||
|
|
||||||
|
|
||||||
private fun getUnitActionButton(unitAction: UnitAction): Button {
|
private fun getUnitActionButton(unitAction: UnitAction): Button {
|
||||||
val iconAndKey = getIconAndKeyForUnitAction(unitAction.title)
|
val icon = unitAction.getIcon()
|
||||||
|
|
||||||
// If peripheral keyboard not detected, hotkeys will not be displayed
|
// If peripheral keyboard not detected, hotkeys will not be displayed
|
||||||
if (!keyboardAvailable) { iconAndKey.key = KeyCharAndCode.UNKNOWN }
|
val key = if (keyboardAvailable) unitAction.type.key else KeyCharAndCode.UNKNOWN
|
||||||
|
|
||||||
val actionButton = Button(CameraStageBaseScreen.skin)
|
val actionButton = Button(CameraStageBaseScreen.skin)
|
||||||
actionButton.add(iconAndKey.icon).size(20f).pad(5f)
|
actionButton.add(icon).size(20f).pad(5f)
|
||||||
val fontColor = if (unitAction.isCurrentAction) Color.YELLOW else Color.WHITE
|
val fontColor = if (unitAction.isCurrentAction) Color.YELLOW else Color.WHITE
|
||||||
actionButton.add(unitAction.title.toLabel(fontColor)).pad(5f)
|
actionButton.add(unitAction.title.toLabel(fontColor)).pad(5f)
|
||||||
actionButton.addTooltip(iconAndKey.key)
|
actionButton.addTooltip(key)
|
||||||
actionButton.pack()
|
actionButton.pack()
|
||||||
val action = {
|
val action = {
|
||||||
unitAction.action?.invoke()
|
unitAction.action?.invoke()
|
||||||
@ -111,8 +42,8 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table() {
|
|||||||
if (unitAction.action == null) actionButton.disable()
|
if (unitAction.action == null) actionButton.disable()
|
||||||
else {
|
else {
|
||||||
actionButton.onClick(unitAction.uncivSound, action)
|
actionButton.onClick(unitAction.uncivSound, action)
|
||||||
if (iconAndKey.key != KeyCharAndCode.UNKNOWN)
|
if (key != KeyCharAndCode.UNKNOWN)
|
||||||
worldScreen.keyPressDispatcher[iconAndKey.key] = {
|
worldScreen.keyPressDispatcher[key] = {
|
||||||
thread(name = "Sound") { Sounds.play(unitAction.uncivSound) }
|
thread(name = "Sound") { Sounds.play(unitAction.uncivSound) }
|
||||||
action()
|
action()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user