Allow resources from follower beliefs (#11252)

* Allow resources from follower beliefs

* incorporate suggestions
This commit is contained in:
SeventhM 2024-03-13 14:19:18 -07:00 committed by GitHub
parent fc1e701c7f
commit b60dabc089
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 37 additions and 14 deletions

View File

@ -456,24 +456,22 @@ class City : IsPartOfGameInfoSerialization {
// Finds matching uniques provided from both local and non-local sources.
fun getMatchingUniques(
uniqueType: UniqueType,
stateForConditionals: StateForConditionals = StateForConditionals(civ, this)
stateForConditionals: StateForConditionals = StateForConditionals(this),
includeCivUniques: Boolean = true
): Sequence<Unique> {
return civ.getMatchingUniques(uniqueType, stateForConditionals) +
return if (includeCivUniques)
civ.getMatchingUniques(uniqueType, stateForConditionals) +
getLocalMatchingUniques(uniqueType, stateForConditionals)
}
// Uniques special to this city
fun getLocalMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(civ, this)): Sequence<Unique> {
return (
cityConstructions.builtBuildingUniqueMap.getUniques(uniqueType).filter { it.isLocalEffect }
else (
cityConstructions.builtBuildingUniqueMap.getUniques(uniqueType)
+ religion.getUniques().filter { it.type == uniqueType }
).filter {
!it.isTimedTriggerable && it.conditionalsApply(stateForConditionals)
}
}
// Uniques coming from only this city
fun getMatchingLocalOnlyUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals): Sequence<Unique> {
// Uniques special to this city
fun getLocalMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(this)): Sequence<Unique> {
val uniques = cityConstructions.builtBuildingUniqueMap.getUniques(uniqueType).filter { it.isLocalEffect } +
religion.getUniques().filter { it.type == uniqueType }
return if (uniques.any()) uniques.filter { !it.isTimedTriggerable && it.conditionalsApply(stateForConditionals) }

View File

@ -33,6 +33,8 @@ object CityResources {
// This way we get them once, but it is ugly, I welcome other ideas :/
getCityResourcesFromCiv(city, cityResources, resourceModifers)
cityResources.removeAll { !it.resource.hasUnique(UniqueType.CityResource) }
return cityResources
}
@ -57,7 +59,7 @@ object CityResources {
}
private fun addCityResourcesGeneratedFromUniqueBuildings(city: City, cityResources: ResourceSupplyList, resourceModifer: HashMap<String, Float>) {
for (unique in city.getMatchingUniquesWithNonLocalEffects(UniqueType.ProvidesResources, StateForConditionals(city.civ, city))) { // E.G "Provides [1] [Iron]"
for (unique in city.getMatchingUniques(UniqueType.ProvidesResources, StateForConditionals(city), false)) { // E.G "Provides [1] [Iron]"
val resource = city.getRuleset().tileResources[unique.params[1]]
?: continue
cityResources.add(
@ -111,13 +113,13 @@ object CityResources {
for (building in city.cityConstructions.getBuiltBuildings()) {
// Free buildings cost no resources
if (building.name in freeBuildings) continue
cityResources.subtractResourceRequirements(building.getResourceRequirementsPerTurn(StateForConditionals(city.civ, city)), city.getRuleset(), "Buildings")
cityResources.subtractResourceRequirements(building.getResourceRequirementsPerTurn(StateForConditionals(city)), city.getRuleset(), "Buildings")
}
}
private fun getCityResourcesFromCiv(city: City, cityResources: ResourceSupplyList, resourceModifers: HashMap<String, Float>) {
// This includes the uniques from buildings, from this and all other cities
for (unique in city.getMatchingUniques(UniqueType.ProvidesResources, StateForConditionals(city.civ, city))) { // E.G "Provides [1] [Iron]"
for (unique in city.getMatchingUniques(UniqueType.ProvidesResources, StateForConditionals(city))) { // E.G "Provides [1] [Iron]"
val resource = city.getRuleset().tileResources[unique.params[1]]
?: continue
cityResources.add(

View File

@ -181,6 +181,8 @@ class CityReligionManager : IsPartOfGameInfoSerialization {
if (oldMajorityReligion != newMajorityReligion && newMajorityReligion != null) {
triggerReligionAdoption(newMajorityReligion)
}
if (oldMajorityReligion != newMajorityReligion)
city.civ.cache.updateCivResources() // follower uniques can provide resources
if (followers != previousFollowers)
city.cityStats.update()
}

View File

@ -153,7 +153,7 @@ class CivConstructions : IsPartOfGameInfoSerialization {
// "Gain a free [buildingName] [cityFilter]"
val freeBuildingsFromCiv = civInfo.getMatchingUniques(UniqueType.GainFreeBuildings, StateForConditionals.IgnoreConditionals)
for (city in civInfo.cities) {
val freeBuildingsFromCity = city.getMatchingLocalOnlyUniques(UniqueType.GainFreeBuildings, StateForConditionals.IgnoreConditionals)
val freeBuildingsFromCity = city.getLocalMatchingUniques(UniqueType.GainFreeBuildings, StateForConditionals.IgnoreConditionals)
val freeBuildingUniques = (freeBuildingsFromCiv + freeBuildingsFromCity)
.filter { city.matchesFilter(it.params[1]) && it.conditionalsApply(StateForConditionals(city.civ, city))
&& !it.hasTriggerConditional() }

View File

@ -2,6 +2,7 @@ package com.unciv.logic.city
import com.badlogic.gdx.math.Vector2
import com.unciv.logic.civilization.Civilization
import com.unciv.models.ruleset.BeliefType
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.testing.GdxTestRunner
import com.unciv.testing.TestGame
@ -97,6 +98,7 @@ class CityTest {
assertTrue(capitalCity.hasSoldBuildingThisTurn)
}
// Resource tests
@Test
fun `should get resources from tiles`() {
// given
@ -190,4 +192,23 @@ class CityTest {
assertEquals(4, resourceAmountInCapital)
}
@Test
fun `Civ-wide resources can come from follower beliefs, and affect all cities`() {
// given
val religion = testGame.addReligion(testCiv)
val belief = testGame.createBelief(BeliefType.Follower, "Provides [1] [Iron]")
religion.followerBeliefs.add(belief.name)
capitalCity.population.setPopulation(1)
capitalCity.religion.addPressure(religion.name, 1000)
val otherCity = testCiv.addCity(Vector2(2f,2f)) // NOT religionized
// when
val resourceAmountInCapital = capitalCity.getAvailableResourceAmount("Iron")
val resourceAmountInOtherCity = otherCity.getAvailableResourceAmount("Iron")
// then
assertEquals(1, resourceAmountInCapital)
assertEquals(1, resourceAmountInOtherCity)
}
}