Added feature to save unitType promotion. (#12894)

* Settler settle best tile when not escort and dangerous Tiles instead of running away

Settler unit will now settle on best tile in dangerous Tiles without escort instead of running away.

* Update WorkerAutomation.kt

* Update SpecificUnitAutomation.kt

* Update WorkerAutomation.kt

* Update SpecificUnitAutomation.kt

* Now city states get mad when you steal their Lands

* new version

* change to getDiplomacyManagerOrMeet

* added text to template.properties and changed AlertPopup.kt

* Update template.properties

* with period at the end :b

* add flag now

* Made Option to declare war when a city state is bullied unavailable

* added option to change the Maximum Autosave turns stored

* remove print

* change letter

* should fix issue with building test

* update with changes

* Added UniqueType.FoundPuppetCity

with "Founds a new puppet city" in "uniques" of an unit in Units.json.
Making it so you can now settle a puppet city.

* Added save promotion

* Updated for PR

* Updated with requested changes

* Removed unnecessary check

* updated PR

* Update PromotionPickerScreen.kt to save promotion cells too

* change name and added !

* updated name of variable
This commit is contained in:
General_E 2025-02-13 19:34:58 +01:00 committed by GitHub
parent 34b281ebfc
commit 2a8edb3af0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 112 additions and 53 deletions

View File

@ -200,6 +200,34 @@ OtherIcons/Stop
orig: 100, 100
offset: 0, 0
index: -1
ImprovementIcons/Circle
rotate: false
xy: 289, 1590
size: 178, 178
orig: 178, 178
offset: 0, 0
index: -1
OtherIcons/Circle
rotate: false
xy: 289, 1590
size: 178, 178
orig: 178, 178
offset: 0, 0
index: -1
ResourceIcons/Circle
rotate: false
xy: 289, 1590
size: 178, 178
orig: 178, 178
offset: 0, 0
index: -1
StatIcons/Circle
rotate: false
xy: 289, 1590
size: 178, 178
orig: 178, 178
offset: 0, 0
index: -1
ImprovementIcons/Citadel
rotate: false
xy: 4, 62
@ -459,6 +487,27 @@ StatIcons/Faith
orig: 100, 100
offset: 0, 0
index: -1
NotificationIcons/Loading
rotate: false
xy: 907, 1686
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
NotificationIcons/Working
rotate: false
xy: 907, 1686
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
OtherIcons/Loading
rotate: false
xy: 907, 1686
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
NotificationIcons/PickConstruction
rotate: false
xy: 1771, 1500
@ -620,34 +669,6 @@ NotificationIcons/NextTurn
orig: 100, 100
offset: 0, 0
index: -1
OtherIcons/Circle
rotate: false
xy: 289, 1590
size: 178, 178
orig: 178, 178
offset: 0, 0
index: -1
ImprovementIcons/Circle
rotate: false
xy: 289, 1590
size: 178, 178
orig: 178, 178
offset: 0, 0
index: -1
ResourceIcons/Circle
rotate: false
xy: 289, 1590
size: 178, 178
orig: 178, 178
offset: 0, 0
index: -1
StatIcons/Circle
rotate: false
xy: 289, 1590
size: 178, 178
orig: 178, 178
offset: 0, 0
index: -1
OtherIcons/Cities
rotate: false
xy: 208, 1436
@ -823,27 +844,6 @@ OtherIcons/Load
orig: 100, 100
offset: 0, 0
index: -1
OtherIcons/Loading
rotate: false
xy: 907, 1686
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
NotificationIcons/Loading
rotate: false
xy: 907, 1686
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
NotificationIcons/Working
rotate: false
xy: 907, 1686
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
OtherIcons/LockSmall
rotate: false
xy: 1398, 1168

View File

@ -113,6 +113,8 @@ Requires [PolicyOrNationalWonder] =
Cannot be purchased =
Can only be purchased =
See also =
Use default promotions =
Default promotions for [unitType] =
Requires at least one of the following: =
Requires all of the following: =

View File

@ -14,6 +14,7 @@ import com.unciv.logic.city.managers.SpyFleeReason
import com.unciv.logic.civilization.Civilization
import com.unciv.logic.map.TileMap
import com.unciv.logic.map.mapunit.MapUnit
import com.unciv.logic.map.mapunit.UnitPromotions
import com.unciv.logic.map.tile.RoadStatus
import com.unciv.logic.map.tile.Tile
import com.unciv.models.Counter
@ -91,7 +92,11 @@ class City : IsPartOfGameInfoSerialization, INamed {
var hasSoldBuildingThisTurn = false
var isPuppet = false
var shouldReassignPopulation = false // flag so that on startTurn() we reassign population
var unitTypeShouldUseSavedPromotion = HashMap<String, Boolean>()
var cityUnitTypePromotions = HashMap<String, UnitPromotions>()
@delegate:Transient
val neighboringCities: List<City> by lazy {
civ.gameInfo.getCities().filter { it != this && it.getCenterTile().isExplored(civ) && it.getCenterTile().aerialDistanceTo(getCenterTile()) <= 12 }.toList()
@ -153,6 +158,8 @@ class City : IsPartOfGameInfoSerialization, INamed {
toReturn.avoidGrowth = avoidGrowth
toReturn.manualSpecialists = manualSpecialists
toReturn.connectedToCapitalStatus = connectedToCapitalStatus
toReturn.unitTypeShouldUseSavedPromotion = unitTypeShouldUseSavedPromotion
toReturn.cityUnitTypePromotions = cityUnitTypePromotions
return toReturn
}

View File

@ -464,6 +464,19 @@ class CityConstructions : IsPartOfGameInfoSerialization {
else if (construction is BaseUnit) {
unit = construction.construct(this, null)
?: return false // unable to place unit
// checking if it's true that we should load saved promotion for the unitType
// Check if the player want to rebuild the unit the saved promotion
// and null check.
// and finally check if the current unit has enough XP.
val savedPromotion = city.cityUnitTypePromotions[unit.baseUnit.unitType]
if (city.unitTypeShouldUseSavedPromotion[unit.baseUnit.unitType] == true &&
savedPromotion != null && unit.promotions.XP >= savedPromotion.XP) {
for (promotions in savedPromotion.promotions) {
unit.promotions.addPromotion(promotions)
}
}
}
if (construction.name in inProgressConstructions)

View File

@ -9,6 +9,7 @@ import com.unciv.logic.city.CityConstructions
import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.IConstruction
import com.unciv.models.ruleset.PerpetualConstruction
import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.ui.components.input.KeyboardBinding
//todo Check move/top/end for "place one improvement" buildings

View File

@ -15,6 +15,7 @@ import com.unciv.models.translations.tr
import com.unciv.ui.components.extensions.darken
import com.unciv.ui.components.extensions.disable
import com.unciv.ui.components.extensions.isEnabled
import com.unciv.ui.components.extensions.toCheckBox
import com.unciv.ui.components.extensions.toTextButton
import com.unciv.ui.components.fonts.Fonts
import com.unciv.ui.components.input.onClick
@ -90,7 +91,7 @@ class ConstructionInfoTable(val cityScreen: CityScreen) : Table() {
val descriptionLabel = Label(description, BaseScreen.skin) // already translated
descriptionLabel.wrap = true
add(descriptionLabel).colspan(2).width(stage.width / if(cityScreen.isCrampedPortrait()) 3 else 4)
if (cityConstructions.isBuilt(construction.name)) {
showSellButton(construction)
} else if (buyButtonFactory.hasBuyButtons(construction)) {
@ -99,6 +100,16 @@ class ConstructionInfoTable(val cityScreen: CityScreen) : Table() {
selectedConstructionTable.add(button).padTop(5f).colspan(2).center().row()
}
}
if (construction is BaseUnit) {
val unitType = construction.unitType
val buildUnitWithPromotions = city.unitTypeShouldUseSavedPromotion[unitType]
if (buildUnitWithPromotions != null) {
row()
add("Use default promotions".toCheckBox(buildUnitWithPromotions) {city.unitTypeShouldUseSavedPromotion[unitType] = it}).colspan(2).center()
}
}
}
}
@ -133,7 +144,7 @@ class ConstructionInfoTable(val cityScreen: CityScreen) : Table() {
}
}
}
private fun sellBuildingClicked(construction: Building, sellText: String) {
cityScreen.closeAllPopups()

View File

@ -15,6 +15,7 @@ import com.unciv.models.ruleset.unit.Promotion
import com.unciv.models.translations.tr
import com.unciv.ui.audio.SoundPlayer
import com.unciv.ui.components.extensions.isEnabled
import com.unciv.ui.components.extensions.toCheckBox
import com.unciv.ui.components.extensions.toTextButton
import com.unciv.ui.components.input.KeyCharAndCode
import com.unciv.ui.components.input.KeyboardBinding
@ -64,6 +65,8 @@ class PromotionPickerScreen private constructor(
// Logic
private val tree = PromotionTree(unit)
// This if we should save the unit promotion or not.
private var saveUnitTypePromotion = false
init {
closeButton.onActivation {
@ -77,6 +80,8 @@ class PromotionPickerScreen private constructor(
rightSideButton.setText("Pick promotion".tr())
rightSideButton.onClick(UncivSound.Silent) {
acceptPromotion(selectedPromotion)
checkSaveUnitTypePrormotion()
}
} else {
rightSideButton.isVisible = false
@ -191,9 +196,29 @@ class PromotionPickerScreen private constructor(
}
topTable.add(promotionsTable)
saveUnitTypePromotionForCity()
addConnectingLines(emptySet())
}
// adds the checkBoxs to choice to save unit promotion.
private fun saveUnitTypePromotionForCity() {
val checkBoxSaveUnitPromotion = "Default promotions for [${unit.baseUnit.unitType}]".toCheckBox(saveUnitTypePromotion) {saveUnitTypePromotion = it}
promotionsTable.add(checkBoxSaveUnitPromotion)
}
// going to reuse this bit of code 2 time so turn it into a funtion
private fun checkSaveUnitTypePrormotion() {
if (!saveUnitTypePromotion) {
val unitCurrentCity = unit.currentTile.getCity()
if (unitCurrentCity != null) {
// If you are clicked the save unitType promotion, you want the next unitType to have the same promotion.
unitCurrentCity.unitTypeShouldUseSavedPromotion.put(unit.baseUnit.unitType,true)
unitCurrentCity.cityUnitTypePromotions.put(unit.baseUnit.unitType,unit.promotions)
}
}
}
private fun getButton(tree: PromotionTree, node: PromotionTree.PromotionNode) : PromotionButton {
val isPickable = canPromoteNow &&
(!node.pathIsAmbiguous || node.distanceToAdopted == 1) &&
@ -221,6 +246,7 @@ class PromotionPickerScreen private constructor(
if (isPickable)
button.onDoubleClick(UncivSound.Silent) {
acceptPromotion(button)
checkSaveUnitTypePrormotion()
}
return button
@ -352,7 +378,6 @@ class PromotionPickerScreen private constructor(
}
override fun recreate() = recreate(closeOnPick)
fun recreate(closeOnPick: Boolean): BaseScreen {
val newScreen = PromotionPickerScreen(unit, closeOnPick, originalName, onChange)
newScreen.setScrollY(scrollPane.scrollY)