[663] Allow unit rename on promote (#3620)

* Add nullable "instanceName" field to MapUnit to capture name for individual units
* Add "displayName" property to MapUnit which takes instanceName if set, name
  otherwise
* Add dialog to PromotionPicker to allow setting instanceName of unit, if not
  already set
This commit is contained in:
david.howard
2021-03-01 10:52:46 -08:00
committed by GitHub
parent 237884a60d
commit 12e3005294
11 changed files with 84 additions and 9 deletions

View File

@ -902,6 +902,7 @@ Bonus when performing air sweep [bonusAmount]% =
Dogfighting I =
Dogfighting II =
Dogfighting III =
Choose name for [unitName] =
# Multiplayer Turn Checker Service

View File

@ -474,7 +474,7 @@ object UnitAutomation {
if (tryGoToRuinAndEncampment(unit) && unit.currentMovement == 0f) return
if (unit.health < 80 && tryHealUnit(unit)) return
if (tryExplore(unit)) return
unit.civInfo.addNotification("[${unit.name}] finished exploring.", unit.currentTile.position, Color.GRAY)
unit.civInfo.addNotification("[${unit.displayName()}] finished exploring.", unit.currentTile.position, Color.GRAY)
unit.action = null
}

View File

@ -56,7 +56,7 @@ class WorkerAutomation(val unit: MapUnit) {
return
}
unit.civInfo.addNotification("[${unit.name}] has no work to do.", unit.currentTile.position, Color.GRAY)
unit.civInfo.addNotification("[${unit.displayName()}] has no work to do.", unit.currentTile.position, Color.GRAY)
}

View File

@ -508,7 +508,7 @@ class CivilizationInfo {
val unitToDisband = civMilitaryUnits.first()
unitToDisband.disband()
civMilitaryUnits -= unitToDisband
val unitName = unitToDisband.name
val unitName = unitToDisband.displayName()
addNotification("Cannot provide unit upkeep for [$unitName] - unit has been disbanded!", null, Color.RED)
}
}

View File

@ -14,6 +14,9 @@ import com.unciv.models.ruleset.unit.UnitType
import java.text.DecimalFormat
import kotlin.random.Random
/**
* The immutable properties and mutable game state of an individual unit present on the map
*/
class MapUnit {
@Transient
@ -57,7 +60,29 @@ class MapUnit {
var cannotEnterOceanTilesUntilAstronomy = false
lateinit var owner: String
/**
* Name key of the unit, used for serialization
*/
lateinit var name: String
/**
* Name of this individual unit, usually resulting from promotion
*/
var instanceName: String? = null
/**
* Name which should be displayed in UI
*/
fun displayName(): String {
return if(instanceName == null) {
name
}
else {
"$instanceName ($name)"
}
}
var currentMovement: Float = 0f
var health: Int = 100
@ -77,8 +102,11 @@ class MapUnit {
//region pure functions
fun clone(): MapUnit {
val toReturn = MapUnit()
toReturn.owner = owner
toReturn.baseUnit = baseUnit
toReturn.name = name
toReturn.civInfo = civInfo
toReturn.owner = owner
toReturn.instanceName = instanceName
toReturn.currentMovement = currentMovement
toReturn.health = health
toReturn.action = action

View File

@ -350,10 +350,10 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa
table.row()
table.addSeparator()
for (unit in viewingPlayer.getCivUnits().sortedWith(compareBy({ it.name }, { !it.due },
for (unit in viewingPlayer.getCivUnits().sortedWith(compareBy({ it.displayName() }, { !it.due },
{ it.currentMovement < 0.1f }, { abs(it.currentTile.position.x) + abs(it.currentTile.position.y) }))) {
val baseUnit = unit.baseUnit()
val button = unit.name.toTextButton()
val button = unit.displayName().toTextButton()
button.onClick {
game.setWorldScreen()
game.worldScreen.mapHolder.setCenterPosition(unit.currentTile.position)

View File

@ -14,6 +14,11 @@ open class PickerScreen : CameraStageBaseScreen() {
protected var rightSideGroup = VerticalGroup()
protected var rightSideButton: TextButton
private var screenSplit = 0.85f
/**
* The table displaying the choices from which to pick (usually).
* Also the element which most of the screen realestate is devoted to displaying.
*/
protected var topTable: Table
var bottomTable:Table = Table()
internal var splitPane: SplitPane

View File

@ -40,7 +40,8 @@ class PromotionPickerScreen(val unit: MapUnit) : PickerScreen() {
}
val canBePromoted = unit.promotions.canBePromoted()
val canChangeState = game.worldScreen.canChangeState
if (!canBePromoted || !canChangeState)
val canPromoteNow = canBePromoted && canChangeState
if (!canPromoteNow)
rightSideButton.disable()
val availablePromotionsGroup = Table()
@ -52,6 +53,15 @@ class PromotionPickerScreen(val unit: MapUnit) : PickerScreen() {
|| unit.promotions.promotions.contains(it.name) }
val unitAvailablePromotions = unit.promotions.getAvailablePromotions()
if(canPromoteNow && unit.instanceName == null) {
val renameButton = "Choose name for [${unit.name}]".toTextButton()
renameButton.touchable = Touchable.enabled
renameButton.onClick {
RenameUnitPopup(unit, this).open()
}
availablePromotionsGroup.add(renameButton)
availablePromotionsGroup.row()
}
for (promotion in promotionsForUnitType) {
if(promotion.name=="Heal Instantly" && unit.health==100) continue
val isPromotionAvailable = promotion in unitAvailablePromotions

View File

@ -0,0 +1,31 @@
package com.unciv.ui.pickerscreens
import com.badlogic.gdx.scenes.scene2d.ui.TextField
import com.unciv.logic.map.MapUnit
import com.unciv.models.translations.tr
import com.unciv.ui.utils.*
class RenameUnitPopup(unit: MapUnit, screen: CameraStageBaseScreen): Popup(screen) {
init {
addGoodSizedLabel("Choose name for [${unit.baseUnit.name}]").row()
val nameField = TextField("", skin)
// Disallowed special characters determined with US keyboard and a certain binary
// copyrighted by Firaxis Games
val illegal_chars = "%*[]\"\\|<>/?"
nameField.textFieldFilter = TextField.TextFieldFilter { _, char -> !(char in illegal_chars)}
// Max name length decided arbitrarily
nameField.maxLength = 10
add(nameField)
row()
add("OK".toTextButton().onClick {
if (nameField.text != "") {
unit.instanceName = nameField.text
}
screen.game.setScreen(PromotionPickerScreen(unit))
})
add("Close".toTextButton().onClick { close() })
}
}

View File

@ -110,7 +110,7 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
if(selectedUnits.size==1) { //single selected unit
separator.isVisible = true
val unit = selectedUnit!!
var nameLabelText = unit.name.tr()
var nameLabelText = unit.displayName().tr()
if (unit.health < 100) nameLabelText += " (" + unit.health + ")"
if (nameLabelText != unitNameLabel.text.toString()) {
unitNameLabel.setText(nameLabelText)