Resolved #12546 - Spies assigned to cities moved to other civs are returned to hideout

This commit is contained in:
yairm210
2024-12-02 19:17:51 +02:00
parent b1f1998f11
commit cff67ddb5b
6 changed files with 18 additions and 3 deletions

View File

@ -1847,6 +1847,7 @@ Do you want to stage a coup in [civName] with a [percent]% chance of success? =
# Spy fleeing city # Spy fleeing city
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. =
After the city of [cityName] was taken over, 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. =
# Promotions # Promotions

View File

@ -273,6 +273,10 @@ class CityConquestFunctions(val city: City) {
// Remove their free buildings from this city and remove free buildings provided by the city from their cities // Remove their free buildings from this city and remove free buildings provided by the city from their cities
removeBuildingsOnMoveToCiv() removeBuildingsOnMoveToCiv()
// catch-all - should ideally not happen as we catch the individual cases with an appropriate notification
city.espionage.removeAllPresentSpies(SpyFleeReason.Other)
// Place palace for newCiv if this is the only city they have. // Place palace for newCiv if this is the only city they have.
if (newCiv.cities.size == 1) newCiv.moveCapitalTo(city, null) if (newCiv.cities.size == 1) newCiv.moveCapitalTo(city, null)

View File

@ -3,13 +3,13 @@ package com.unciv.logic.city.managers
import com.unciv.logic.IsPartOfGameInfoSerialization import com.unciv.logic.IsPartOfGameInfoSerialization
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.NotificationCategory
import com.unciv.logic.civilization.NotificationIcon
import com.unciv.models.Spy import com.unciv.models.Spy
enum class SpyFleeReason { enum class SpyFleeReason {
CityDestroyed, CityDestroyed,
CityCaptured, CityCaptured,
CityBought,
CityTakenOverByMarriage,
Other Other
} }
@ -38,6 +38,7 @@ class CityEspionageManager : IsPartOfGameInfoSerialization {
val notificationString = when (reason) { val notificationString = when (reason) {
SpyFleeReason.CityDestroyed -> "After the city of [${city.name}] was destroyed, your spy [${spy.name}] has fled back to our hideout." SpyFleeReason.CityDestroyed -> "After the city of [${city.name}] was destroyed, your spy [${spy.name}] has fled back to our hideout."
SpyFleeReason.CityCaptured -> "After the city of [${city.name}] was conquered, your spy [${spy.name}] has fled back to our hideout." SpyFleeReason.CityCaptured -> "After the city of [${city.name}] was conquered, your spy [${spy.name}] has fled back to our hideout."
SpyFleeReason.CityBought, SpyFleeReason.CityTakenOverByMarriage -> "After the city of [${city.name}] was taken over, your spy [${spy.name}] has fled back to our hideout."
else -> "Due to the chaos ensuing in [${city.name}], your spy [${spy.name}] has fled back to our hideout." else -> "Due to the chaos ensuing in [${city.name}], your spy [${spy.name}] has fled back to our hideout."
} }
spy.addNotification(notificationString) spy.addNotification(notificationString)

View File

@ -126,7 +126,7 @@ class CityTurnManager(val city: City) {
.sumOf { it.params[0].toInt() - 1 } .sumOf { it.params[0].toInt() - 1 }
if (city.population.population <= removedPopulation) { if (city.population.population <= removedPopulation) {
city.espionage.removeAllPresentSpies(SpyFleeReason.CityCaptured) city.espionage.removeAllPresentSpies(SpyFleeReason.Other)
city.civ.addNotification( city.civ.addNotification(
"[${city.name}] has been razed to the ground!", "[${city.name}] has been razed to the ground!",
city.location, NotificationCategory.General, city.location, NotificationCategory.General,

View File

@ -3,6 +3,7 @@ package com.unciv.logic.civilization.diplomacy
import com.unciv.Constants import com.unciv.Constants
import com.unciv.logic.automation.civilization.NextTurnAutomation import com.unciv.logic.automation.civilization.NextTurnAutomation
import com.unciv.logic.battle.CityCombatant import com.unciv.logic.battle.CityCombatant
import com.unciv.logic.city.managers.SpyFleeReason
import com.unciv.logic.civilization.AlertType import com.unciv.logic.civilization.AlertType
import com.unciv.logic.civilization.CivFlags import com.unciv.logic.civilization.CivFlags
import com.unciv.logic.civilization.Civilization import com.unciv.logic.civilization.Civilization
@ -371,19 +372,23 @@ class CityStateFunctions(val civInfo: Civilization) {
return return
otherCiv.addGold(-getDiplomaticMarriageCost()) otherCiv.addGold(-getDiplomaticMarriageCost())
val notificationLocation = civInfo.getCapital()!!.location val notificationLocation = civInfo.getCapital()!!.location
otherCiv.addNotification("We have married into the ruling family of [${civInfo.civName}], bringing them under our control.", otherCiv.addNotification("We have married into the ruling family of [${civInfo.civName}], bringing them under our control.",
notificationLocation, notificationLocation,
NotificationCategory.Diplomacy, civInfo.civName, NotificationCategory.Diplomacy, civInfo.civName,
NotificationIcon.Diplomacy, otherCiv.civName) NotificationIcon.Diplomacy, otherCiv.civName)
for (civ in civInfo.gameInfo.civilizations.filter { it != otherCiv }) for (civ in civInfo.gameInfo.civilizations.filter { it != otherCiv })
civ.addNotification("[${otherCiv.civName}] has married into the ruling family of [${civInfo.civName}], bringing them under their control.", civ.addNotification("[${otherCiv.civName}] has married into the ruling family of [${civInfo.civName}], bringing them under their control.",
notificationLocation, notificationLocation,
NotificationCategory.Diplomacy, civInfo.civName, NotificationCategory.Diplomacy, civInfo.civName,
NotificationIcon.Diplomacy, otherCiv.civName) NotificationIcon.Diplomacy, otherCiv.civName)
for (unit in civInfo.units.getCivUnits()) for (unit in civInfo.units.getCivUnits())
unit.gift(otherCiv) unit.gift(otherCiv)
// Make sure this CS can never be liberated // Make sure this CS can never be liberated
civInfo.gameInfo.getCities().filter { civInfo.gameInfo.getCities().filter {
it.foundingCiv == civInfo.civName it.foundingCiv == civInfo.civName
@ -393,6 +398,7 @@ class CityStateFunctions(val civInfo: Civilization) {
} }
for (city in civInfo.cities) { for (city in civInfo.cities) {
city.espionage.removeAllPresentSpies(SpyFleeReason.CityTakenOverByMarriage)
city.moveToCiv(otherCiv) city.moveToCiv(otherCiv)
city.isPuppet = true // Human players get a popup that allows them to annex instead city.isPuppet = true // Human players get a popup that allows them to annex instead
} }

View File

@ -1,6 +1,7 @@
package com.unciv.logic.trade package com.unciv.logic.trade
import com.unciv.Constants import com.unciv.Constants
import com.unciv.logic.city.managers.SpyFleeReason
import com.unciv.logic.civilization.AlertType import com.unciv.logic.civilization.AlertType
import com.unciv.logic.civilization.Civilization import com.unciv.logic.civilization.Civilization
import com.unciv.logic.civilization.PopupAlert import com.unciv.logic.civilization.PopupAlert
@ -106,6 +107,8 @@ class TradeLogic(val ourCivilization: Civilization, val otherCivilization: Civil
} }
TradeOfferType.City -> { TradeOfferType.City -> {
val city = from.cities.first { it.id == offer.name } val city = from.cities.first { it.id == offer.name }
city.espionage.removeAllPresentSpies(SpyFleeReason.CityBought)
city.moveToCiv(to) city.moveToCiv(to)
city.getCenterTile().getUnits().toList() city.getCenterTile().getUnits().toList()
.forEach { it.movement.teleportToClosestMoveableTile() } .forEach { it.movement.teleportToClosestMoveableTile() }