Added spy steal tech timer (#11657)

This commit is contained in:
Oskar Niesen
2024-05-29 15:58:50 -05:00
committed by GitHub
parent d82669d26c
commit 498a64fa16
2 changed files with 49 additions and 30 deletions

View File

@ -13,23 +13,24 @@ import com.unciv.logic.civilization.managers.EspionageManager
import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueType
import kotlin.math.ceil
import kotlin.random.Random
enum class SpyAction(val displayString: String, val hasTurns: Boolean, internal val isSetUp: Boolean, private val isDoingWork: Boolean = false) {
None("None", false, false),
Moving("Moving", true, false, true),
EstablishNetwork("Establishing Network", true, false, true),
Surveillance("Observing City", false, true),
StealingTech("Stealing Tech", false, true, true),
RiggingElections("Rigging Elections", false, true) {
enum class SpyAction(val displayString: String, val hasCountdownTurns: Boolean, val showTurns: Boolean, internal val isSetUp: Boolean, private val isDoingWork: Boolean = false) {
None("None", false, false, false),
Moving("Moving", true, true, false, true),
EstablishNetwork("Establishing Network", true, true, false, true),
Surveillance("Observing City", false, false, true),
StealingTech("Stealing Tech", false, true, true, true),
RiggingElections("Rigging Elections", false, true, true) {
override fun isDoingWork(spy: Spy) = !spy.civInfo.isAtWarWith(spy.getCity().civ)
},
Coup("Coup", true, true, true),
CounterIntelligence("Counter-intelligence", false, true) {
Coup("Coup", false, false, true, true),
CounterIntelligence("Counter-intelligence", false, false, true) {
override fun isDoingWork(spy: Spy) = spy.turnsRemainingForAction > 0
},
Dead("Dead", true, false),
Dead("Dead", true, true, false),
;
internal open fun isDoingWork(spy: Spy) = isDoingWork
}
@ -81,13 +82,13 @@ class Spy private constructor() : IsPartOfGameInfoSerialization {
}
fun setAction(newAction: SpyAction, turns: Int = 0) {
assert(!newAction.hasTurns || turns > 0) // hasTurns==false but turns > 0 is allowed (CounterIntelligence), hasTurns==true and turns==0 is not.
assert(!newAction.hasCountdownTurns || turns > 0) // hasTurns==false but turns > 0 is allowed (CounterIntelligence), hasTurns==true and turns==0 is not.
action = newAction
turnsRemainingForAction = turns
}
fun endTurn() {
if (action.hasTurns && --turnsRemainingForAction > 0) return
if (action.hasCountdownTurns && --turnsRemainingForAction > 0) return
when (action) {
SpyAction.None -> return
SpyAction.Moving -> {
@ -115,19 +116,12 @@ class Spy private constructor() : IsPartOfGameInfoSerialization {
setAction(SpyAction.StealingTech) // There are new techs to steal!
}
SpyAction.StealingTech -> {
val stealableTechs = espionageManager.getTechsToSteal(getCity().civ)
if (stealableTechs.isEmpty()) {
turnsRemainingForAction = getTurnsRemainingToStealTech()
if (turnsRemainingForAction == -1) {
setAction(SpyAction.Surveillance)
addNotification("Your spy [$name] cannot steal any more techs from [${getCity().civ}] as we've already researched all the technology they know!")
return
}
val techStealCost = stealableTechs.maxOfOrNull { civInfo.gameInfo.ruleset.technologies[it]!!.cost }!!
var progressThisTurn = getCity().cityStats.currentCityStats.science
// 33% spy bonus for each level
progressThisTurn *= (rank + 2f) / 3f
progressThisTurn *= getEfficiencyModifier().toFloat()
progressTowardsStealingTech += progressThisTurn.toInt()
if (progressTowardsStealingTech > techStealCost) {
} else if (turnsRemainingForAction == 0) {
stealTech()
}
}
@ -159,6 +153,30 @@ class Spy private constructor() : IsPartOfGameInfoSerialization {
private fun startStealingTech() {
setAction(SpyAction.StealingTech)
progressTowardsStealingTech = 0
turnsRemainingForAction = getTurnsRemainingToStealTech()
}
/**
* @return The number of turns left to steal the technology, note that this is a guess and may change.
* A 0 means that we are ready to steal the technology.
* A -1 means we have no techonologies to steal.
*/
private fun getTurnsRemainingToStealTech(): Int {
val stealableTechs = espionageManager.getTechsToSteal(getCity().civ)
if (stealableTechs.isEmpty()) return -1
val techStealCost = stealableTechs.maxOfOrNull { civInfo.gameInfo.ruleset.technologies[it]!!.cost }!!
var progressThisTurn = getCity().cityStats.currentCityStats.science
// 33% spy bonus for each level
progressThisTurn *= (rank + 2f) / 3f
progressThisTurn *= getEfficiencyModifier().toFloat()
progressTowardsStealingTech += progressThisTurn.toInt()
if (progressTowardsStealingTech >= techStealCost) {
return 0
} else {
return ceil((techStealCost - progressTowardsStealingTech) / progressThisTurn).toInt()
}
}
private fun stealTech() {

View File

@ -85,7 +85,8 @@ 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.hasTurns) "[${spy.action.displayString}] ${spy.turnsRemainingForAction}${Fonts.turn}"
val actionString = if (spy.action.showTurns && spy.turnsRemainingForAction != -1)
"[${spy.action.displayString}] ${spy.turnsRemainingForAction}${Fonts.turn}"
else spy.action.displayString
spySelectionTable.add(actionString.toLabel())