mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-26 21:35:14 -04:00
Spies now occasionally steal technologies (#9629)
* Spies now occasionally steal technologies * Updated the UI so it doesn't show a turn counter when that cannot be provided * Implemented changes discussed in reveiw comments * Renamed variable --------- Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
This commit is contained in:
parent
3c1f0f7814
commit
47e93a86bf
@ -927,8 +927,6 @@ Your [ourUnit] captured an enemy [theirUnit]! =
|
|||||||
Your [ourUnit] plundered [amount] [Stat] from [theirUnit] =
|
Your [ourUnit] plundered [amount] [Stat] from [theirUnit] =
|
||||||
We have captured a barbarian encampment and recovered [goldAmount] gold! =
|
We have captured a barbarian encampment and recovered [goldAmount] gold! =
|
||||||
An enemy [unitType] has joined us! =
|
An enemy [unitType] has joined us! =
|
||||||
After an unknown civilization entered the [eraName], we have recruited [spyName] as a spy! =
|
|
||||||
We have recruited [spyName] as a spy! =
|
|
||||||
[unitName] can be promoted! =
|
[unitName] can be promoted! =
|
||||||
|
|
||||||
# This might be needed for a rewrite of Germany's unique - see #7376
|
# This might be needed for a rewrite of Germany's unique - see #7376
|
||||||
@ -1650,14 +1648,21 @@ Enhancing religion =
|
|||||||
Enhanced religion =
|
Enhanced religion =
|
||||||
|
|
||||||
# Espionage
|
# Espionage
|
||||||
# As espionage is WIP and these strings are currently not shown in-game,
|
# As espionage is WIP, these strings are currently not shown in-game,
|
||||||
# feel free to not translate these strings for now
|
# so feel free to not translate these strings for now
|
||||||
|
|
||||||
Spy =
|
Spy =
|
||||||
Spy Hideout =
|
Spy Hideout =
|
||||||
Spy present =
|
Spy present =
|
||||||
Move =
|
Move =
|
||||||
|
|
||||||
|
After an unknown civilization entered the [eraName], we have recruited [spyName] as a spy! =
|
||||||
|
We have recruited [spyName] as a spy! =
|
||||||
|
A spy from [civilization] stole the Technology [techName] from [cityName]! =
|
||||||
|
An unidentified spy stole the Technology [techName] from [cityName]! =
|
||||||
|
Your spy [name] stole the Technology [techName] from [cityName]! =
|
||||||
|
Your spy [name] cannot steal any more techs from [civilization] as we've already researched all the technology they know! =
|
||||||
|
|
||||||
After the city of [cityName] was destroyed, your spy [spyName] has fled back to our hideout. =
|
After the city of [cityName] was destroyed, your spy [spyName] has fled back to our hideout. =
|
||||||
After the city of [cityName] was conquered, your spy [spyName] has fled back to our hideout. =
|
After the city of [cityName] was conquered, your spy [spyName] has fled back to our hideout. =
|
||||||
Due to the chaos ensuing in [cityName], your spy [spyname] has fled back to our hideout. =
|
Due to the chaos ensuing in [cityName], your spy [spyname] has fled back to our hideout. =
|
||||||
|
@ -13,7 +13,7 @@ enum class SpyFleeReason {
|
|||||||
Other
|
Other
|
||||||
}
|
}
|
||||||
|
|
||||||
class CityEspionageManager : IsPartOfGameInfoSerialization{
|
class CityEspionageManager : IsPartOfGameInfoSerialization {
|
||||||
@Transient
|
@Transient
|
||||||
lateinit var city: City
|
lateinit var city: City
|
||||||
|
|
||||||
|
@ -759,13 +759,13 @@ class Civilization : IsPartOfGameInfoSerialization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addNotification(text: String, location: Vector2, category:NotificationCategory, vararg notificationIcons: String) {
|
fun addNotification(text: String, location: Vector2, category: NotificationCategory, vararg notificationIcons: String) {
|
||||||
addNotification(text, LocationAction(location), category, *notificationIcons)
|
addNotification(text, LocationAction(location), category, *notificationIcons)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addNotification(text: String, category:NotificationCategory, vararg notificationIcons: String) = addNotification(text, null, category, *notificationIcons)
|
fun addNotification(text: String, category: NotificationCategory, vararg notificationIcons: String) = addNotification(text, null, category, *notificationIcons)
|
||||||
|
|
||||||
fun addNotification(text: String, action: NotificationAction?, category:NotificationCategory, vararg notificationIcons: String) {
|
fun addNotification(text: String, action: NotificationAction?, category: NotificationCategory, vararg notificationIcons: String) {
|
||||||
if (playerType == PlayerType.AI) return // no point in lengthening the saved game info if no one will read it
|
if (playerType == PlayerType.AI) return // no point in lengthening the saved game info if no one will read it
|
||||||
val arrayList = notificationIcons.toCollection(ArrayList())
|
val arrayList = notificationIcons.toCollection(ArrayList())
|
||||||
notifications.add(Notification(text, arrayList,
|
notifications.add(Notification(text, arrayList,
|
||||||
|
@ -40,7 +40,7 @@ object NotificationIcon {
|
|||||||
const val War = "OtherIcons/Pillage"
|
const val War = "OtherIcons/Pillage"
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class NotificationCategory{
|
enum class NotificationCategory {
|
||||||
General,
|
General,
|
||||||
Trade,
|
Trade,
|
||||||
Diplomacy,
|
Diplomacy,
|
||||||
@ -69,7 +69,7 @@ open class Notification() : IsPartOfGameInfoSerialization {
|
|||||||
var action: NotificationAction? = null
|
var action: NotificationAction? = null
|
||||||
var category: String = NotificationCategory.General.name
|
var category: String = NotificationCategory.General.name
|
||||||
|
|
||||||
constructor(text: String, notificationIcons: ArrayList<String>, action: NotificationAction?, category:NotificationCategory) : this() {
|
constructor(text: String, notificationIcons: ArrayList<String>, action: NotificationAction?, category: NotificationCategory) : this() {
|
||||||
this.text = text
|
this.text = text
|
||||||
this.icons = notificationIcons
|
this.icons = notificationIcons
|
||||||
this.action = action
|
this.action = action
|
||||||
|
@ -1,106 +1,21 @@
|
|||||||
package com.unciv.logic.civilization.managers
|
package com.unciv.logic.civilization.managers
|
||||||
|
|
||||||
import com.unciv.Constants
|
|
||||||
import com.unciv.logic.IsPartOfGameInfoSerialization
|
import com.unciv.logic.IsPartOfGameInfoSerialization
|
||||||
import com.unciv.logic.city.City
|
|
||||||
import com.unciv.logic.civilization.Civilization
|
import com.unciv.logic.civilization.Civilization
|
||||||
|
import com.unciv.logic.map.tile.Tile
|
||||||
|
import com.unciv.models.Spy
|
||||||
|
|
||||||
enum class SpyAction(val stringName: String) {
|
|
||||||
None("None"),
|
|
||||||
Moving("Moving"),
|
|
||||||
EstablishNetwork("Establishing Network"),
|
|
||||||
StealingTech("Stealing Tech"),
|
|
||||||
RiggingElections("Rigging Elections"),
|
|
||||||
CounterIntelligence("Conducting Counter-intelligence")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Spy() : IsPartOfGameInfoSerialization {
|
|
||||||
// `location == null` means that the spy is in its hideout
|
|
||||||
var location: String? = null
|
|
||||||
lateinit var name: String
|
|
||||||
var timeTillActionFinish = 0
|
|
||||||
var action = SpyAction.None
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
lateinit var civInfo: Civilization
|
|
||||||
|
|
||||||
constructor(name: String) : this() {
|
|
||||||
this.name = name
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clone(): Spy {
|
|
||||||
val toReturn = Spy(name)
|
|
||||||
toReturn.location = location
|
|
||||||
toReturn.timeTillActionFinish = timeTillActionFinish
|
|
||||||
toReturn.action = action
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setTransients(civInfo: Civilization) {
|
|
||||||
this.civInfo = civInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
fun endTurn() {
|
|
||||||
--timeTillActionFinish
|
|
||||||
if (timeTillActionFinish != 0) return
|
|
||||||
|
|
||||||
when (action) {
|
|
||||||
SpyAction.Moving -> {
|
|
||||||
action = SpyAction.EstablishNetwork
|
|
||||||
timeTillActionFinish = 3 // Dependent on cultural familiarity level if that is ever implemented
|
|
||||||
}
|
|
||||||
SpyAction.EstablishNetwork -> {
|
|
||||||
val location = getLocation()!! // This should be impossible to reach as going to the hideout sets your action to None.
|
|
||||||
action =
|
|
||||||
if (location.civ.isCityState()) {
|
|
||||||
SpyAction.RiggingElections
|
|
||||||
} else if (location.civ == civInfo) {
|
|
||||||
SpyAction.CounterIntelligence
|
|
||||||
} else {
|
|
||||||
SpyAction.StealingTech
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
++timeTillActionFinish // Not implemented yet, so don't do anything
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun moveTo(city: City?) {
|
|
||||||
location = city?.id
|
|
||||||
if (city == null) { // Moving to spy hideout
|
|
||||||
action = SpyAction.None
|
|
||||||
timeTillActionFinish = 0
|
|
||||||
return
|
|
||||||
}
|
|
||||||
action = SpyAction.Moving
|
|
||||||
timeTillActionFinish = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isSetUp() = action !in listOf(SpyAction.Moving, SpyAction.None, SpyAction.EstablishNetwork)
|
|
||||||
|
|
||||||
fun getLocation(): City? {
|
|
||||||
return civInfo.gameInfo.getCities().firstOrNull { it.id == location }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLocationName(): String {
|
|
||||||
return getLocation()?.name ?: Constants.spyHideout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class EspionageManager : IsPartOfGameInfoSerialization {
|
class EspionageManager : IsPartOfGameInfoSerialization {
|
||||||
|
|
||||||
var spyCount = 0
|
|
||||||
var spyList = mutableListOf<Spy>()
|
var spyList = mutableListOf<Spy>()
|
||||||
var erasSpyEarnedFor = mutableListOf<String>()
|
val erasSpyEarnedFor = mutableSetOf<String>()
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
lateinit var civInfo: Civilization
|
lateinit var civInfo: Civilization
|
||||||
|
|
||||||
fun clone(): EspionageManager {
|
fun clone(): EspionageManager {
|
||||||
val toReturn = EspionageManager()
|
val toReturn = EspionageManager()
|
||||||
toReturn.spyCount = spyCount
|
|
||||||
toReturn.spyList.addAll(spyList.map { it.clone() })
|
toReturn.spyList.addAll(spyList.map { it.clone() })
|
||||||
toReturn.erasSpyEarnedFor.addAll(erasSpyEarnedFor)
|
toReturn.erasSpyEarnedFor.addAll(erasSpyEarnedFor)
|
||||||
return toReturn
|
return toReturn
|
||||||
@ -130,7 +45,23 @@ class EspionageManager : IsPartOfGameInfoSerialization {
|
|||||||
val newSpy = Spy(spyName)
|
val newSpy = Spy(spyName)
|
||||||
newSpy.setTransients(civInfo)
|
newSpy.setTransients(civInfo)
|
||||||
spyList.add(newSpy)
|
spyList.add(newSpy)
|
||||||
++spyCount
|
|
||||||
return spyName
|
return spyName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTilesVisibleViaSpies(): Sequence<Tile> {
|
||||||
|
return spyList.asSequence()
|
||||||
|
.filter { it.isSetUp() }
|
||||||
|
.mapNotNull { it.getLocation() }
|
||||||
|
.flatMap { it.getCenterTile().getTilesInDistance(1) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTechsToSteal(otherCiv: Civilization): Set<String> {
|
||||||
|
val techsToSteal = mutableSetOf<String>()
|
||||||
|
for (tech in otherCiv.tech.techsResearched) {
|
||||||
|
if (civInfo.tech.isResearched(tech)) continue
|
||||||
|
if (!civInfo.tech.canBeResearched(tech)) continue
|
||||||
|
techsToSteal.add(tech)
|
||||||
|
}
|
||||||
|
return techsToSteal
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,11 +182,7 @@ class CivInfoTransientCache(val civInfo: Civilization) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (spy in civInfo.espionageManager.spyList) {
|
newViewableTiles.addAll(civInfo.espionageManager.getTilesVisibleViaSpies())
|
||||||
val spyCity = spy.getLocation() ?: continue
|
|
||||||
if (!spy.isSetUp()) continue // Can't see cities when you haven't set up yet
|
|
||||||
newViewableTiles.addAll(spyCity.getCenterTile().getTilesInDistance(1))
|
|
||||||
}
|
|
||||||
|
|
||||||
civInfo.viewableTiles = newViewableTiles // to avoid concurrent modification problems
|
civInfo.viewableTiles = newViewableTiles // to avoid concurrent modification problems
|
||||||
}
|
}
|
||||||
|
164
core/src/com/unciv/models/Spy.kt
Normal file
164
core/src/com/unciv/models/Spy.kt
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
package com.unciv.models
|
||||||
|
|
||||||
|
import com.unciv.Constants
|
||||||
|
import com.unciv.logic.IsPartOfGameInfoSerialization
|
||||||
|
import com.unciv.logic.city.City
|
||||||
|
import com.unciv.logic.civilization.Civilization
|
||||||
|
import com.unciv.logic.civilization.NotificationCategory
|
||||||
|
import com.unciv.logic.civilization.NotificationIcon
|
||||||
|
import com.unciv.logic.civilization.managers.EspionageManager
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
|
||||||
|
enum class SpyAction(val displayString: String) {
|
||||||
|
None("None"),
|
||||||
|
Moving("Moving"),
|
||||||
|
EstablishNetwork("Establishing Network"),
|
||||||
|
Surveillance("Observing City"),
|
||||||
|
StealingTech("Stealing Tech"),
|
||||||
|
RiggingElections("Rigging Elections"),
|
||||||
|
CounterIntelligence("Conducting Counter-intelligence")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Spy() : IsPartOfGameInfoSerialization {
|
||||||
|
// `location == null` means that the spy is in its hideout
|
||||||
|
var location: String? = null
|
||||||
|
lateinit var name: String
|
||||||
|
var action = SpyAction.None
|
||||||
|
private set
|
||||||
|
var turnsRemainingForAction = 0
|
||||||
|
private set
|
||||||
|
private var progressTowardsStealingTech = 0
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
lateinit var civInfo: Civilization
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private lateinit var espionageManager: EspionageManager
|
||||||
|
|
||||||
|
constructor(name: String) : this() {
|
||||||
|
this.name = name
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clone(): Spy {
|
||||||
|
val toReturn = Spy(name)
|
||||||
|
toReturn.location = location
|
||||||
|
toReturn.action = action
|
||||||
|
toReturn.turnsRemainingForAction = turnsRemainingForAction
|
||||||
|
toReturn.progressTowardsStealingTech = progressTowardsStealingTech
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setTransients(civInfo: Civilization) {
|
||||||
|
this.civInfo = civInfo
|
||||||
|
this.espionageManager = civInfo.espionageManager
|
||||||
|
}
|
||||||
|
|
||||||
|
fun endTurn() {
|
||||||
|
when (action) {
|
||||||
|
SpyAction.None -> return
|
||||||
|
SpyAction.Moving -> {
|
||||||
|
--turnsRemainingForAction
|
||||||
|
if (turnsRemainingForAction > 0) return
|
||||||
|
|
||||||
|
action = SpyAction.EstablishNetwork
|
||||||
|
turnsRemainingForAction = 3 // Depending on cultural familiarity level if that is ever implemented
|
||||||
|
}
|
||||||
|
SpyAction.EstablishNetwork -> {
|
||||||
|
--turnsRemainingForAction
|
||||||
|
if (turnsRemainingForAction > 0) return
|
||||||
|
|
||||||
|
val location = getLocation()!! // This should never throw an exception, as going to the hideout sets your action to None.
|
||||||
|
if (location.civ.isCityState()) {
|
||||||
|
action = SpyAction.RiggingElections
|
||||||
|
} else if (location.civ == civInfo) {
|
||||||
|
action = SpyAction.CounterIntelligence
|
||||||
|
} else {
|
||||||
|
startStealingTech()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SpyAction.Surveillance -> {
|
||||||
|
if (!getLocation()!!.civ.isMajorCiv()) return
|
||||||
|
|
||||||
|
val stealableTechs = espionageManager.getTechsToSteal(getLocation()!!.civ)
|
||||||
|
if (stealableTechs.isEmpty()) return
|
||||||
|
action = SpyAction.StealingTech // There are new techs to steal!
|
||||||
|
}
|
||||||
|
SpyAction.StealingTech -> {
|
||||||
|
val stealableTechs = espionageManager.getTechsToSteal(getLocation()!!.civ)
|
||||||
|
if (stealableTechs.isEmpty()) {
|
||||||
|
action = SpyAction.Surveillance
|
||||||
|
turnsRemainingForAction = 0
|
||||||
|
val notificationString = "Your spy [$name] cannot steal any more techs from [${getLocation()!!.civ}] as we've already researched all the technology they know!"
|
||||||
|
civInfo.addNotification(notificationString, getLocation()!!.location, NotificationCategory.Espionage, NotificationIcon.Spy)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val techStealCost = stealableTechs.maxOfOrNull { civInfo.gameInfo.ruleset.technologies[it]!!.cost }!!
|
||||||
|
val progressThisTurn = getLocation()!!.cityStats.currentCityStats.science
|
||||||
|
progressTowardsStealingTech += progressThisTurn.toInt()
|
||||||
|
if (progressTowardsStealingTech > techStealCost) {
|
||||||
|
stealTech()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> return // Not implemented yet, so don't do anything
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startStealingTech() {
|
||||||
|
action = SpyAction.StealingTech
|
||||||
|
turnsRemainingForAction = 0
|
||||||
|
progressTowardsStealingTech = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stealTech() {
|
||||||
|
val city = getLocation()!!
|
||||||
|
val otherCiv = city.civ
|
||||||
|
val randomSeed = city.location.x * city.location.y + 123f * civInfo.gameInfo.turns
|
||||||
|
|
||||||
|
val stolenTech = espionageManager.getTechsToSteal(getLocation()!!.civ)
|
||||||
|
.randomOrNull(Random(randomSeed.toInt())) // Could be improved to for example steal the most expensive tech or the tech that has the least progress as of yet
|
||||||
|
if (stolenTech != null) {
|
||||||
|
civInfo.tech.addTechnology(stolenTech)
|
||||||
|
}
|
||||||
|
|
||||||
|
val spyDetected = Random(randomSeed.toInt()).nextInt(3)
|
||||||
|
val detectionString = when (spyDetected) {
|
||||||
|
0 -> "A spy from [${civInfo.civName}] stole the Technology [$stolenTech] from [$city]!"
|
||||||
|
1 -> "An unidentified spy stole the Technology [$stolenTech] from [$city]!"
|
||||||
|
else -> null // Not detected
|
||||||
|
}
|
||||||
|
if (detectionString != null)
|
||||||
|
otherCiv.addNotification(detectionString, city.location, NotificationCategory.Espionage, NotificationIcon.Spy)
|
||||||
|
|
||||||
|
civInfo.addNotification("Your spy [$name] stole the Technology [$stolenTech] from [$city]!", city.location,
|
||||||
|
NotificationCategory.Espionage,
|
||||||
|
NotificationIcon.Spy
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
startStealingTech()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun moveTo(city: City?) {
|
||||||
|
location = city?.id
|
||||||
|
if (city == null) { // Moving to spy hideout
|
||||||
|
action = SpyAction.None
|
||||||
|
turnsRemainingForAction = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
action = SpyAction.Moving
|
||||||
|
turnsRemainingForAction = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isSetUp() = action !in listOf(SpyAction.Moving, SpyAction.None, SpyAction.EstablishNetwork)
|
||||||
|
|
||||||
|
fun getLocation(): City? {
|
||||||
|
return civInfo.gameInfo.getCities().firstOrNull { it.id == location }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLocationName(): String {
|
||||||
|
return getLocation()?.name ?: Constants.spyHideout
|
||||||
|
}
|
||||||
|
}
|
@ -622,9 +622,9 @@ object UniqueTriggerActivation {
|
|||||||
otherCiv.espionageManager.erasSpyEarnedFor.add(currentEra)
|
otherCiv.espionageManager.erasSpyEarnedFor.add(currentEra)
|
||||||
if (otherCiv == civInfo || otherCiv.knows(civInfo))
|
if (otherCiv == civInfo || otherCiv.knows(civInfo))
|
||||||
// We don't tell which civilization entered the new era, as that is done in the notification directly above this one
|
// We don't tell which civilization entered the new era, as that is done in the notification directly above this one
|
||||||
otherCiv.addNotification("We have recruited [${spyName}] as a spy!", NotificationCategory.General, NotificationIcon.Spy)
|
otherCiv.addNotification("We have recruited [${spyName}] as a spy!", NotificationCategory.Espionage, NotificationIcon.Spy)
|
||||||
else
|
else
|
||||||
otherCiv.addNotification("After an unknown civilization entered the [${currentEra}], we have recruited [${spyName}] as a spy!", NotificationCategory.General, NotificationIcon.Spy)
|
otherCiv.addNotification("After an unknown civilization entered the [${currentEra}], we have recruited [${spyName}] as a spy!", NotificationCategory.Espionage, NotificationIcon.Spy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -225,8 +225,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
|||||||
UnitSupplyPerCity("[amount] Unit Supply per city", UniqueTarget.Global),
|
UnitSupplyPerCity("[amount] Unit Supply per city", UniqueTarget.Global),
|
||||||
FreeUnits("[amount] units cost no maintenance", UniqueTarget.Global),
|
FreeUnits("[amount] units cost no maintenance", UniqueTarget.Global),
|
||||||
UnitsInCitiesNoMaintenance("Units in cities cost no Maintenance", UniqueTarget.Global),
|
UnitsInCitiesNoMaintenance("Units in cities cost no Maintenance", UniqueTarget.Global),
|
||||||
// Acts as a trigger - this should be generalized somehow but the current setup does not allow this
|
// ToDo: Replace with "Free [unit] appears <upon discovering [tech]>"
|
||||||
// It would currently mean cycling through EVERY unique type to find ones with a specific conditional...
|
|
||||||
ReceiveFreeUnitWhenDiscoveringTech("Receive free [unit] when you discover [tech]", UniqueTarget.Global),
|
ReceiveFreeUnitWhenDiscoveringTech("Receive free [unit] when you discover [tech]", UniqueTarget.Global),
|
||||||
|
|
||||||
// Units entering Tiles
|
// Units entering Tiles
|
||||||
|
@ -5,7 +5,7 @@ import com.badlogic.gdx.files.FileHandle
|
|||||||
import com.unciv.json.fromJsonFile
|
import com.unciv.json.fromJsonFile
|
||||||
import com.unciv.json.json
|
import com.unciv.json.json
|
||||||
import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers
|
import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers
|
||||||
import com.unciv.logic.civilization.managers.SpyAction
|
import com.unciv.models.SpyAction
|
||||||
import com.unciv.models.metadata.BaseRuleset
|
import com.unciv.models.metadata.BaseRuleset
|
||||||
import com.unciv.models.metadata.LocaleCode
|
import com.unciv.models.metadata.LocaleCode
|
||||||
import com.unciv.models.ruleset.Belief
|
import com.unciv.models.ruleset.Belief
|
||||||
@ -127,7 +127,7 @@ object TranslationFileWriter {
|
|||||||
|
|
||||||
linesToTranslate += "\n\n#################### Lines from spy actions #######################\n"
|
linesToTranslate += "\n\n#################### Lines from spy actions #######################\n"
|
||||||
for (spyAction in SpyAction.values()) {
|
for (spyAction in SpyAction.values()) {
|
||||||
linesToTranslate += "$spyAction = "
|
linesToTranslate += "${spyAction.displayString} = "
|
||||||
}
|
}
|
||||||
|
|
||||||
linesToTranslate += "\n\n#################### Lines from diplomatic modifiers #######################\n"
|
linesToTranslate += "\n\n#################### Lines from diplomatic modifiers #######################\n"
|
||||||
|
@ -8,8 +8,8 @@ import com.badlogic.gdx.utils.Align
|
|||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.city.City
|
import com.unciv.logic.city.City
|
||||||
import com.unciv.logic.civilization.Civilization
|
import com.unciv.logic.civilization.Civilization
|
||||||
import com.unciv.logic.civilization.managers.Spy
|
import com.unciv.models.Spy
|
||||||
import com.unciv.logic.civilization.managers.SpyAction
|
import com.unciv.models.SpyAction
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
import com.unciv.ui.screens.pickerscreens.PickerScreen
|
import com.unciv.ui.screens.pickerscreens.PickerScreen
|
||||||
@ -71,8 +71,12 @@ class EspionageOverviewScreen(val civInfo: Civilization) : PickerScreen(true) {
|
|||||||
spySelectionTable.add(spy.name.toLabel()).pad(10f)
|
spySelectionTable.add(spy.name.toLabel()).pad(10f)
|
||||||
spySelectionTable.add(spy.getLocationName().toLabel()).pad(10f)
|
spySelectionTable.add(spy.getLocationName().toLabel()).pad(10f)
|
||||||
val actionString =
|
val actionString =
|
||||||
if (spy.action == SpyAction.None) SpyAction.None.stringName
|
when (spy.action) {
|
||||||
else "[${spy.action.stringName}] ${spy.timeTillActionFinish}${Fonts.turn}"
|
SpyAction.None, SpyAction.StealingTech, SpyAction.Surveillance -> spy.action.displayString
|
||||||
|
SpyAction.Moving, SpyAction.EstablishNetwork -> "[${spy.action.displayString}] ${spy.turnsRemainingForAction}${Fonts.turn}"
|
||||||
|
SpyAction.RiggingElections -> TODO()
|
||||||
|
SpyAction.CounterIntelligence -> TODO()
|
||||||
|
}
|
||||||
spySelectionTable.add(actionString.toLabel()).pad(10f)
|
spySelectionTable.add(actionString.toLabel()).pad(10f)
|
||||||
|
|
||||||
val moveSpyButton = "Move".toTextButton()
|
val moveSpyButton = "Move".toTextButton()
|
||||||
|
@ -153,7 +153,7 @@ class TechPolicyDiplomacyButtons(val worldScreen: WorldScreen) : Table(BaseScree
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateEspionageButton() {
|
private fun updateEspionageButton() {
|
||||||
if (viewingCiv.espionageManager.spyCount == 0) {
|
if (viewingCiv.espionageManager.spyList.isEmpty()) {
|
||||||
espionageButtonHolder.touchable = Touchable.disabled
|
espionageButtonHolder.touchable = Touchable.disabled
|
||||||
espionageButtonHolder.actor = null
|
espionageButtonHolder.actor = null
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user