mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-11 16:29:48 +07:00
Add May not annex cities
unique (#9314)
* Add `May not annex cities` unique, following same behaviour as Civ5 Venice. Hopefully this time I won't need to re-install windows. * Add `May not annex cities` unique, following same behaviour as Civ5 Venice. Hopefully this time I won't need to re-install windows. * Fix raze button being unavailable in city screen * Fixed raze button being available in city screen, as per civ5 * Corrected indentation * mayAnnex instead of canAnnex, hasUnique rather than getMatchingUniques * AI will follow rules * Replaced getMatchingUniques with hasUnique, for real this time
This commit is contained in:
@ -1411,6 +1411,7 @@ What would you like to do with the city of [cityName]? =
|
|||||||
Annex =
|
Annex =
|
||||||
Annexed cities become part of your regular empire. =
|
Annexed cities become part of your regular empire. =
|
||||||
Their citizens generate 2x the unhappiness, unless you build a courthouse. =
|
Their citizens generate 2x the unhappiness, unless you build a courthouse. =
|
||||||
|
Your civilization may not annex this city. =
|
||||||
Puppet =
|
Puppet =
|
||||||
Puppeted cities do not increase your tech or policy cost. =
|
Puppeted cities do not increase your tech or policy cost. =
|
||||||
You have no control over the the production of puppeted cities. =
|
You have no control over the the production of puppeted cities. =
|
||||||
@ -1420,6 +1421,7 @@ Liberate (city returns to [originalOwner]) =
|
|||||||
Liberating a city returns it to its original owner, giving you a massive relationship boost with them! =
|
Liberating a city returns it to its original owner, giving you a massive relationship boost with them! =
|
||||||
Raze =
|
Raze =
|
||||||
Razing the city annexes it, and starts burning the city to the ground. =
|
Razing the city annexes it, and starts burning the city to the ground. =
|
||||||
|
Razing the city puppets it, and starts burning the city to the ground. =
|
||||||
The population will gradually dwindle until the city is destroyed. =
|
The population will gradually dwindle until the city is destroyed. =
|
||||||
Original capitals and holy cities cannot be razed. =
|
Original capitals and holy cities cannot be razed. =
|
||||||
Destroy =
|
Destroy =
|
||||||
|
@ -1016,7 +1016,7 @@ object NextTurnAutomation {
|
|||||||
ownMilitaryStrength < sumOfEnemiesMilitaryStrength * 0.66f
|
ownMilitaryStrength < sumOfEnemiesMilitaryStrength * 0.66f
|
||||||
for (city in civInfo.cities) {
|
for (city in civInfo.cities) {
|
||||||
if (city.isPuppet && city.population.population > 9
|
if (city.isPuppet && city.population.population > 9
|
||||||
&& !city.isInResistance()
|
&& !city.isInResistance() && !civInfo.hasUnique(UniqueType.MayNotAnnexCities)
|
||||||
) {
|
) {
|
||||||
city.annexCity()
|
city.annexCity()
|
||||||
}
|
}
|
||||||
@ -1124,7 +1124,7 @@ object NextTurnAutomation {
|
|||||||
if ((city.population.population < 4 || civInfo.isCityState())
|
if ((city.population.population < 4 || civInfo.isCityState())
|
||||||
&& city.foundingCiv != civInfo.civName && city.canBeDestroyed(justCaptured = true)) {
|
&& city.foundingCiv != civInfo.civName && city.canBeDestroyed(justCaptured = true)) {
|
||||||
// raze if attacker is a city state
|
// raze if attacker is a city state
|
||||||
city.annexCity()
|
if (!civInfo.hasUnique(UniqueType.MayNotAnnexCities)) { city.annexCity() }
|
||||||
city.isBeingRazed = true
|
city.isBeingRazed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,6 +595,7 @@ object Battle {
|
|||||||
if (city.isOriginalCapital && city.foundingCiv == attackerCiv.civName) {
|
if (city.isOriginalCapital && city.foundingCiv == attackerCiv.civName) {
|
||||||
// retaking old capital
|
// retaking old capital
|
||||||
city.puppetCity(attackerCiv)
|
city.puppetCity(attackerCiv)
|
||||||
|
//Although in Civ5 Venice is unable to re-annex their capital, that seems a bit silly. No check for May not annex cities here.
|
||||||
city.annexCity()
|
city.annexCity()
|
||||||
} else if (attackerCiv.isHuman()) {
|
} else if (attackerCiv.isHuman()) {
|
||||||
// we're not taking our former capital
|
// we're not taking our former capital
|
||||||
|
@ -315,6 +315,13 @@ class CityInfoConquestFunctions(val city: City){
|
|||||||
|
|
||||||
if (civ.gameInfo.isReligionEnabled()) religion.removeUnknownPantheons()
|
if (civ.gameInfo.isReligionEnabled()) religion.removeUnknownPantheons()
|
||||||
|
|
||||||
|
if (newCiv.hasUnique(UniqueType.MayNotAnnexCities)) {
|
||||||
|
isPuppet = true
|
||||||
|
cityConstructions.currentConstructionIsUserSet = false
|
||||||
|
cityConstructions.constructionQueue.clear()
|
||||||
|
cityConstructions.chooseNextConstruction()
|
||||||
|
}
|
||||||
|
|
||||||
tryUpdateRoadStatus()
|
tryUpdateRoadStatus()
|
||||||
cityStats.update()
|
cityStats.update()
|
||||||
|
|
||||||
|
@ -239,6 +239,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
|||||||
GainInfluenceWithUnitGiftToCityState("Gain [amount] Influence with a [baseUnitFilter] gift to a City-State", UniqueTarget.Global),
|
GainInfluenceWithUnitGiftToCityState("Gain [amount] Influence with a [baseUnitFilter] gift to a City-State", UniqueTarget.Global),
|
||||||
FaithCostOfGreatProphetChange("[relativeAmount]% Faith cost of generating Great Prophet equivalents", UniqueTarget.Global),
|
FaithCostOfGreatProphetChange("[relativeAmount]% Faith cost of generating Great Prophet equivalents", UniqueTarget.Global),
|
||||||
RestingPointOfCityStatesFollowingReligionChange("Resting point for Influence with City-States following this religion [amount]", UniqueTarget.Global),
|
RestingPointOfCityStatesFollowingReligionChange("Resting point for Influence with City-States following this religion [amount]", UniqueTarget.Global),
|
||||||
|
MayNotAnnexCities("May not annex cities", UniqueTarget.Nation),
|
||||||
|
|
||||||
ProvidesGoldWheneverGreatPersonExpended("Provides a sum of gold each time you spend a Great Person", UniqueTarget.Global),
|
ProvidesGoldWheneverGreatPersonExpended("Provides a sum of gold each time you spend a Great Person", UniqueTarget.Global),
|
||||||
ProvidesStatsWheneverGreatPersonExpended("[stats] whenever a Great Person is expended", UniqueTarget.Global),
|
ProvidesStatsWheneverGreatPersonExpended("[stats] whenever a Great Person is expended", UniqueTarget.Global),
|
||||||
|
@ -259,7 +259,8 @@ class CityScreen(
|
|||||||
addWltkIcon("OtherIcons/WLTK 1") { color = Color.FIREBRICK }.padRight(10f)
|
addWltkIcon("OtherIcons/WLTK 1") { color = Color.FIREBRICK }.padRight(10f)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (city.isPuppet) {
|
val canAnnex = !city.civ.hasUnique(UniqueType.MayNotAnnexCities)
|
||||||
|
if (city.isPuppet && canAnnex) {
|
||||||
val annexCityButton = "Annex city".toTextButton()
|
val annexCityButton = "Annex city".toTextButton()
|
||||||
annexCityButton.labelCell.pad(10f)
|
annexCityButton.labelCell.pad(10f)
|
||||||
annexCityButton.onClick {
|
annexCityButton.onClick {
|
||||||
@ -272,8 +273,9 @@ class CityScreen(
|
|||||||
val razeCityButton = "Raze city".toTextButton()
|
val razeCityButton = "Raze city".toTextButton()
|
||||||
razeCityButton.labelCell.pad(10f)
|
razeCityButton.labelCell.pad(10f)
|
||||||
razeCityButton.onClick { city.isBeingRazed = true; update() }
|
razeCityButton.onClick { city.isBeingRazed = true; update() }
|
||||||
if (!canChangeState || !city.canBeDestroyed())
|
if (!canChangeState || !city.canBeDestroyed() || !canAnnex) {
|
||||||
razeCityButton.disable()
|
razeCityButton.disable()
|
||||||
|
}
|
||||||
|
|
||||||
razeCityButtonHolder.add(razeCityButton) //.colspan(cityPickerTable.columns)
|
razeCityButtonHolder.add(razeCityButton) //.colspan(cityPickerTable.columns)
|
||||||
} else {
|
} else {
|
||||||
|
@ -14,6 +14,7 @@ import com.unciv.logic.civilization.NotificationCategory
|
|||||||
import com.unciv.logic.civilization.PopupAlert
|
import com.unciv.logic.civilization.PopupAlert
|
||||||
import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers
|
import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers
|
||||||
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
||||||
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.models.translations.fillPlaceholders
|
import com.unciv.models.translations.fillPlaceholders
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
import com.unciv.ui.audio.MusicMood
|
import com.unciv.ui.audio.MusicMood
|
||||||
@ -146,7 +147,8 @@ class AlertPopup(
|
|||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
addAnnexOption {
|
val mayAnnex = !conqueringCiv.hasUnique(UniqueType.MayNotAnnexCities)
|
||||||
|
addAnnexOption(mayAnnex = mayAnnex) {
|
||||||
city.puppetCity(conqueringCiv)
|
city.puppetCity(conqueringCiv)
|
||||||
city.annexCity()
|
city.annexCity()
|
||||||
worldScreen.shouldUpdate = true
|
worldScreen.shouldUpdate = true
|
||||||
@ -154,16 +156,16 @@ class AlertPopup(
|
|||||||
}
|
}
|
||||||
addSeparator()
|
addSeparator()
|
||||||
|
|
||||||
addPuppetOption {
|
addPuppetOption(mayAnnex = mayAnnex) {
|
||||||
city.puppetCity(conqueringCiv)
|
city.puppetCity(conqueringCiv)
|
||||||
worldScreen.shouldUpdate = true
|
worldScreen.shouldUpdate = true
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
addSeparator()
|
addSeparator()
|
||||||
|
|
||||||
addRazeOption(canRaze = { city.canBeDestroyed(justCaptured = true) } ) {
|
addRazeOption(canRaze = city.canBeDestroyed(justCaptured = true), mayAnnex = mayAnnex) {
|
||||||
city.puppetCity(conqueringCiv)
|
city.puppetCity(conqueringCiv)
|
||||||
city.annexCity()
|
if (mayAnnex) { city.annexCity() }
|
||||||
city.isBeingRazed = true
|
city.isBeingRazed = true
|
||||||
worldScreen.shouldUpdate = true
|
worldScreen.shouldUpdate = true
|
||||||
close()
|
close()
|
||||||
@ -239,13 +241,14 @@ class AlertPopup(
|
|||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
addAnnexOption {
|
val mayAnnex = !marryingCiv.hasUnique(UniqueType.MayNotAnnexCities)
|
||||||
|
addAnnexOption(mayAnnex) {
|
||||||
city.annexCity()
|
city.annexCity()
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
addSeparator()
|
addSeparator()
|
||||||
|
|
||||||
addPuppetOption {
|
addPuppetOption(mayAnnex) {
|
||||||
city.isPuppet = true
|
city.isPuppet = true
|
||||||
city.cityStats.update()
|
city.cityStats.update()
|
||||||
worldScreen.shouldUpdate = true
|
worldScreen.shouldUpdate = true
|
||||||
@ -428,16 +431,25 @@ class AlertPopup(
|
|||||||
addGoodSizedLabel("Destroying the city instantly razes the city to the ground.").row()
|
addGoodSizedLabel("Destroying the city instantly razes the city to the ground.").row()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addAnnexOption(annexAction: () -> Unit) {
|
private fun addAnnexOption(mayAnnex: Boolean, annexAction: () -> Unit) {
|
||||||
val button = "Annex".toTextButton()
|
val button = "Annex".toTextButton()
|
||||||
button.onActivation { annexAction() }
|
button.apply {
|
||||||
button.keyShortcuts.add('a')
|
if (!mayAnnex) disable() else {
|
||||||
|
button.onActivation { annexAction() }
|
||||||
|
button.keyShortcuts.add('a')
|
||||||
|
}
|
||||||
|
}
|
||||||
add(button).row()
|
add(button).row()
|
||||||
addGoodSizedLabel("Annexed cities become part of your regular empire.").row()
|
if (mayAnnex) {
|
||||||
addGoodSizedLabel("Their citizens generate 2x the unhappiness, unless you build a courthouse.").row()
|
addGoodSizedLabel("Annexed cities become part of your regular empire.").row()
|
||||||
|
addGoodSizedLabel("Their citizens generate 2x the unhappiness, unless you build a courthouse.").row()
|
||||||
|
} else {
|
||||||
|
addGoodSizedLabel("Your civilization may not annex this city.").row()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addPuppetOption(puppetAction: () -> Unit) {
|
private fun addPuppetOption(mayAnnex: Boolean, puppetAction: () -> Unit) {
|
||||||
val button = "Puppet".toTextButton()
|
val button = "Puppet".toTextButton()
|
||||||
button.onActivation { puppetAction() }
|
button.onActivation { puppetAction() }
|
||||||
button.keyShortcuts.add('p')
|
button.keyShortcuts.add('p')
|
||||||
@ -445,7 +457,7 @@ class AlertPopup(
|
|||||||
addGoodSizedLabel("Puppeted cities do not increase your tech or policy cost.").row()
|
addGoodSizedLabel("Puppeted cities do not increase your tech or policy cost.").row()
|
||||||
addGoodSizedLabel("You have no control over the the production of puppeted cities.").row()
|
addGoodSizedLabel("You have no control over the the production of puppeted cities.").row()
|
||||||
addGoodSizedLabel("Puppeted cities also generate 25% less Gold and Science.").row()
|
addGoodSizedLabel("Puppeted cities also generate 25% less Gold and Science.").row()
|
||||||
addGoodSizedLabel("A puppeted city can be annexed at any time.").row()
|
if (mayAnnex) addGoodSizedLabel("A puppeted city can be annexed at any time.").row()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addLiberateOption(foundingCiv: String, liberateAction: () -> Unit) {
|
private fun addLiberateOption(foundingCiv: String, liberateAction: () -> Unit) {
|
||||||
@ -456,18 +468,22 @@ class AlertPopup(
|
|||||||
addGoodSizedLabel("Liberating a city returns it to its original owner, giving you a massive relationship boost with them!")
|
addGoodSizedLabel("Liberating a city returns it to its original owner, giving you a massive relationship boost with them!")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addRazeOption(canRaze: () -> Boolean, razeAction: () -> Unit) {
|
private fun addRazeOption(canRaze: Boolean, mayAnnex: Boolean, razeAction: () -> Unit) {
|
||||||
val button = "Raze".toTextButton()
|
val button = "Raze".toTextButton()
|
||||||
button.apply {
|
button.apply {
|
||||||
if (!canRaze()) disable()
|
if (!canRaze) disable()
|
||||||
else {
|
else {
|
||||||
onActivation { razeAction() }
|
onActivation { razeAction() }
|
||||||
keyShortcuts.add('r')
|
keyShortcuts.add('r')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
add(button).row()
|
add(button).row()
|
||||||
if (canRaze()) {
|
if (canRaze) {
|
||||||
addGoodSizedLabel("Razing the city annexes it, and starts burning the city to the ground.").row()
|
if (mayAnnex) {
|
||||||
|
addGoodSizedLabel("Razing the city annexes it, and starts burning the city to the ground.").row()
|
||||||
|
} else {
|
||||||
|
addGoodSizedLabel("Razing the city puppets it, and starts burning the city to the ground.").row()
|
||||||
|
}
|
||||||
addGoodSizedLabel("The population will gradually dwindle until the city is destroyed.").row()
|
addGoodSizedLabel("The population will gradually dwindle until the city is destroyed.").row()
|
||||||
} else {
|
} else {
|
||||||
addGoodSizedLabel("Original capitals and holy cities cannot be razed.").row()
|
addGoodSizedLabel("Original capitals and holy cities cannot be razed.").row()
|
||||||
|
@ -863,6 +863,9 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
|
|||||||
??? example "Will not be chosen for new games"
|
??? example "Will not be chosen for new games"
|
||||||
Applicable to: Nation
|
Applicable to: Nation
|
||||||
|
|
||||||
|
??? example "May not annex cities"
|
||||||
|
Applicable to: Nation
|
||||||
|
|
||||||
??? example "Starts with [tech]"
|
??? example "Starts with [tech]"
|
||||||
Example: "Starts with [Agriculture]"
|
Example: "Starts with [Agriculture]"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user