From 3c1f0f7814ff1bf8c37434b0329311d615065bfa Mon Sep 17 00:00:00 2001 From: Xander Lenstra <71121390+xlenstra@users.noreply.github.com> Date: Fri, 23 Jun 2023 07:50:56 +0200 Subject: [PATCH] Spies in cities that are captured or destroyed now go to the hideout (#9632) * Spies in cities that are captured or destroyed now go home * Turned spy flee reason string into enum --- .../jsons/translations/template.properties | 4 +++ core/src/com/unciv/logic/city/City.kt | 5 +++- .../city/managers/CityEspionageManager.kt | 27 +++++++++++++++++++ .../managers/CityInfoConquestFunctions.kt | 12 ++++----- .../unciv/logic/civilization/Notification.kt | 1 + 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index 11380190cd..03b3d935a8 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -1658,6 +1658,10 @@ Spy Hideout = Spy present = Move = +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. = +Due to the chaos ensuing in [cityName], your spy [spyname] has fled back to our hideout. = + # Promotions Pick promotion = diff --git a/core/src/com/unciv/logic/city/City.kt b/core/src/com/unciv/logic/city/City.kt index f567ddba02..ff320a173f 100644 --- a/core/src/com/unciv/logic/city/City.kt +++ b/core/src/com/unciv/logic/city/City.kt @@ -8,6 +8,7 @@ import com.unciv.logic.city.managers.CityExpansionManager import com.unciv.logic.city.managers.CityInfoConquestFunctions import com.unciv.logic.city.managers.CityPopulationManager import com.unciv.logic.city.managers.CityReligionManager +import com.unciv.logic.city.managers.SpyFleeReason import com.unciv.logic.civilization.Civilization import com.unciv.logic.civilization.diplomacy.DiplomacyFlags import com.unciv.logic.map.TileMap @@ -445,7 +446,8 @@ class City : IsPartOfGameInfoSerialization { // unless, of course, they are captured by a one-city-challenger. if (!canBeDestroyed() && !overrideSafeties) return - for (airUnit in getCenterTile().airUnits.toList()) airUnit.destroy() //Destroy planes stationed in city + // Destroy planes stationed in city + for (airUnit in getCenterTile().airUnits.toList()) airUnit.destroy() // The relinquish ownership MUST come before removing the city, // because it updates the city stats which assumes there is a capital, so if you remove the capital it crashes @@ -469,6 +471,7 @@ class City : IsPartOfGameInfoSerialization { unit.movement.teleportToClosestMoveableTile() } + espionage.removeAllPresentSpies(SpyFleeReason.CityDestroyed) // Update proximity rankings for all civs for (otherCiv in civ.gameInfo.getAliveMajorCivs()) { diff --git a/core/src/com/unciv/logic/city/managers/CityEspionageManager.kt b/core/src/com/unciv/logic/city/managers/CityEspionageManager.kt index 7dc3ee52e9..2e02fd6738 100644 --- a/core/src/com/unciv/logic/city/managers/CityEspionageManager.kt +++ b/core/src/com/unciv/logic/city/managers/CityEspionageManager.kt @@ -3,6 +3,15 @@ package com.unciv.logic.city.managers 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.Spy + +enum class SpyFleeReason { + CityDestroyed, + CityCaptured, + Other +} class CityEspionageManager : IsPartOfGameInfoSerialization{ @Transient @@ -20,4 +29,22 @@ class CityEspionageManager : IsPartOfGameInfoSerialization{ return civInfo.espionageManager.spyList.any { it.location == city.id } } + private fun getAllStationedSpies(): List { + return city.civ.gameInfo.civilizations.flatMap { civ -> + civ.espionageManager.spyList.filter { it.location == city.id } + } + } + + fun removeAllPresentSpies(reason: SpyFleeReason) { + for (spy in getAllStationedSpies()) { + val owningCiv = spy.civInfo + 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.CityCaptured -> "After the city of [${city.name}] was conquered, 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." + } + owningCiv.addNotification(notificationString, city.location, NotificationCategory.Espionage, NotificationIcon.Spy) + spy.location = null + } + } } diff --git a/core/src/com/unciv/logic/city/managers/CityInfoConquestFunctions.kt b/core/src/com/unciv/logic/city/managers/CityInfoConquestFunctions.kt index ab8ce4d33c..125ddaf602 100644 --- a/core/src/com/unciv/logic/city/managers/CityInfoConquestFunctions.kt +++ b/core/src/com/unciv/logic/city/managers/CityInfoConquestFunctions.kt @@ -93,7 +93,7 @@ class CityInfoConquestFunctions(val city: City){ /** Function for stuff that should happen on any capture, be it puppet, annex or liberate. * Stuff that should happen any time a city is moved between civs, so also when trading, - * should go in `this.moveToCiv()`, which this function also calls. + * should go in `this.moveToCiv()`, which is called by `this.conquerCity()`. */ private fun conquerCity(conqueringCiv: Civilization, conqueredCiv: Civilization, receivingCiv: Civilization) { val goldPlundered = getGoldForCapturingCity(conqueringCiv) @@ -111,20 +111,20 @@ class CityInfoConquestFunctions(val city: City){ Battle.destroyIfDefeated(conqueredCiv, conqueringCiv) health = getMaxHealth() / 2 // I think that cities recover to half health when conquered? - if (population.population > 1) population.addPopulation(-1 - population.population / 4) // so from 2-4 population, remove 1, from 5-8, remove 2, etc. + if (population.population > 1) + population.addPopulation(-1 - population.population / 4) // so from 2-4 population, remove 1, from 5-8, remove 2, etc. reassignAllPopulation() if (!reconqueredCityWhileStillInResistance && foundingCiv != receivingCiv.civName) { // add resistance - setFlag( - CityFlags.Resistance, - population.population // I checked, and even if you puppet there's resistance for conquering - ) + // I checked, and even if you puppet there's resistance for conquering + setFlag(CityFlags.Resistance, population.population) } else { // reconquering or liberating city in resistance so eliminate it removeFlag(CityFlags.Resistance) } + espionage.removeAllPresentSpies(SpyFleeReason.CityCaptured) } } diff --git a/core/src/com/unciv/logic/civilization/Notification.kt b/core/src/com/unciv/logic/civilization/Notification.kt index 50958f4abf..0bdf654421 100644 --- a/core/src/com/unciv/logic/civilization/Notification.kt +++ b/core/src/com/unciv/logic/civilization/Notification.kt @@ -48,6 +48,7 @@ enum class NotificationCategory{ Units, War, Religion, + Espionage, Cities ; companion object {