mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 23:40:01 +07:00
Generalized "Stats per policies" unique
This commit is contained in:
@ -959,7 +959,7 @@
|
||||
"happiness": 5,
|
||||
"greatPersonPoints": {"Great Merchant": 2},
|
||||
"isWonder": true,
|
||||
"uniques": ["Provides 1 happiness per 2 additional social policies adopted"],
|
||||
"uniques": ["[+1 Happiness] per [2] social policies adopted"],
|
||||
"requiredTech": "Radio",
|
||||
"quote": "'We live only to discover beauty, all else is a form of waiting' - Kahlil Gibran"
|
||||
},
|
||||
|
@ -816,7 +816,7 @@
|
||||
"happiness": 5,
|
||||
"greatPersonPoints": {"Great Merchant": 2},
|
||||
"isWonder": true,
|
||||
"uniques": ["Provides 1 happiness per 2 additional social policies adopted"],
|
||||
"uniques": ["[+1 Happiness] per [2] social policies adopted"],
|
||||
"requiredTech": "Radio",
|
||||
"quote": "'We live only to discover beauty, all else is a form of waiting' - Kahlil Gibran"
|
||||
},
|
||||
|
@ -3,7 +3,6 @@ package com.unciv.logic.civilization
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.models.ruleset.BeliefType
|
||||
import com.unciv.models.ruleset.Policy
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
@ -140,10 +139,6 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
statMap.add(entry.key, entry.value)
|
||||
}
|
||||
|
||||
for (unique in civInfo.getMatchingUniques(UniqueType.Stats))
|
||||
if (unique.sourceObjectType != UniqueTarget.Building && unique.sourceObjectType != UniqueTarget.Wonder)
|
||||
statMap.add(unique.sourceObjectType!!.name, unique.stats)
|
||||
|
||||
//City-States bonuses
|
||||
for (otherCiv in civInfo.getKnownCivs()) {
|
||||
if (!otherCiv.isCityState()) continue
|
||||
@ -164,21 +159,6 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
statMap["Transportation upkeep"] = Stats(gold = -getTransportationUpkeep().toFloat())
|
||||
statMap["Unit upkeep"] = Stats(gold = -getUnitMaintenance().toFloat())
|
||||
|
||||
if (civInfo.religionManager.religion != null) {
|
||||
for (unique in civInfo.religionManager.religion!!.getFounderUniques()) {
|
||||
if (unique.isOfType(UniqueType.StatsFromGlobalCitiesFollowingReligion)) {
|
||||
statMap.add(
|
||||
"Religion",
|
||||
unique.stats * civInfo.religionManager.numberOfCitiesFollowingThisReligion()
|
||||
)
|
||||
}
|
||||
if (unique.isOfType(UniqueType.StatsFromGlobalFollowers))
|
||||
statMap.add(
|
||||
"Religion",
|
||||
unique.stats * civInfo.religionManager.numberOfFollowersFollowingThisReligion(unique.params[2]).toFloat() / unique.params[1].toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (civInfo.getHappiness() > 0) {
|
||||
val excessHappinessConversion = Stats()
|
||||
@ -201,12 +181,22 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
if (goldDifferenceFromTrade != 0)
|
||||
statMap["Trade"] = Stats(gold = goldDifferenceFromTrade.toFloat())
|
||||
|
||||
for ((key, value) in getGlobalStatsFromUniques())
|
||||
statMap.add(key,value)
|
||||
|
||||
return statMap
|
||||
}
|
||||
|
||||
|
||||
fun getHappinessBreakdown(): HashMap<String, Float> {
|
||||
val statMap = HashMap<String, Float>()
|
||||
|
||||
fun HashMap<String, Float>.add(key:String, value: Float){
|
||||
if (!containsKey(key)) put(key, value)
|
||||
else put(key, value+get(key)!!)
|
||||
}
|
||||
fun HashMap<String, Float>.add(key:String, value: Int) = add(key, value.toFloat())
|
||||
|
||||
statMap["Base happiness"] = civInfo.getDifficulty().baseHappiness.toFloat()
|
||||
|
||||
var happinessPerUniqueLuxury = 4f + civInfo.getDifficulty().extraHappinessPerLuxury
|
||||
@ -252,18 +242,12 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
// There appears to be a concurrency problem? In concurrent thread in ConstructionsTable.getConstructionButtonDTOs
|
||||
// Literally no idea how, since happinessList is ONLY replaced, NEVER altered.
|
||||
// Oh well, toList() should solve the problem, wherever it may come from.
|
||||
for ((key, value) in city.cityStats.happinessList.toList()) {
|
||||
if (statMap.containsKey(key))
|
||||
statMap[key] = statMap[key]!! + value
|
||||
else statMap[key] = value
|
||||
}
|
||||
for ((key, value) in city.cityStats.happinessList.toList())
|
||||
statMap.add(key, value)
|
||||
}
|
||||
|
||||
if (civInfo.hasUnique(UniqueType.HappinessPer2Policies)) {
|
||||
if (!statMap.containsKey("Policies")) statMap["Policies"] = 0f
|
||||
statMap["Policies"] = statMap["Policies"]!! +
|
||||
civInfo.policies.getAdoptedPolicies()
|
||||
.count { !Policy.isBranchCompleteByName(it) } / 2
|
||||
statMap.add("Policies", civInfo.policies.getAdoptedPolicies().count { !Policy.isBranchCompleteByName(it) } / 2)
|
||||
}
|
||||
|
||||
var happinessPerNaturalWonder = 1f
|
||||
@ -272,32 +256,38 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
|
||||
statMap["Natural Wonders"] = happinessPerNaturalWonder * civInfo.naturalWonders.size
|
||||
|
||||
for ((key, value) in getGlobalStatsFromUniques())
|
||||
statMap.add(key,value.happiness)
|
||||
|
||||
return statMap
|
||||
}
|
||||
|
||||
fun getGlobalStatsFromUniques():StatMap{
|
||||
val statMap = StatMap()
|
||||
if (civInfo.religionManager.religion != null) {
|
||||
var religionHappiness = 0f
|
||||
for (unique in civInfo.religionManager.religion!!.getBeliefs(BeliefType.Founder)
|
||||
.flatMap { it.uniqueObjects }
|
||||
) {
|
||||
if (unique.type == UniqueType.StatsFromGlobalCitiesFollowingReligion) {
|
||||
val followingCities =
|
||||
civInfo.religionManager.numberOfCitiesFollowingThisReligion()
|
||||
religionHappiness += unique.stats.happiness * followingCities
|
||||
}
|
||||
if (unique.type == UniqueType.StatsFromGlobalFollowers) {
|
||||
val followers =
|
||||
civInfo.religionManager.numberOfFollowersFollowingThisReligion(unique.params[2])
|
||||
religionHappiness +=
|
||||
unique.stats.happiness * (followers / unique.params[1].toInt())
|
||||
for (unique in civInfo.religionManager.religion!!.getFounderUniques()) {
|
||||
if (unique.isOfType(UniqueType.StatsFromGlobalCitiesFollowingReligion)) {
|
||||
statMap.add(
|
||||
"Religion",
|
||||
unique.stats * civInfo.religionManager.numberOfCitiesFollowingThisReligion()
|
||||
)
|
||||
}
|
||||
if (unique.isOfType(UniqueType.StatsFromGlobalFollowers))
|
||||
statMap.add(
|
||||
"Religion",
|
||||
unique.stats * civInfo.religionManager.numberOfFollowersFollowingThisReligion(unique.params[2]).toFloat() / unique.params[1].toFloat()
|
||||
)
|
||||
}
|
||||
if (religionHappiness > 0) statMap["Religion"] = religionHappiness
|
||||
}
|
||||
|
||||
for (unique in civInfo.getMatchingUniques(UniqueType.StatsPerPolicies)) {
|
||||
val amount = civInfo.policies.getAdoptedPolicies().count { !Policy.isBranchCompleteByName(it) } / unique.params[1].toInt()
|
||||
statMap.add("Policies", unique.stats.times(amount))
|
||||
}
|
||||
|
||||
for (unique in civInfo.getMatchingUniques(UniqueType.Stats))
|
||||
if (unique.sourceObjectType != UniqueTarget.Building && unique.sourceObjectType != UniqueTarget.Wonder && unique.stats.happiness != 0f){
|
||||
val sourceObjectType = unique.sourceObjectType!!.name
|
||||
if (!statMap.containsKey(sourceObjectType)) statMap[sourceObjectType] = unique.stats.happiness
|
||||
else statMap[sourceObjectType] = statMap[sourceObjectType]!! + unique.stats.happiness
|
||||
}
|
||||
if (unique.sourceObjectType != UniqueTarget.Building && unique.sourceObjectType != UniqueTarget.Wonder)
|
||||
statMap.add(unique.sourceObjectType!!.name, unique.stats)
|
||||
|
||||
return statMap
|
||||
}
|
||||
|
@ -80,6 +80,8 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
|
||||
StatsFromSpecialist("[stats] from every specialist [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
StatsPerPopulation("[stats] per [amount] population [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
StatsPerPolicies("[stats] per [amount] social policies adopted", UniqueTarget.Global),
|
||||
|
||||
|
||||
StatsFromCitiesOnSpecificTiles("[stats] in cities on [terrainFilter] tiles", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
StatsFromBuildings("[stats] from all [buildingFilter] buildings", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
@ -157,8 +159,10 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
StatsWhenAdoptingReligion("[stats] when a city adopts this religion for the first time", UniqueTarget.Global),
|
||||
StatsSpendingGreatPeople("[stats] whenever a Great Person is expended", UniqueTarget.Global),
|
||||
|
||||
|
||||
UnhappinessFromPopulationTypePercentageChange("[relativeAmount]% Unhappiness from [populationFilter] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
FoodConsumptionBySpecialists("[relativeAmount]% Food consumption by specialists [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||
@Deprecated("as of 4.3.4", ReplaceWith("[+1 Happiness] per [2] social policies adopted"))
|
||||
HappinessPer2Policies("Provides 1 happiness per 2 additional social policies adopted", UniqueTarget.Global),
|
||||
ExcessHappinessToGlobalStat("[relativeAmount]% of excess happiness converted to [stat]", UniqueTarget.Global),
|
||||
|
||||
|
@ -93,6 +93,11 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
??? example "[stats] per [amount] social policies adopted"
|
||||
Example: "[+1 Gold, +2 Production] per [3] social policies adopted"
|
||||
|
||||
Applicable to: Global
|
||||
|
||||
??? example "[stats] in cities on [terrainFilter] tiles"
|
||||
Example: "[+1 Gold, +2 Production] in cities on [Fresh Water] tiles"
|
||||
|
||||
@ -302,9 +307,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
|
||||
|
||||
Applicable to: Global, FollowerBelief
|
||||
|
||||
??? example "Provides 1 happiness per 2 additional social policies adopted"
|
||||
Applicable to: Global
|
||||
|
||||
??? example "[relativeAmount]% of excess happiness converted to [stat]"
|
||||
Example: "[+20]% of excess happiness converted to [Culture]"
|
||||
|
||||
@ -1623,21 +1625,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
|
||||
Applicable to: Ruins
|
||||
|
||||
## CityState uniques
|
||||
??? example "Provides [stats] per turn"
|
||||
Example: "Provides [+1 Gold, +2 Production] per turn"
|
||||
|
||||
Applicable to: CityState
|
||||
|
||||
??? example "Provides [stats] [cityFilter] per turn"
|
||||
Example: "Provides [+1 Gold, +2 Production] [in all cities] per turn"
|
||||
|
||||
Applicable to: CityState
|
||||
|
||||
??? example "Provides [amount] Happiness"
|
||||
Example: "Provides [3] Happiness"
|
||||
|
||||
Applicable to: CityState
|
||||
|
||||
??? example "Provides military units every ≈[amount] turns"
|
||||
Example: "Provides military units every ≈[3] turns"
|
||||
|
||||
@ -1723,11 +1710,6 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
|
||||
|
||||
Applicable to: Conditional
|
||||
|
||||
??? example "<upon discovering [tech]>"
|
||||
Example: "<upon discovering [Agriculture]>"
|
||||
|
||||
Applicable to: Conditional
|
||||
|
||||
??? example "<after adopting [policy]>"
|
||||
Example: "<after adopting [Oligarchy]>"
|
||||
|
||||
|
@ -207,6 +207,19 @@ class GlobalUniquesTests {
|
||||
Assert.assertTrue(city2.cityStats.finalStatList["Trade routes"]!!.science == 30f)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun statsFromPolicies() {
|
||||
game.makeHexagonalMap(3)
|
||||
val civInfo = game.addCiv("[+30 Science] per [2] social policies adopted")
|
||||
val policiesToAdopt = listOf("Tradition", "Aristocracy", "Legalism")
|
||||
civInfo.policies.freePolicies = 3
|
||||
for (policyName in policiesToAdopt){
|
||||
val policy = game.ruleset.policies[policyName]!!
|
||||
civInfo.policies.adopt(policy, )
|
||||
}
|
||||
Assert.assertTrue(civInfo.stats().getStatMapForNextTurn()["Policies"]!!.science == 30f)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun statsFromGlobalCitiesFollowingReligion() {
|
||||
val civ1 = game.addCiv()
|
||||
|
Reference in New Issue
Block a user