Fix Autocracy Complete including unit test (#6908)

This commit is contained in:
SomeTroglodyte 2022-05-22 18:51:05 +02:00 committed by GitHub
parent 39bbb2de1c
commit a2c646ef8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 116 additions and 72 deletions

View File

@ -8,9 +8,13 @@ import com.unciv.models.translations.tr
import com.unciv.ui.civilopedia.FormattedLine
import kotlin.collections.ArrayList
class Belief : RulesetObject() {
class Belief() : RulesetObject() {
var type: BeliefType = BeliefType.None
constructor(type: BeliefType) : this() {
this.type = type
}
override fun getUniqueTarget() =
if (type == BeliefType.Founder || type == BeliefType.Enhancer) UniqueTarget.FounderBelief
else UniqueTarget.FollowerBelief

View File

@ -25,14 +25,14 @@ object UniqueTriggerActivation {
tile: TileInfo? = null,
notification: String? = null
): Boolean {
if (!unique.conditionalsApply(civInfo, cityInfo)) return false
val timingConditional = unique.conditionals.firstOrNull{it.type == ConditionalTimedUnique}
if (timingConditional!=null) {
if (timingConditional != null) {
civInfo.temporaryUniques.add(TemporaryUnique(unique, timingConditional.params[0].toInt()))
return true
}
if (!unique.conditionalsApply(civInfo, cityInfo)) return false
val chosenCity = cityInfo ?: civInfo.cities.firstOrNull { it.isCapital() }
val tileBasedRandom =
if (tile != null) Random(tile.position.toString().hashCode())

View File

@ -29,7 +29,7 @@ class GlobalUniquesTests {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val buildingName = game.createBuildingWithUnique("[+1 Food]").name
val buildingName = game.createBuilding("[+1 Food]").name
cityInfo.cityConstructions.addBuilding(buildingName)
cityInfo.cityStats.update()
@ -41,7 +41,7 @@ class GlobalUniquesTests {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val buildingName = game.createBuildingWithUnique("[+1 Production] [in this city]").name
val buildingName = game.createBuilding("[+1 Production] [in this city]").name
cityInfo.cityConstructions.addBuilding(buildingName)
cityInfo.cityStats.update()
@ -53,7 +53,7 @@ class GlobalUniquesTests {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true, initialPopulation = 2)
val building = game.createBuildingWithUnique("[+3 Gold] from every specialist [in this city]")
val building = game.createBuilding("[+3 Gold] from every specialist [in this city]")
val specialistName = game.addEmptySpecialist()
building.specialistSlots.add(specialistName, 2)
cityInfo.population.specialistAllocations[specialistName] = 2
@ -68,7 +68,7 @@ class GlobalUniquesTests {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true, initialPopulation = 4)
val building = game.createBuildingWithUnique("[+3 Gold] per [2] population [in this city]")
val building = game.createBuilding("[+3 Gold] per [2] population [in this city]")
cityInfo.cityConstructions.addBuilding(building.name)
cityInfo.cityStats.update()
@ -80,7 +80,7 @@ class GlobalUniquesTests {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true, initialPopulation = 2)
val building = game.createBuildingWithUnique("[+3 Gold] in cities with [3] or more population")
val building = game.createBuilding("[+3 Gold] in cities with [3] or more population")
cityInfo.cityConstructions.addBuilding(building.name)
@ -96,7 +96,7 @@ class GlobalUniquesTests {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val building = game.createBuildingWithUnique("[+3 Gold] in cities on [${Constants.desert}] tiles")
val building = game.createBuilding("[+3 Gold] in cities on [${Constants.desert}] tiles")
cityInfo.cityConstructions.addBuilding(building.name)
cityInfo.cityStats.update()
@ -112,7 +112,7 @@ class GlobalUniquesTests {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val building = game.createBuildingWithUnique("[+4 Gold] from [${Constants.grassland}] tiles [in all cities]")
val building = game.createBuilding("[+4 Gold] from [${Constants.grassland}] tiles [in all cities]")
cityInfo.cityConstructions.addBuilding(building.name)
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
@ -125,7 +125,7 @@ class GlobalUniquesTests {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val building = game.createBuildingWithUnique("[+4 Gold] from [${Constants.grassland}] tiles without [${Constants.forest}] [in this city]")
val building = game.createBuilding("[+4 Gold] from [${Constants.grassland}] tiles without [${Constants.forest}] [in this city]")
cityInfo.cityConstructions.addBuilding(building.name)
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
@ -144,7 +144,7 @@ class GlobalUniquesTests {
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true, initialPopulation = 2)
val specialist = game.addEmptySpecialist()
val building = game.createBuildingWithUnique("[+3 Faith] from every [${specialist}]")
val building = game.createBuilding("[+3 Faith] from every [${specialist}]")
cityInfo.cityConstructions.addBuilding(building.name)
cityInfo.population.specialistAllocations[specialist] = 2
@ -153,7 +153,7 @@ class GlobalUniquesTests {
Assert.assertTrue(cityInfo.cityStats.finalStatList["Specialists"]!!.faith == 6f)
cityInfo.cityConstructions.removeBuilding(building.name)
val building2 = game.createBuildingWithUnique("[+3 Faith] from every [${Constants.grassland}]")
val building2 = game.createBuilding("[+3 Faith] from every [${Constants.grassland}]")
cityInfo.cityConstructions.addBuilding(building2.name)
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
@ -161,9 +161,9 @@ class GlobalUniquesTests {
cityInfo.cityConstructions.removeBuilding(building2.name)
val emptyBuilding = game.createBuildingWithUniques()
val emptyBuilding = game.createBuilding()
val building3 = game.createBuildingWithUnique("[+3 Faith] from every [${emptyBuilding.name}]")
val building3 = game.createBuilding("[+3 Faith] from every [${emptyBuilding.name}]")
cityInfo.cityConstructions.addBuilding(emptyBuilding.name)
cityInfo.cityConstructions.addBuilding(building3.name)
cityInfo.cityStats.update()
@ -173,13 +173,14 @@ class GlobalUniquesTests {
@Test
fun statsFromTradeRoute() {
game.makeHexagonalMap(3)
val civInfo = game.addCiv(uniques = listOf("[+30 Science] from each Trade Route"))
val civInfo = game.addCiv("[+30 Science] from each Trade Route")
civInfo.tech.addTechnology("The Wheel") // Required to form trade routes
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val tile1 = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val tile2 = game.setTileFeatures(Vector2(0f,2f), Constants.desert)
tile.roadStatus = RoadStatus.Road
tile1.roadStatus = RoadStatus.Road
tile2.roadStatus = RoadStatus.Road
val cityInfo = game.addCity(civInfo, tile)
@Suppress("UNUSED_VARIABLE")
val city1 = game.addCity(civInfo, tile1)
val city2 = game.addCity(civInfo, tile2)
val inBetweenTile = game.setTileFeatures(Vector2(0f, 1f), Constants.desert)
inBetweenTile.roadStatus = RoadStatus.Road
@ -193,7 +194,7 @@ class GlobalUniquesTests {
fun statsFromGlobalCitiesFollowingReligion() {
val civ1 = game.addCiv()
val religion = game.addReligion(civ1)
val belief = game.addBelief(BeliefType.Founder, "[+30 Science] for each global city following this religion")
val belief = game.createBelief(BeliefType.Founder, "[+30 Science] for each global city following this religion")
religion.founderBeliefs.add(belief.name)
val civ2 = game.addCiv()
val tile = game.getTile(Vector2(0f,0f))
@ -211,7 +212,7 @@ class GlobalUniquesTests {
fun happinessFromGlobalCitiesFollowingReligion() {
val civ1 = game.addCiv()
val religion = game.addReligion(civ1)
val belief = game.addBelief(BeliefType.Founder, "[+42 Happiness] for each global city following this religion")
val belief = game.createBelief(BeliefType.Founder, "[+42 Happiness] for each global city following this religion")
religion.founderBeliefs.add(belief.name)
val civ2 = game.addCiv()
val tile = game.getTile(Vector2(0f,0f))
@ -229,7 +230,7 @@ class GlobalUniquesTests {
fun statsFromGlobalFollowers() {
val civ1 = game.addCiv()
val religion = game.addReligion(civ1)
val belief = game.addBelief(BeliefType.Founder, "[+30 Science] from every [3] global followers [in all cities]")
val belief = game.createBelief(BeliefType.Founder, "[+30 Science] from every [3] global followers [in all cities]")
religion.founderBeliefs.add(belief.name)
val civ2 = game.addCiv()
val tile = game.getTile(Vector2(0f,0f))
@ -250,7 +251,7 @@ class GlobalUniquesTests {
val civ = game.addCiv()
val tile = game.getTile(Vector2(0f, 0f))
val city = game.addCity(civ, tile, true)
val building = game.createBuildingWithUniques(arrayListOf("[+10 Science]", "[+200]% [Science]"))
val building = game.createBuilding("[+10 Science]", "[+200]% [Science]")
city.cityConstructions.addBuilding(building.name)
city.cityStats.update()
@ -259,10 +260,10 @@ class GlobalUniquesTests {
@Test
fun statPercentBonusCities() {
val civ = game.addCiv(uniques = listOf("[+200]% [Science] [in all cities]"))
val civ = game.addCiv("[+200]% [Science] [in all cities]")
val tile = game.getTile(Vector2(0f, 0f))
val city = game.addCity(civ, tile, true)
val building = game.createBuildingWithUniques(arrayListOf("[+10 Science]"))
val building = game.createBuilding("[+10 Science]")
city.cityConstructions.addBuilding(building.name)
city.cityStats.update()
@ -272,17 +273,15 @@ class GlobalUniquesTests {
@Test
fun statPercentFromObject() {
game.makeHexagonalMap(1)
val emptyBuilding = game.createBuildingWithUniques()
val emptyBuilding = game.createBuilding()
val civInfo = game.addCiv(
uniques = listOf(
"[+3 Faith] from every [Farm]",
"[+200]% [Faith] from every [${emptyBuilding.name}]",
"[+200]% [Faith] from every [Farm]",
)
)
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val city = game.addCity(civInfo, tile, true)
val faithBuilding = game.createBuildingWithUniques()
val faithBuilding = game.createBuilding()
faithBuilding.faith = 3f
city.cityConstructions.addBuilding(faithBuilding.name)
@ -299,17 +298,15 @@ class GlobalUniquesTests {
@Test
fun allStatsPercentFromObject() {
game.makeHexagonalMap(1)
val emptyBuilding = game.createBuildingWithUniques()
val emptyBuilding = game.createBuilding()
val civInfo = game.addCiv(
uniques = listOf(
"[+3 Faith] from every [Farm]",
"[+200]% Yield from every [${emptyBuilding.name}]",
"[+200]% Yield from every [Farm]",
)
)
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val city = game.addCity(civInfo, tile, true)
val faithBuilding = game.createBuildingWithUniques()
val faithBuilding = game.createBuilding()
faithBuilding.faith = 3f
city.cityConstructions.addBuilding(faithBuilding.name)
@ -333,7 +330,7 @@ class GlobalUniquesTests {
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
val unit = game.addUnit("Great Engineer", civInfo, tile)
val building = game.createBuildingWithUnique("[+250 Gold] whenever a Great Person is expended")
val building = game.createBuilding("[+250 Gold] whenever a Great Person is expended")
cityInfo.cityConstructions.addBuilding(building.name)
civInfo.addGold(-civInfo.gold) // reset gold just to be sure

View File

@ -87,20 +87,18 @@ class TestGame {
return tile
}
fun addCiv(uniques: List<String> = emptyList(), isPlayer: Boolean = false, cityState: CityStateType? = null): CivilizationInfo {
val nationName = "Nation-${objectsCreated++}"
ruleset.nations[nationName] = Nation().apply {
name = nationName
fun addCiv(vararg uniques: String, isPlayer: Boolean = false, cityState: CityStateType? = null): CivilizationInfo {
fun nationFactory() = Nation().apply {
cities = arrayListOf("The Capital")
if (cityState != null) {
cityStateType = cityState
}
this.uniques = ArrayList(uniques)
cityStateType = cityState
}
val nation = createRulesetObject(ruleset.nations, *uniques) {
nationFactory()
}
val civInfo = CivilizationInfo()
civInfo.nation = ruleset.nations[nationName]!!
civInfo.nation = nation
civInfo.gameInfo = gameInfo
civInfo.civName = nationName
civInfo.civName = nation.name
if (isPlayer) civInfo.playerType = PlayerType.Human
civInfo.setTransients()
if (cityState != null) {
@ -122,7 +120,7 @@ class TestGame {
if (replacePalace && civInfo.cities.size == 1) {
// Add a capital indicator without any other stats
val palaceWithoutStats = createBuildingWithUnique(UniqueType.IndicatesCapital.text)
val palaceWithoutStats = createBuilding(UniqueType.IndicatesCapital.text)
cityInfo.cityConstructions.removeBuilding("Palace")
cityInfo.cityConstructions.addBuilding(palaceWithoutStats.name)
}
@ -147,18 +145,6 @@ class TestGame {
return name
}
fun createBuildingWithUnique(unique: String): Building {
return createBuildingWithUniques(arrayListOf(unique))
}
fun createBuildingWithUniques(uniques: ArrayList<String> = arrayListOf()): Building {
val building = Building()
building.uniques = uniques
building.name = "Building-${objectsCreated++}"
ruleset.buildings[building.name] = building
return building
}
fun addReligion(foundingCiv: CivilizationInfo): Religion {
gameInfo.gameParameters.religionEnabled = true
val religion = Religion("Religion-${objectsCreated++}", gameInfo, foundingCiv.civName)
@ -167,12 +153,23 @@ class TestGame {
return religion
}
fun addBelief(type: BeliefType = BeliefType.Any, vararg uniques: String): Belief {
val belief = Belief()
belief.name = "Belief-${objectsCreated++}"
belief.type = type
belief.uniques = arrayListOf<String>(*uniques)
ruleset.beliefs[belief.name] = belief
return belief
private fun <T: IRulesetObject> createRulesetObject(
rulesetCollection: LinkedHashMap<String, T>,
vararg uniques: String,
factory: () -> T
): T {
val obj = factory()
val name = "${obj::class.simpleName}-${objectsCreated++}"
obj.name = name
uniques.toCollection(obj.uniques)
rulesetCollection[name] = obj
return obj
}
fun createBelief(type: BeliefType = BeliefType.Any, vararg uniques: String) =
createRulesetObject(ruleset.beliefs, *uniques) { Belief(type) }
fun createBuilding(vararg uniques: String) =
createRulesetObject(ruleset.buildings, *uniques) { Building() }
fun createPolicy(vararg uniques: String) =
createRulesetObject(ruleset.policies, *uniques) { Policy() }
}

View File

@ -0,0 +1,51 @@
package com.unciv.uniques
import com.badlogic.gdx.math.Vector2
import com.unciv.logic.battle.BattleDamage
import com.unciv.logic.battle.MapUnitCombatant
import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.testing.GdxTestRunner
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(GdxTestRunner::class)
class TriggeredUniquesTests {
/**
* Autocracy Complete was [UniqueType.TimedAttackStrength]
* Now: [UniqueType.Strength], ConditionalAttacking, ConditionalOurUnit, [UniqueType.ConditionalTimedUnique]
*/
private val game = TestGame().apply { makeHexagonalMap(2) }
private val civInfo = game.addCiv()
private val policy =
game.createPolicy("[+42]% Strength <when attacking> <for [Military] units> <for [1] turns>")
private val enemy = game.addCiv()
private val attacker =
MapUnitCombatant(game.addUnit("Warrior", civInfo, game.setTileFeatures(Vector2.Zero)))
private val defender =
MapUnitCombatant(game.addUnit("Warrior", enemy, game.setTileFeatures(Vector2(1f, 0f))))
@Test
fun testConditionalTimedUniqueIsTriggerable() {
val unique = policy.getMatchingUniques(UniqueType.Strength, StateForConditionals.IgnoreConditionals).firstOrNull()
Assert.assertTrue("Unique with timed conditional must be triggerable", unique!!.isTriggerable)
}
@Test
fun testConditionalTimedUniqueStrength() {
civInfo.policies.adopt(policy, true)
val modifiers = BattleDamage.getAttackModifiers(attacker, defender)
Assert.assertTrue("Timed Strength should work right after triggering", modifiers.sumValues() == 42)
}
@Test
fun testConditionalTimedUniqueExpires() {
civInfo.policies.adopt(policy, true)
civInfo.endTurn()
val modifiers = BattleDamage.getAttackModifiers(attacker, defender)
Assert.assertTrue("Timed Strength should no longer work after endTurn", modifiers.sumValues() == 0)
}
}

View File

@ -1,13 +1,9 @@
package com.unciv.uniques
import com.badlogic.gdx.math.Vector2
import com.unciv.Constants
import com.unciv.logic.civilization.CityStateType
import com.unciv.testing.GdxTestRunner
import com.unciv.ui.worldscreen.unit.UnitActions
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
@ -30,8 +26,7 @@ class UnitUniquesTests {
val cityStateCapitalTile = game.getTile(Vector2(0f, 0f))
val cityStateCapital = game.addCity(cityState, cityStateCapitalTile)
val mainCiv = game.addCiv(
uniques = listOf("Gain [90] Influence with a [Great Person] gift to a City-State"),
val mainCiv = game.addCiv("Gain [90] Influence with a [Great Person] gift to a City-State",
isPlayer = true
)
game.gameInfo.currentPlayerCiv = mainCiv
@ -46,4 +41,4 @@ class UnitUniquesTests {
assertNotNull("Great Person should have a gift action", giftAction)
}
}
}