mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-19 20:28:56 +07:00
"Sleep until healed" functionality (#1821)
* "Sleep until healed" functionality * Unit test for actions translations is added * "Fortify until healed" functionality * Refactoring
This commit is contained in:
@ -1380,10 +1380,12 @@ Stop automation =
|
|||||||
Construct road =
|
Construct road =
|
||||||
# Requires translation!
|
# Requires translation!
|
||||||
Fortify =
|
Fortify =
|
||||||
|
Fortify until healed = Fortify until healed
|
||||||
# Requires translation!
|
# Requires translation!
|
||||||
Fortification =
|
Fortification =
|
||||||
# Requires translation!
|
# Requires translation!
|
||||||
Sleep =
|
Sleep =
|
||||||
|
Sleep until healed = Sleep until healed
|
||||||
# Requires translation!
|
# Requires translation!
|
||||||
Moving =
|
Moving =
|
||||||
# Requires translation!
|
# Requires translation!
|
||||||
|
@ -760,8 +760,10 @@ Automate = Автоматизировать
|
|||||||
Stop automation = Остановить автоматизацию
|
Stop automation = Остановить автоматизацию
|
||||||
Construct road = Построить дорогу
|
Construct road = Построить дорогу
|
||||||
Fortify = Укрепить
|
Fortify = Укрепить
|
||||||
|
Fortify until healed = Укрепить до выздоровления
|
||||||
Fortification = к защите
|
Fortification = к защите
|
||||||
Sleep = Спать
|
Sleep = Спать
|
||||||
|
Sleep until healed = Спать до выздоровления
|
||||||
Moving = В движении
|
Moving = В движении
|
||||||
Set up = Подготовиться
|
Set up = Подготовиться
|
||||||
Upgrade to [unitType] ([goldCost] gold) = Улучшить до [unitType] ([goldCost] золота)
|
Upgrade to [unitType] ([goldCost] gold) = Улучшить до [unitType] ([goldCost] золота)
|
||||||
|
@ -762,8 +762,10 @@ Automate = Автоматизувати
|
|||||||
Stop automation = Зупинити автоматизацію
|
Stop automation = Зупинити автоматизацію
|
||||||
Construct road = Будувати дорогу
|
Construct road = Будувати дорогу
|
||||||
Fortify = Укріпити
|
Fortify = Укріпити
|
||||||
|
Fortify until healed = Укріпити до одужання
|
||||||
Fortification = Фортифікація
|
Fortification = Фортифікація
|
||||||
Sleep = Спати
|
Sleep = Спати
|
||||||
|
Sleep until healed = Спати до одужання
|
||||||
Moving = У русі
|
Moving = У русі
|
||||||
Set up = Підготуватися
|
Set up = Підготуватися
|
||||||
Upgrade to [unitType] ([goldCost] gold) = Удосконалити до [unitType] ([goldCost] золота)
|
Upgrade to [unitType] ([goldCost] gold) = Удосконалити до [unitType] ([goldCost] золота)
|
||||||
|
@ -760,8 +760,10 @@ Automate =
|
|||||||
Stop automation =
|
Stop automation =
|
||||||
Construct road =
|
Construct road =
|
||||||
Fortify =
|
Fortify =
|
||||||
|
Fortify until healed =
|
||||||
Fortification =
|
Fortification =
|
||||||
Sleep =
|
Sleep =
|
||||||
|
Sleep until healed =
|
||||||
Moving =
|
Moving =
|
||||||
Set up =
|
Set up =
|
||||||
Upgrade to [unitType] ([goldCost] gold) =
|
Upgrade to [unitType] ([goldCost] gold) =
|
||||||
|
@ -41,6 +41,7 @@ class Constants{
|
|||||||
|
|
||||||
val unitActionSetUp = "Set Up"
|
val unitActionSetUp = "Set Up"
|
||||||
val unitActionSleep = "Sleep"
|
val unitActionSleep = "Sleep"
|
||||||
|
val unitActionSleepUntilHealed = "Sleep until healed"
|
||||||
val unitActionAutomation = "Automate"
|
val unitActionAutomation = "Automate"
|
||||||
val unitActionExplore = "Explore"
|
val unitActionExplore = "Explore"
|
||||||
val futureTech = "Future Tech"
|
val futureTech = "Future Tech"
|
||||||
|
@ -201,7 +201,7 @@ object Battle {
|
|||||||
unit.useMovementPoints(1f)
|
unit.useMovementPoints(1f)
|
||||||
} else unit.currentMovement = 0f
|
} else unit.currentMovement = 0f
|
||||||
unit.attacksThisTurn += 1
|
unit.attacksThisTurn += 1
|
||||||
if (unit.isFortified() || unit.action == Constants.unitActionSleep)
|
if (unit.isFortified() || unit.isSleeping())
|
||||||
attacker.unit.action = null // but not, for instance, if it's Set Up - then it should definitely keep the action!
|
attacker.unit.action = null // but not, for instance, if it's Set Up - then it should definitely keep the action!
|
||||||
} else if (attacker is CityCombatant) {
|
} else if (attacker is CityCombatant) {
|
||||||
attacker.city.attackedThisTurn = true
|
attacker.city.attackedThisTurn = true
|
||||||
|
@ -166,6 +166,10 @@ class MapUnit {
|
|||||||
return action?.startsWith("Fortify") == true
|
return action?.startsWith("Fortify") == true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isSleeping(): Boolean {
|
||||||
|
return action?.startsWith("Sleep") == 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()
|
||||||
@ -181,7 +185,7 @@ class MapUnit {
|
|||||||
if (name == Constants.worker && getTile().improvementInProgress != null) return false
|
if (name == Constants.worker && 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 || action==Constants.unitActionSleep
|
if (action==Constants.unitActionExplore || isSleeping()
|
||||||
|| action == Constants.unitActionAutomation) return false
|
|| action == Constants.unitActionAutomation) return false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -268,13 +272,17 @@ class MapUnit {
|
|||||||
action = "Fortify 0"
|
action = "Fortify 0"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun fortifyUntilHealed() {
|
||||||
|
action = "Fortify 0 until healed"
|
||||||
|
}
|
||||||
|
|
||||||
fun fortifyIfCan() {
|
fun fortifyIfCan() {
|
||||||
if (canFortify()) {
|
if (canFortify()) {
|
||||||
fortify()
|
fortify()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun adjacentHealingBonus():Int{
|
private fun adjacentHealingBonus():Int{
|
||||||
var healingBonus = 0
|
var healingBonus = 0
|
||||||
if(hasUnique("This unit and all others in adjacent tiles heal 5 additional HP per turn")) healingBonus +=5
|
if(hasUnique("This unit and all others in adjacent tiles heal 5 additional HP per turn")) healingBonus +=5
|
||||||
if(hasUnique("This unit and all others in adjacent tiles heal 5 additional HP. This unit heals 5 additional HP outside of friendly territory.")) healingBonus +=5
|
if(hasUnique("This unit and all others in adjacent tiles heal 5 additional HP. This unit heals 5 additional HP outside of friendly territory.")) healingBonus +=5
|
||||||
@ -337,7 +345,8 @@ class MapUnit {
|
|||||||
if(currentMovement == getMaxMovement().toFloat()
|
if(currentMovement == getMaxMovement().toFloat()
|
||||||
&& isFortified()){
|
&& isFortified()){
|
||||||
val currentTurnsFortified = getFortificationTurns()
|
val currentTurnsFortified = getFortificationTurns()
|
||||||
if(currentTurnsFortified<2) action = "Fortify ${currentTurnsFortified+1}"
|
if(currentTurnsFortified<2)
|
||||||
|
action = action!!.replace(currentTurnsFortified.toString(),(currentTurnsFortified+1).toString(), true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,6 +427,10 @@ class MapUnit {
|
|||||||
|| getUniques().contains("Unit will heal every turn, even if it performs an action")){
|
|| getUniques().contains("Unit will heal every turn, even if it performs an action")){
|
||||||
heal()
|
heal()
|
||||||
}
|
}
|
||||||
|
if(action != null && health > 99)
|
||||||
|
if (action!!.endsWith(" until healed")) {
|
||||||
|
action = null // wake up when healed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startTurn(){
|
fun startTurn(){
|
||||||
@ -426,7 +439,7 @@ class MapUnit {
|
|||||||
due = true
|
due = true
|
||||||
|
|
||||||
// Wake sleeping units if there's an enemy nearby
|
// Wake sleeping units if there's an enemy nearby
|
||||||
if(action==Constants.unitActionSleep && currentTile.getTilesInDistance(2).any {
|
if(isSleeping() && currentTile.getTilesInDistance(2).any {
|
||||||
it.militaryUnit!=null && it.militaryUnit!!.civInfo.isAtWarWith(civInfo)
|
it.militaryUnit!=null && it.militaryUnit!!.civInfo.isAtWarWith(civInfo)
|
||||||
})
|
})
|
||||||
action=null
|
action=null
|
||||||
|
@ -235,7 +235,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
|||||||
|
|
||||||
unit.currentMovement -= distanceToTiles[destination]!!.totalDistance
|
unit.currentMovement -= distanceToTiles[destination]!!.totalDistance
|
||||||
if (unit.currentMovement < 0.1) unit.currentMovement = 0f // silly floats which are "almost zero"
|
if (unit.currentMovement < 0.1) unit.currentMovement = 0f // silly floats which are "almost zero"
|
||||||
if(unit.isFortified() || unit.action==Constants.unitActionSetUp || unit.action==Constants.unitActionSleep)
|
if(unit.isFortified() || unit.action==Constants.unitActionSetUp || unit.isSleeping())
|
||||||
unit.action=null // unfortify/setup after moving
|
unit.action=null // unfortify/setup after moving
|
||||||
|
|
||||||
// If this unit is a carrier, keep record of its air payload whereabouts.
|
// If this unit is a carrier, keep record of its air payload whereabouts.
|
||||||
|
@ -15,7 +15,9 @@ enum class UnitActionType(val value: String) {
|
|||||||
StopAutomation("Stop automation"),
|
StopAutomation("Stop automation"),
|
||||||
StopExploration("Stop exploration"),
|
StopExploration("Stop exploration"),
|
||||||
Sleep("Sleep"),
|
Sleep("Sleep"),
|
||||||
|
SleepUntilHealed("Sleep until healed"),
|
||||||
Fortify("Fortify"),
|
Fortify("Fortify"),
|
||||||
|
FortifyUntilHealed("Fortify until healed"),
|
||||||
Explore("Explore"),
|
Explore("Explore"),
|
||||||
Promote("Promote"),
|
Promote("Promote"),
|
||||||
Upgrade("Upgrade"),
|
Upgrade("Upgrade"),
|
||||||
|
@ -16,7 +16,7 @@ class Translations : LinkedHashMap<String, TranslationEntry>(){
|
|||||||
return get(text)!![language]!!
|
return get(text)!![language]!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasTranslation(text:String,language:String): Boolean {
|
private fun hasTranslation(text:String,language:String): Boolean {
|
||||||
return containsKey(text) && get(text)!!.containsKey(language)
|
return containsKey(text) && get(text)!!.containsKey(language)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,31 +35,18 @@ class UnitActions {
|
|||||||
|
|
||||||
val workingOnImprovement = unit.hasUnique("Can build improvements on tiles")
|
val workingOnImprovement = unit.hasUnique("Can build improvements on tiles")
|
||||||
&& unit.currentTile.hasImprovementInProgress()
|
&& unit.currentTile.hasImprovementInProgress()
|
||||||
if (!unit.isFortified() && (!unit.canFortify() || unit.health < 100) && unit.currentMovement > 0
|
if (!unit.isFortified() && !unit.canFortify()
|
||||||
&& !workingOnImprovement) {
|
&& unit.currentMovement > 0 && !workingOnImprovement) {
|
||||||
val isSleeping = unit.action == Constants.unitActionSleep
|
addSleepActions(actionList, unit, unitTable)
|
||||||
actionList += UnitAction(
|
|
||||||
type = UnitActionType.Sleep,
|
|
||||||
canAct = !isSleeping,
|
|
||||||
isCurrentAction = isSleeping,
|
|
||||||
action = {
|
|
||||||
unit.action = Constants.unitActionSleep
|
|
||||||
unitTable.selectedUnit = null
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unit.canFortify()) {
|
if (unit.canFortify()) {
|
||||||
actionList += UnitAction(
|
addFortifyActions(actionList, unit, unitTable)
|
||||||
type = UnitActionType.Fortify,
|
|
||||||
canAct = unit.currentMovement > 0,
|
|
||||||
uncivSound = UncivSound.Fortify,
|
|
||||||
action = {
|
|
||||||
unit.fortify()
|
|
||||||
unitTable.selectedUnit = null
|
|
||||||
})
|
|
||||||
} else if (unit.isFortified()) {
|
} else if (unit.isFortified()) {
|
||||||
actionList += UnitAction(
|
actionList += UnitAction(
|
||||||
type = UnitActionType.Fortify,
|
type = if (unit.action!!.endsWith(" until healed"))
|
||||||
|
UnitActionType.FortifyUntilHealed else
|
||||||
|
UnitActionType.Fortify,
|
||||||
canAct = false,
|
canAct = false,
|
||||||
isCurrentAction = true,
|
isCurrentAction = true,
|
||||||
title = "${"Fortification".tr()} ${unit.getFortificationTurns() * 20}%"
|
title = "${"Fortification".tr()} ${unit.getFortificationTurns() * 20}%"
|
||||||
@ -320,6 +307,58 @@ class UnitActions {
|
|||||||
return actionList
|
return actionList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addFortifyActions(actionList: ArrayList<UnitAction>, unit: MapUnit, unitTable: UnitTable) {
|
||||||
|
|
||||||
|
val action = UnitAction(
|
||||||
|
type = UnitActionType.Fortify,
|
||||||
|
canAct = unit.currentMovement > 0,
|
||||||
|
uncivSound = UncivSound.Fortify,
|
||||||
|
action = {
|
||||||
|
unit.fortify()
|
||||||
|
unitTable.selectedUnit = null
|
||||||
|
})
|
||||||
|
|
||||||
|
if (unit.health < 100) {
|
||||||
|
val actionForWounded = action.copy(
|
||||||
|
type = UnitActionType.FortifyUntilHealed,
|
||||||
|
title = UnitActionType.FortifyUntilHealed.value,
|
||||||
|
action = {
|
||||||
|
unit.fortifyUntilHealed()
|
||||||
|
unitTable.selectedUnit = null
|
||||||
|
})
|
||||||
|
actionList += actionForWounded
|
||||||
|
}
|
||||||
|
|
||||||
|
actionList += action
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addSleepActions(actionList: ArrayList<UnitAction>, unit: MapUnit, unitTable: UnitTable) {
|
||||||
|
|
||||||
|
val isSleeping = unit.isSleeping()
|
||||||
|
|
||||||
|
val action = UnitAction(
|
||||||
|
type = UnitActionType.Sleep,
|
||||||
|
canAct = !isSleeping,
|
||||||
|
isCurrentAction = isSleeping,
|
||||||
|
action = {
|
||||||
|
unit.action = Constants.unitActionSleep
|
||||||
|
unitTable.selectedUnit = null
|
||||||
|
})
|
||||||
|
|
||||||
|
if (unit.health < 100 && !isSleeping) {
|
||||||
|
val actionForWounded = action.copy(
|
||||||
|
type = UnitActionType.SleepUntilHealed,
|
||||||
|
title = UnitActionType.SleepUntilHealed.value,
|
||||||
|
action = {
|
||||||
|
unit.action = Constants.unitActionSleepUntilHealed
|
||||||
|
unitTable.selectedUnit = null
|
||||||
|
})
|
||||||
|
actionList += actionForWounded
|
||||||
|
}
|
||||||
|
|
||||||
|
actionList += action
|
||||||
|
}
|
||||||
|
|
||||||
fun canPillage(unit: MapUnit, tile: TileInfo): Boolean {
|
fun canPillage(unit: MapUnit, tile: TileInfo): Boolean {
|
||||||
if (tile.improvement == null || tile.improvement == Constants.barbarianEncampment
|
if (tile.improvement == null || tile.improvement == Constants.barbarianEncampment
|
||||||
|| tile.improvement == Constants.ancientRuins
|
|| tile.improvement == Constants.ancientRuins
|
||||||
|
@ -18,17 +18,19 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
|
|||||||
touchable = Touchable.enabled
|
touchable = Touchable.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getIconForUnitAction(unitAction:String): Actor {
|
private fun getIconForUnitAction(unitAction:String): Actor {
|
||||||
if(unitAction.startsWith("Upgrade to")){
|
when {
|
||||||
|
unitAction.startsWith("Upgrade to") -> {
|
||||||
// Regexplaination: start with a [, take as many non-] chars as you can, until you reach a ].
|
// 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. 1
|
// What you find between the first [ and the first ] that comes after it, will be group no. 1
|
||||||
val unitToUpgradeTo = Regex("""Upgrade to \[([^\]]*)\]""").find(unitAction)!!.groups[1]!!.value
|
val unitToUpgradeTo = Regex("""Upgrade to \[([^\]]*)\]""").find(unitAction)!!.groups[1]!!.value
|
||||||
return ImageGetter.getUnitIcon(unitToUpgradeTo)
|
return ImageGetter.getUnitIcon(unitToUpgradeTo)
|
||||||
}
|
}
|
||||||
when(unitAction){
|
unitAction.startsWith("Sleep") -> return ImageGetter.getImage("OtherIcons/Sleep")
|
||||||
|
unitAction.startsWith("Fortify") -> return ImageGetter.getImage("OtherIcons/Shield").apply { color= Color.BLACK }
|
||||||
|
else -> when(unitAction){
|
||||||
"Move unit" -> return ImageGetter.getStatIcon("Movement")
|
"Move unit" -> return ImageGetter.getStatIcon("Movement")
|
||||||
"Stop movement"-> return ImageGetter.getStatIcon("Movement").apply { color= Color.RED }
|
"Stop movement"-> return ImageGetter.getStatIcon("Movement").apply { color= Color.RED }
|
||||||
"Fortify" -> return ImageGetter.getImage("OtherIcons/Shield").apply { color= Color.BLACK }
|
|
||||||
"Promote" -> return ImageGetter.getImage("OtherIcons/Star").apply { color= Color.GOLD }
|
"Promote" -> return ImageGetter.getImage("OtherIcons/Star").apply { color= Color.GOLD }
|
||||||
"Construct improvement" -> return ImageGetter.getUnitIcon(Constants.worker)
|
"Construct improvement" -> return ImageGetter.getUnitIcon(Constants.worker)
|
||||||
"Automate" -> return ImageGetter.getUnitIcon("Great Engineer")
|
"Automate" -> return ImageGetter.getUnitIcon("Great Engineer")
|
||||||
@ -44,7 +46,6 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
|
|||||||
"Construct Customs House" -> return ImageGetter.getImprovementIcon("Customs house")
|
"Construct Customs House" -> return ImageGetter.getImprovementIcon("Customs house")
|
||||||
"Set up" -> return ImageGetter.getUnitIcon("Catapult")
|
"Set up" -> return ImageGetter.getUnitIcon("Catapult")
|
||||||
"Disband unit" -> return ImageGetter.getImage("OtherIcons/DisbandUnit")
|
"Disband unit" -> return ImageGetter.getImage("OtherIcons/DisbandUnit")
|
||||||
"Sleep" -> return ImageGetter.getImage("OtherIcons/Sleep")
|
|
||||||
"Explore" -> return ImageGetter.getUnitIcon("Scout")
|
"Explore" -> return ImageGetter.getUnitIcon("Scout")
|
||||||
"Stop exploration" -> return ImageGetter.getImage("OtherIcons/Stop")
|
"Stop exploration" -> return ImageGetter.getImage("OtherIcons/Stop")
|
||||||
"Create Fishing Boats" -> return ImageGetter.getImprovementIcon("Fishing Boats")
|
"Create Fishing Boats" -> return ImageGetter.getImprovementIcon("Fishing Boats")
|
||||||
@ -54,6 +55,7 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
|
|||||||
else -> return ImageGetter.getImage("OtherIcons/Star")
|
else -> return ImageGetter.getImage("OtherIcons/Star")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun update(unit: MapUnit?){
|
fun update(unit: MapUnit?){
|
||||||
clear()
|
clear()
|
||||||
|
@ -4,6 +4,7 @@ package com.unciv.testing
|
|||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.utils.Array
|
import com.badlogic.gdx.utils.Array
|
||||||
import com.unciv.JsonParser
|
import com.unciv.JsonParser
|
||||||
|
import com.unciv.models.UnitActionType
|
||||||
import com.unciv.models.ruleset.Nation
|
import com.unciv.models.ruleset.Nation
|
||||||
import com.unciv.models.ruleset.Ruleset
|
import com.unciv.models.ruleset.Ruleset
|
||||||
import com.unciv.models.ruleset.RulesetCache
|
import com.unciv.models.ruleset.RulesetCache
|
||||||
@ -52,6 +53,20 @@ class TranslationTests {
|
|||||||
allStringsHaveTranslation)
|
allStringsHaveTranslation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun allUnitActionsHaveTranslation() {
|
||||||
|
val actions: MutableSet<String> = HashSet()
|
||||||
|
for (action in UnitActionType.values()) {
|
||||||
|
if (action == UnitActionType.Upgrade)
|
||||||
|
actions.add("Upgrade to [unitType] ([goldCost] gold)")
|
||||||
|
else
|
||||||
|
actions.add(action.value)
|
||||||
|
}
|
||||||
|
val allUnitActionsHaveTranslation = allStringAreTranslated(actions)
|
||||||
|
Assert.assertTrue("This test will only pass when there is a translation for all unit actions",
|
||||||
|
allUnitActionsHaveTranslation)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun allBuildingsHaveTranslation() {
|
fun allBuildingsHaveTranslation() {
|
||||||
val allBuildingsHaveTranslation = allStringAreTranslated(ruleset.buildings.keys)
|
val allBuildingsHaveTranslation = allStringAreTranslated(ruleset.buildings.keys)
|
||||||
|
Reference in New Issue
Block a user