mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-30 14:48:56 +07:00
Spy max rank can be modded (#11650)
* Changed the spy level cap to be a mod constant * Spy rank shows with more stars * Reverted some temporary debug changes * Changed Promotes all spies to accept an amount * Change Promotes all spies [amount] time(s) to have parenthesis around the s * Fixed problem with merging
This commit is contained in:
@ -87,6 +87,8 @@ class ModConstants {
|
||||
|
||||
var workboatAutomationSearchMaxTiles = 20
|
||||
|
||||
var maxSpyLevel = 3
|
||||
|
||||
fun merge(other: ModConstants) {
|
||||
for (field in this::class.java.declaredFields) {
|
||||
if (field.modifiers and Modifier.STATIC != 0) continue
|
||||
|
@ -230,9 +230,9 @@ class Spy private constructor() : IsPartOfGameInfoSerialization {
|
||||
otherCiv.getDiplomacyManager(civInfo).addModifier(DiplomaticModifiers.SpiedOnUs, -15f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun canDoCoup(): Boolean = getCityOrNull() != null && getCity().civ.isCityState() && isSetUp() && getCity().civ.getAllyCiv() != civInfo.civName
|
||||
|
||||
|
||||
/**
|
||||
* Initiates a coup if this spies civ is not the ally of the city-state.
|
||||
* The coup will only happen at the end of the Civ's turn for save scum reasons, so a play may not reload in multiplayer.
|
||||
@ -353,11 +353,13 @@ class Spy private constructor() : IsPartOfGameInfoSerialization {
|
||||
|
||||
fun getLocationName() = getCityOrNull()?.name ?: Constants.spyHideout
|
||||
|
||||
fun levelUpSpy() {
|
||||
//TODO: Make the spy level cap dependent on some unique
|
||||
if (rank >= 3) return
|
||||
addNotification("Your spy [$name] has leveled up!")
|
||||
rank++
|
||||
fun levelUpSpy(amount: Int = 1) {
|
||||
if (rank >= civInfo.gameInfo.ruleset.modOptions.constants.maxSpyLevel) return
|
||||
val ranksToLevelUp = amount.coerceAtMost(civInfo.gameInfo.ruleset.modOptions.constants.maxSpyLevel - rank)
|
||||
|
||||
if (ranksToLevelUp == 1) addNotification("Your spy [$name] has leveled up!")
|
||||
else addNotification("Your spy [$name] has leveled up [$ranksToLevelUp] times!")
|
||||
rank += ranksToLevelUp
|
||||
}
|
||||
|
||||
/** Zero-based modifier expressing shift of probabilities from Spy Rank
|
||||
|
@ -858,7 +858,7 @@ object UniqueTriggerActivation {
|
||||
if (!civInfo.gameInfo.isEspionageEnabled()) return null
|
||||
|
||||
return {
|
||||
civInfo.espionageManager.spyList.forEach { it.levelUpSpy() }
|
||||
civInfo.espionageManager.spyList.forEach { it.levelUpSpy(unique.params[1].toInt()) }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
@ -787,7 +787,7 @@ enum class UniqueType(
|
||||
OneTimeRevealCrudeMap("From a randomly chosen tile [positiveAmount] tiles away from the ruins, reveal tiles up to [positiveAmount] tiles away with [positiveAmount]% chance", UniqueTarget.Ruins),
|
||||
OneTimeGlobalAlert("Triggers the following global alert: [comment]", UniqueTarget.Triggerable), // used in Policy
|
||||
OneTimeGlobalSpiesWhenEnteringEra("Every major Civilization gains a spy once a civilization enters this era", UniqueTarget.Era),
|
||||
OneTimeSpiesLevelUp("Promotes all spies", UniqueTarget.Triggerable), // used in Policies, Buildings
|
||||
OneTimeSpiesLevelUp("Promotes all spies [amount] time(s)", UniqueTarget.Triggerable), // used in Policies, Buildings
|
||||
OneTimeGainSpy("Gain an extra spy", UniqueTarget.Triggerable), // used in Wonders
|
||||
|
||||
OneTimeUnitHeal("Heal this unit by [positiveAmount] HP", UniqueTarget.UnitTriggerable),
|
||||
|
@ -85,7 +85,7 @@ class EspionageOverviewScreen(val civInfo: Civilization, val worldScreen: WorldS
|
||||
spySelectionTable.add(spy.name.toLabel())
|
||||
spySelectionTable.add(spy.rank.toLabel())
|
||||
spySelectionTable.add(spy.getLocationName().toLabel())
|
||||
val actionString = if (spy.action.showTurns && spy.turnsRemainingForAction != -1)
|
||||
val actionString = if (spy.action.showTurns)
|
||||
"[${spy.action.displayString}] ${spy.turnsRemainingForAction}${Fonts.turn}"
|
||||
else spy.action.displayString
|
||||
spySelectionTable.add(actionString.toLabel())
|
||||
@ -94,7 +94,7 @@ class EspionageOverviewScreen(val civInfo: Civilization, val worldScreen: WorldS
|
||||
moveSpyButton.onClick {
|
||||
onSpyClicked(moveSpyButton, spy)
|
||||
}
|
||||
moveSpyButton.onRightClick {
|
||||
moveSpyButton.onRightClick {
|
||||
onSpyRightClicked(spy)
|
||||
}
|
||||
if (!worldScreen.canChangeState || !spy.isAlive()) {
|
||||
@ -124,18 +124,18 @@ class EspionageOverviewScreen(val civInfo: Civilization, val worldScreen: WorldS
|
||||
// Then add all cities
|
||||
|
||||
val sortedCities = civInfo.gameInfo.getCities()
|
||||
.filter { civInfo.hasExplored(it.getCenterTile()) }
|
||||
.sortedWith(
|
||||
compareBy<City> {
|
||||
it.civ != civInfo
|
||||
}.thenBy {
|
||||
it.civ.isCityState()
|
||||
}.thenBy(collator) {
|
||||
it.civ.civName.tr(hideIcons = true)
|
||||
}.thenBy(collator) {
|
||||
it.name.tr(hideIcons = true)
|
||||
}
|
||||
)
|
||||
.filter { civInfo.hasExplored(it.getCenterTile()) }
|
||||
.sortedWith(
|
||||
compareBy<City> {
|
||||
it.civ != civInfo
|
||||
}.thenBy {
|
||||
it.civ.isCityState()
|
||||
}.thenBy(collator) {
|
||||
it.civ.civName.tr(hideIcons = true)
|
||||
}.thenBy(collator) {
|
||||
it.name.tr(hideIcons = true)
|
||||
}
|
||||
)
|
||||
for (city in sortedCities) {
|
||||
addCityToSelectionTable(city)
|
||||
}
|
||||
@ -143,7 +143,7 @@ class EspionageOverviewScreen(val civInfo: Civilization, val worldScreen: WorldS
|
||||
|
||||
private fun addCityToSelectionTable(city: City) {
|
||||
citySelectionTable.add(ImageGetter.getNationPortrait(city.civ.nation, 30f))
|
||||
.padLeft(20f)
|
||||
.padLeft(20f)
|
||||
val label = city.name.toLabel(hideIcons = true)
|
||||
label.onClick {
|
||||
worldScreen.game.popScreen() // If a detour to this screen (i.e. not directly from worldScreen) is made possible, use resetToWorldScreen instead
|
||||
@ -152,7 +152,7 @@ class EspionageOverviewScreen(val civInfo: Civilization, val worldScreen: WorldS
|
||||
citySelectionTable.add(label).fill()
|
||||
citySelectionTable.add(getSpyIcons(manager.getSpiesInCity(city)))
|
||||
|
||||
val spy = civInfo.espionageManager.getSpyAssignedToCity(city)
|
||||
val spy = civInfo.espionageManager.getSpyAssignedToCity(city)
|
||||
if (city.civ.isCityState() && spy != null && spy.canDoCoup()) {
|
||||
val coupButton = CoupButton(city, spy.action == SpyAction.Coup)
|
||||
citySelectionTable.add(coupButton)
|
||||
@ -164,20 +164,31 @@ class EspionageOverviewScreen(val civInfo: Civilization, val worldScreen: WorldS
|
||||
}
|
||||
|
||||
private fun getSpyIcon(spy: Spy) = Table().apply {
|
||||
add (ImageGetter.getImage("OtherIcons/Spy_White").apply {
|
||||
add(ImageGetter.getImage("OtherIcons/Spy_White").apply {
|
||||
color = Color.WHITE
|
||||
}).size(30f)
|
||||
val color = when(spy.rank) {
|
||||
fun getColor(rank: Int): Color = when (rank) {
|
||||
1 -> Color.BROWN
|
||||
2 -> Color.LIGHT_GRAY
|
||||
3 -> Color.GOLD
|
||||
else -> return@apply
|
||||
else -> Color.GOLD
|
||||
}
|
||||
|
||||
// If we have 10 or more ranks, display them with a bigger star
|
||||
if (spy.rank >= 10) {
|
||||
val star = ImageGetter.getImage("OtherIcons/Star")
|
||||
star.color = getColor(spy.rank / 10)
|
||||
add(star).size(20f).pad(3f)
|
||||
}
|
||||
|
||||
val color = getColor(spy.rank)
|
||||
val starTable = Table()
|
||||
repeat(spy.rank) {
|
||||
// Create a grid of up to 9 stars
|
||||
repeat(spy.rank % 10) {
|
||||
val star = ImageGetter.getImage("OtherIcons/Star")
|
||||
star.color = color
|
||||
starTable.add(star).size(8f).pad(1f).row()
|
||||
starTable.add(star).size(8f).pad(1f)
|
||||
if (it % 3 == 2)
|
||||
starTable.row()
|
||||
}
|
||||
add(starTable).center().padLeft(-4f)
|
||||
|
||||
@ -199,12 +210,13 @@ class EspionageOverviewScreen(val civInfo: Civilization, val worldScreen: WorldS
|
||||
}
|
||||
|
||||
private abstract inner class SpyCityActionButton : Button(SmallButtonStyle()) {
|
||||
open fun setDirection(align: Int) { }
|
||||
open fun setDirection(align: Int) {}
|
||||
}
|
||||
|
||||
// city == null is interpreted as 'spy hideout'
|
||||
private inner class MoveToCityButton(city: City?) : SpyCityActionButton() {
|
||||
val arrow = ImageGetter.getArrowImage(Align.left)
|
||||
|
||||
init {
|
||||
arrow.setSize(24f)
|
||||
add(arrow).size(24f)
|
||||
@ -251,7 +263,7 @@ class EspionageOverviewScreen(val civInfo: Civilization, val worldScreen: WorldS
|
||||
worldScreen.game.popScreen()
|
||||
worldScreen.shouldUpdate = true
|
||||
}
|
||||
|
||||
|
||||
private fun resetSelection() {
|
||||
selectedSpy = null
|
||||
selectedSpyButton?.label?.setText("Move".tr())
|
||||
@ -262,6 +274,7 @@ class EspionageOverviewScreen(val civInfo: Civilization, val worldScreen: WorldS
|
||||
|
||||
private inner class CoupButton(city: City, isCurrentAction: Boolean) : SpyCityActionButton() {
|
||||
val fist = ImageGetter.getStatIcon("Resistance")
|
||||
|
||||
init {
|
||||
fist.setSize(24f)
|
||||
add(fist).size(24f)
|
||||
@ -271,7 +284,7 @@ class EspionageOverviewScreen(val civInfo: Civilization, val worldScreen: WorldS
|
||||
onClick {
|
||||
val spy = selectedSpy!!
|
||||
if (!isCurrentAction) {
|
||||
ConfirmPopup(this@EspionageOverviewScreen,
|
||||
ConfirmPopup(this@EspionageOverviewScreen,
|
||||
"Do you want to stage a coup in [${city.civ.civName}] with a " +
|
||||
"[${(selectedSpy!!.getCoupChanceOfSuccess(false) * 100f).toInt()}]% " +
|
||||
"chance of success?", "Stage Coup") {
|
||||
|
Reference in New Issue
Block a user