mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-24 03:53:12 -04:00
chore(purity): CityStateFunctions
This commit is contained in:
parent
ca44be05d5
commit
885e62e501
@ -209,7 +209,7 @@ class City : IsPartOfGameInfoSerialization, INamed {
|
|||||||
|
|
||||||
@Readonly fun getRuleset() = civ.gameInfo.ruleset
|
@Readonly fun getRuleset() = civ.gameInfo.ruleset
|
||||||
|
|
||||||
fun getResourcesGeneratedByCity(civResourceModifiers: Map<String, Float>) = CityResources.getResourcesGeneratedByCity(this, civResourceModifiers)
|
@Readonly fun getResourcesGeneratedByCity(civResourceModifiers: Map<String, Float>) = CityResources.getResourcesGeneratedByCity(this, civResourceModifiers)
|
||||||
@Readonly fun getAvailableResourceAmount(resourceName: String) = CityResources.getAvailableResourceAmount(this, resourceName)
|
@Readonly fun getAvailableResourceAmount(resourceName: String) = CityResources.getAvailableResourceAmount(this, resourceName)
|
||||||
|
|
||||||
@Readonly fun isGrowing() = foodForNextTurn() > 0
|
@Readonly fun isGrowing() = foodForNextTurn() > 0
|
||||||
|
@ -11,9 +11,10 @@ import yairm210.purity.annotations.Readonly
|
|||||||
object CityResources {
|
object CityResources {
|
||||||
|
|
||||||
/** Returns ALL resources, city-wide and civ-wide */
|
/** Returns ALL resources, city-wide and civ-wide */
|
||||||
|
@Readonly
|
||||||
fun getResourcesGeneratedByCity(city: City, resourceModifiers: Map<String, Float>): ResourceSupplyList {
|
fun getResourcesGeneratedByCity(city: City, resourceModifiers: Map<String, Float>): ResourceSupplyList {
|
||||||
val cityResources = getResourcesGeneratedByCityNotIncludingBuildings(city, resourceModifiers)
|
@LocalState val cityResources = getResourcesGeneratedByCityNotIncludingBuildings(city, resourceModifiers)
|
||||||
addCityResourcesGeneratedFromUniqueBuildings(city, cityResources, resourceModifiers)
|
cityResources += getCityResourcesGeneratedFromUniqueBuildings(city, resourceModifiers)
|
||||||
return cityResources
|
return cityResources
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,15 +56,18 @@ object CityResources {
|
|||||||
return cityResources
|
return cityResources
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addCityResourcesGeneratedFromUniqueBuildings(city: City, cityResources: ResourceSupplyList, resourceModifer: Map<String, Float>) {
|
@Readonly
|
||||||
|
private fun getCityResourcesGeneratedFromUniqueBuildings(city: City, resourceModifer: Map<String, Float>): ResourceSupplyList {
|
||||||
|
val buildingResources = ResourceSupplyList()
|
||||||
for (unique in city.getMatchingUniques(UniqueType.ProvidesResources, city.state, false)) { // E.G "Provides [1] [Iron]"
|
for (unique in city.getMatchingUniques(UniqueType.ProvidesResources, city.state, false)) { // E.G "Provides [1] [Iron]"
|
||||||
val resource = city.getRuleset().tileResources[unique.params[1]]
|
val resource = city.getRuleset().tileResources[unique.params[1]]
|
||||||
?: continue
|
?: continue
|
||||||
cityResources.add(
|
buildingResources.add(
|
||||||
resource, unique.getSourceNameForUser(),
|
resource, unique.getSourceNameForUser(),
|
||||||
(unique.params[0].toFloat() * resourceModifer[resource.name]!!).toInt()
|
(unique.params[0].toFloat() * resourceModifer[resource.name]!!).toInt()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
return buildingResources
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the number of resources available to this city
|
/** Gets the number of resources available to this city
|
||||||
|
@ -119,6 +119,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Readonly
|
||||||
fun turnsForGreatPersonFromCityState(): Int = ((37 + Random.Default.nextInt(7)) * civInfo.gameInfo.speed.modifier).toInt()
|
fun turnsForGreatPersonFromCityState(): Int = ((37 + Random.Default.nextInt(7)) * civInfo.gameInfo.speed.modifier).toInt()
|
||||||
|
|
||||||
/** Gain a random great person from the city state */
|
/** Gain a random great person from the city state */
|
||||||
@ -143,6 +144,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
|
|
||||||
val city = cities.city1
|
val city = cities.city1
|
||||||
|
|
||||||
|
@Readonly
|
||||||
fun giftableUniqueUnit(): BaseUnit? {
|
fun giftableUniqueUnit(): BaseUnit? {
|
||||||
val uniqueUnit = civInfo.gameInfo.ruleset.units[civInfo.cityStateUniqueUnit]
|
val uniqueUnit = civInfo.gameInfo.ruleset.units[civInfo.cityStateUniqueUnit]
|
||||||
?: return null
|
?: return null
|
||||||
@ -152,6 +154,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
return null
|
return null
|
||||||
return uniqueUnit
|
return uniqueUnit
|
||||||
}
|
}
|
||||||
|
@Readonly
|
||||||
fun randomGiftableUnit() =
|
fun randomGiftableUnit() =
|
||||||
city.cityConstructions.getConstructableUnits()
|
city.cityConstructions.getConstructableUnits()
|
||||||
.filter { !it.isCivilian() && it.isLandUnit && it.uniqueTo == null }
|
.filter { !it.isCivilian() && it.isLandUnit && it.uniqueTo == null }
|
||||||
@ -160,6 +163,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
it.value > 0 && receivingCiv.getResourceAmount(it.key) < it.value
|
it.value > 0 && receivingCiv.getResourceAmount(it.key) < it.value
|
||||||
} }
|
} }
|
||||||
.toList().randomOrNull()
|
.toList().randomOrNull()
|
||||||
|
|
||||||
val militaryUnit = giftableUniqueUnit() // If the receiving civ has discovered the required tech and not the obsolete tech for our unique, always give them the unique
|
val militaryUnit = giftableUniqueUnit() // If the receiving civ has discovered the required tech and not the obsolete tech for our unique, always give them the unique
|
||||||
?: randomGiftableUnit() // Otherwise pick at random
|
?: randomGiftableUnit() // Otherwise pick at random
|
||||||
?: return // That filter _can_ result in no candidates, if so, quit silently
|
?: return // That filter _can_ result in no candidates, if so, quit silently
|
||||||
@ -242,6 +246,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
diplomacy.addInfluence(-20f)
|
diplomacy.addInfluence(-20f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Readonly
|
||||||
fun otherCivCanPledgeProtection(otherCiv: Civilization): Boolean {
|
fun otherCivCanPledgeProtection(otherCiv: Civilization): Boolean {
|
||||||
// Must be a known city state
|
// Must be a known city state
|
||||||
if(!civInfo.isCityState || !otherCiv.isMajorCiv() || otherCiv.isDefeated() || !civInfo.knows(otherCiv))
|
if(!civInfo.isCityState || !otherCiv.isMajorCiv() || otherCiv.isDefeated() || !civInfo.knows(otherCiv))
|
||||||
@ -262,6 +267,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Readonly
|
||||||
fun otherCivCanWithdrawProtection(otherCiv: Civilization): Boolean {
|
fun otherCivCanWithdrawProtection(otherCiv: Civilization): Boolean {
|
||||||
// Must be a known city state
|
// Must be a known city state
|
||||||
if(!civInfo.isCityState || !otherCiv.isMajorCiv() || otherCiv.isDefeated() || !civInfo.knows(otherCiv))
|
if(!civInfo.isCityState || !otherCiv.isMajorCiv() || otherCiv.isDefeated() || !civInfo.knows(otherCiv))
|
||||||
@ -334,6 +340,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @return a Sequence of NotificationActions for use in addNotification, showing Capital on map if any, then opening diplomacy */
|
/** @return a Sequence of NotificationActions for use in addNotification, showing Capital on map if any, then opening diplomacy */
|
||||||
|
@Readonly
|
||||||
fun getNotificationActions() = sequence {
|
fun getNotificationActions() = sequence {
|
||||||
// Notification click will first point to CS location, if any, then open diplomacy.
|
// Notification click will first point to CS location, if any, then open diplomacy.
|
||||||
// That's fine for the influence notifications and for afraid too.
|
// That's fine for the influence notifications and for afraid too.
|
||||||
@ -348,6 +355,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
yield(DiplomacyAction(civInfo.civName))
|
yield(DiplomacyAction(civInfo.civName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Readonly
|
||||||
fun getDiplomaticMarriageCost(): Int {
|
fun getDiplomaticMarriageCost(): Int {
|
||||||
// https://github.com/Gedemon/Civ5-DLL/blob/master/CvGameCoreDLL_Expansion1/CvMinorCivAI.cpp, line 7812
|
// https://github.com/Gedemon/Civ5-DLL/blob/master/CvGameCoreDLL_Expansion1/CvMinorCivAI.cpp, line 7812
|
||||||
var cost = (500 * civInfo.gameInfo.speed.goldCostModifier).toInt()
|
var cost = (500 * civInfo.gameInfo.speed.goldCostModifier).toInt()
|
||||||
@ -362,6 +370,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
return cost
|
return cost
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Readonly
|
||||||
fun canBeMarriedBy(otherCiv: Civilization): Boolean {
|
fun canBeMarriedBy(otherCiv: Civilization): Boolean {
|
||||||
return (!civInfo.isDefeated()
|
return (!civInfo.isDefeated()
|
||||||
&& civInfo.isCityState
|
&& civInfo.isCityState
|
||||||
@ -488,6 +497,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
return modifiers
|
return modifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Readonly
|
||||||
fun goldGainedByTribute(): Int {
|
fun goldGainedByTribute(): Int {
|
||||||
// These values are close enough, linear increase throughout the game
|
// These values are close enough, linear increase throughout the game
|
||||||
var gold = (10 * civInfo.gameInfo.speed.goldGiftModifier).toInt() * 5 // rounding down to nearest 5
|
var gold = (10 * civInfo.gameInfo.speed.goldGiftModifier).toInt() * 5 // rounding down to nearest 5
|
||||||
@ -565,6 +575,7 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Readonly
|
||||||
fun getNumThreateningBarbarians(): Int {
|
fun getNumThreateningBarbarians(): Int {
|
||||||
if (civInfo.gameInfo.gameParameters.noBarbarians) return 0
|
if (civInfo.gameInfo.gameParameters.noBarbarians) return 0
|
||||||
val barbarianCiv = civInfo.gameInfo.civilizations.firstOrNull { it.isBarbarian }
|
val barbarianCiv = civInfo.gameInfo.civilizations.firstOrNull { it.isBarbarian }
|
||||||
@ -785,13 +796,16 @@ class CityStateFunctions(val civInfo: Civilization) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCityStateResourcesForAlly() = ResourceSupplyList().apply {
|
@Readonly
|
||||||
|
fun getCityStateResourcesForAlly(): ResourceSupplyList {
|
||||||
|
val resourceSupplyList = ResourceSupplyList()
|
||||||
// TODO: City-states don't give allies resources from civ-wide uniques!
|
// TODO: City-states don't give allies resources from civ-wide uniques!
|
||||||
val civResourceModifiers = civInfo.getResourceModifiers()
|
val civResourceModifiers = civInfo.getResourceModifiers()
|
||||||
for (city in civInfo.cities) {
|
for (city in civInfo.cities) {
|
||||||
// IGNORE the fact that they consume their own resources - #4769
|
// IGNORE the fact that they consume their own resources - #4769
|
||||||
addPositiveByResource(city.getResourcesGeneratedByCity(civResourceModifiers), Constants.cityStates)
|
resourceSupplyList.addPositiveByResource(city.getResourcesGeneratedByCity(civResourceModifiers), Constants.cityStates)
|
||||||
}
|
}
|
||||||
|
return resourceSupplyList
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Optimize, update whenever status changes, otherwise retain the same list
|
// TODO: Optimize, update whenever status changes, otherwise retain the same list
|
||||||
|
@ -33,6 +33,7 @@ import com.unciv.models.translations.getPlaceholderParameters
|
|||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
import com.unciv.ui.components.extensions.toPercent
|
import com.unciv.ui.components.extensions.toPercent
|
||||||
import com.unciv.utils.randomWeighted
|
import com.unciv.utils.randomWeighted
|
||||||
|
import yairm210.purity.annotations.Pure
|
||||||
import yairm210.purity.annotations.Readonly
|
import yairm210.purity.annotations.Readonly
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@ -197,7 +198,7 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Readability helper - No asSequence(): call frequency * data size is small
|
// Readability helper - No asSequence(): call frequency * data size is small
|
||||||
private fun getQuests(predicate: (Quest) -> Boolean) = ruleset.quests.values.filter(predicate)
|
@Readonly private fun getQuests(predicate: (Quest) -> Boolean) = ruleset.quests.values.filter(predicate)
|
||||||
|
|
||||||
private fun tryStartNewGlobalQuest() {
|
private fun tryStartNewGlobalQuest() {
|
||||||
if (globalQuestCountdown != 0)
|
if (globalQuestCountdown != 0)
|
||||||
@ -206,7 +207,7 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|||||||
return
|
return
|
||||||
|
|
||||||
val majorCivs = civ.getKnownCivs().filter { it.isMajorCiv() && !it.isAtWarWith(civ) } // A Sequence - fine because the count below can be different for each Quest
|
val majorCivs = civ.getKnownCivs().filter { it.isMajorCiv() && !it.isAtWarWith(civ) } // A Sequence - fine because the count below can be different for each Quest
|
||||||
fun Quest.isAssignable() = majorCivs.count { civ -> isQuestValid(this, civ) } >= minimumCivs
|
@Readonly fun Quest.isAssignable() = majorCivs.count { civ -> isQuestValid(this, civ) } >= minimumCivs
|
||||||
val assignableQuests = getQuests {
|
val assignableQuests = getQuests {
|
||||||
it.isGlobal() && it.isAssignable()
|
it.isGlobal() && it.isAssignable()
|
||||||
}
|
}
|
||||||
@ -574,7 +575,7 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
val listOfLeadersAsTranslatedString = evaluation.winners.joinToString(separator = ", ") { it.assignee.tr() }
|
val listOfLeadersAsTranslatedString = evaluation.winners.joinToString(separator = ", ") { it.assignee.tr() }
|
||||||
fun getScoreString(name: String, score: Int) = "[$name] with [$score] [$scoreDescriptor]".tr()
|
@Pure fun getScoreString(name: String, score: Int) = "[$name] with [$score] [$scoreDescriptor]".tr()
|
||||||
val leadersString = getScoreString(listOfLeadersAsTranslatedString, evaluation.maxScore)
|
val leadersString = getScoreString(listOfLeadersAsTranslatedString, evaluation.maxScore)
|
||||||
|
|
||||||
if (inquiringAssignedQuest in evaluation.winners)
|
if (inquiringAssignedQuest in evaluation.winners)
|
||||||
|
@ -194,7 +194,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
|||||||
|
|
||||||
override fun getStatBuyCost(city: City, stat: Stat): Int? = costFunctions.getStatBuyCost(city, stat)
|
override fun getStatBuyCost(city: City, stat: Stat): Int? = costFunctions.getStatBuyCost(city, stat)
|
||||||
|
|
||||||
fun getDisbandGold(civInfo: Civilization) = getBaseGoldCost(civInfo, null).toInt() / 20
|
@Readonly fun getDisbandGold(civInfo: Civilization) = getBaseGoldCost(civInfo, null).toInt() / 20
|
||||||
|
|
||||||
override fun shouldBeDisplayed(cityConstructions: CityConstructions): Boolean {
|
override fun shouldBeDisplayed(cityConstructions: CityConstructions): Boolean {
|
||||||
val rejectionReasons = getRejectionReasons(cityConstructions)
|
val rejectionReasons = getRejectionReasons(cityConstructions)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user