Refactor: Remove unnecessary ruleset checks (#9973)

* address unnecessary ruleset checks

* Add missing imports

* Fix units not getting the ability uses set if it the city has your own religion

* Remove unnecessary cityConstructions check

* Remove more cases of unnecessary ruleset checks
This commit is contained in:
SeventhM
2023-08-27 12:48:20 -07:00
committed by GitHub
parent 066c698117
commit bda3215006
29 changed files with 219 additions and 178 deletions

View File

@ -68,7 +68,7 @@ object BackwardCompatibility {
for (building in city.cityConstructions.getBuiltBuildings()) {
if (!ruleset.buildings.containsKey(building.name))
city.cityConstructions.removeBuilding(building.name)
city.cityConstructions.removeBuilding(building)
}
fun isInvalidConstruction(construction: String) =

View File

@ -454,7 +454,7 @@ object GameStarter {
ruleset: Ruleset,
eraUnitReplacement: String,
settlerLikeUnits: Map<String, BaseUnit>
): String? {
): BaseUnit? {
var unit = unitParam // We want to change it and this is the easiest way to do so
if (unit == Constants.eraSpecificUnit) unit = eraUnitReplacement
if (unit == Constants.settler && Constants.settler !in ruleset.units) {
@ -464,7 +464,7 @@ object GameStarter {
&& it.value.isCivilian()
}
if (buildableSettlerLikeUnits.isEmpty()) return null // No settlers in this mod
return civ.getEquivalentUnit(buildableSettlerLikeUnits.keys.random()).name
return civ.getEquivalentUnit(buildableSettlerLikeUnits.keys.random())
}
if (unit == "Worker" && "Worker" !in ruleset.units) {
val buildableWorkerLikeUnits = ruleset.units.filter {
@ -472,9 +472,9 @@ object GameStarter {
it.value.isBuildable(civ) && it.value.isCivilian()
}
if (buildableWorkerLikeUnits.isEmpty()) return null // No workers in this mod
return civ.getEquivalentUnit(buildableWorkerLikeUnits.keys.random()).name
return civ.getEquivalentUnit(buildableWorkerLikeUnits.keys.random())
}
return civ.getEquivalentUnit(unit).name
return civ.getEquivalentUnit(unit)
}
private fun adjustStartingUnitsForCityStatesAndOneCityChallenge(

View File

@ -10,6 +10,7 @@ import com.unciv.logic.civilization.NotificationIcon
import com.unciv.logic.map.TileMap
import com.unciv.logic.map.tile.Tile
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.ui.components.extensions.randomWeighted
import kotlin.math.max
import kotlin.math.min
@ -246,7 +247,7 @@ class Encampment() : IsPartOfGameInfoSerialization {
return (spawnedUnit != null)
}
private fun chooseBarbarianUnit(naval: Boolean): String? {
private fun chooseBarbarianUnit(naval: Boolean): BaseUnit? {
// if we don't make this into a separate list then the retain() will happen on the Tech keys,
// which effectively removes those techs from the game and causes all sorts of problems
val allResearchedTechs = gameInfo.ruleset.technologies.keys.toMutableList()
@ -269,9 +270,7 @@ class Encampment() : IsPartOfGameInfoSerialization {
// getForceEvaluation is already conveniently biased towards fast units and against ranged naval
val weightings = unitList.map { it.getForceEvaluation().toFloat() }
val unit = unitList.randomWeighted(weightings)
return unit.name
return unitList.randomWeighted(weightings)
}
/** When a barbarian is spawned, seed the counter for next spawn */

View File

@ -339,7 +339,7 @@ object NextTurnAutomation {
if (construction is PerpetualConstruction) continue
if ((construction as INonPerpetualConstruction).canBePurchasedWithStat(city, Stat.Gold)
&& city.civ.gold / 3 >= construction.getStatBuyCost(city, Stat.Gold)!!) {
city.cityConstructions.purchaseConstruction(construction.name, 0, true)
city.cityConstructions.purchaseConstruction(construction, 0, true)
}
}
@ -623,7 +623,7 @@ object NextTurnAutomation {
&& it.name !in civInfo.civConstructions.getFreeBuildings(city.id) }
.randomOrNull()
if (buildingToSell != null) {
city.sellBuilding(buildingToSell.name)
city.sellBuilding(buildingToSell)
break
}
}

View File

@ -90,13 +90,12 @@ object ReligionAutomation {
val buildings = city.religion.getMajorityReligion()!!.buildingsPurchasableByBeliefs
val buildingToBePurchased = buildings
.asSequence()
.map { civInfo.getEquivalentBuilding(it).name }
.map { city.cityConstructions.getConstruction(it) as INonPerpetualConstruction }
.map { civInfo.getEquivalentBuilding(it) }
.filter { it.isPurchasable(city.cityConstructions) }
.filter { (it.getStatBuyCost(city, Stat.Faith) ?: return@filter false) <= civInfo.religionManager.storedFaith }
.minByOrNull { it.getStatBuyCost(city, Stat.Faith)!! }
?: continue
city.cityConstructions.purchaseConstruction(buildingToBePurchased.name, -1, true, Stat.Faith)
city.cityConstructions.purchaseConstruction(buildingToBePurchased, -1, true, Stat.Faith)
return
}
}
@ -117,7 +116,7 @@ object ReligionAutomation {
?: return
val hasUniqueToTakeCivReligion = civInfo.gameInfo.ruleset.units[missionaryConstruction.name]!!.hasUnique(UniqueType.TakeReligionOverBirthCity)
val hasUniqueToTakeCivReligion = missionaryConstruction.hasUnique(UniqueType.TakeReligionOverBirthCity)
val validCitiesToBuy = civInfo.cities.filter {
(hasUniqueToTakeCivReligion || it.religion.getMajorityReligion() == civInfo.religionManager.religion)
@ -138,21 +137,20 @@ object ReligionAutomation {
else -> validCitiesToBuy.first()
}
cityToBuyMissionary.cityConstructions.purchaseConstruction(missionaryConstruction.name, -1, true, Stat.Faith)
cityToBuyMissionary.cityConstructions.purchaseConstruction(missionaryConstruction, -1, true, Stat.Faith)
return
}
private fun buyGreatProphetInAnyCity(civInfo: Civilization) {
if (civInfo.religionManager.religionState < ReligionState.Religion) return
var greatProphetUnit = civInfo.religionManager.getGreatProphetEquivalent() ?: return
greatProphetUnit = civInfo.getEquivalentUnit(greatProphetUnit).name
val greatProphetConstruction = civInfo.cities.first().cityConstructions.getConstruction(greatProphetUnit) as INonPerpetualConstruction
greatProphetUnit = civInfo.getEquivalentUnit(greatProphetUnit)
val cityToBuyGreatProphet = civInfo.cities
.asSequence()
.filter { greatProphetConstruction.isPurchasable(it.cityConstructions) }
.filter { greatProphetConstruction.canBePurchasedWithStat(it, Stat.Faith) }
.filter { (greatProphetConstruction.getStatBuyCost(it, Stat.Faith) ?: return@filter false) <= civInfo.religionManager.storedFaith }
.minByOrNull { greatProphetConstruction.getStatBuyCost(it, Stat.Faith)!! }
.filter { greatProphetUnit.isPurchasable(it.cityConstructions) }
.filter { greatProphetUnit.canBePurchasedWithStat(it, Stat.Faith) }
.filter { (greatProphetUnit.getStatBuyCost(it, Stat.Faith) ?: return@filter false) <= civInfo.religionManager.storedFaith }
.minByOrNull { greatProphetUnit.getStatBuyCost(it, Stat.Faith)!! }
?: return
cityToBuyGreatProphet.cityConstructions.purchaseConstruction(greatProphetUnit, -1, true, Stat.Faith)
}
@ -175,7 +173,7 @@ object ReligionAutomation {
?: return
val hasUniqueToTakeCivReligion = civInfo.gameInfo.ruleset.units[inquisitorConstruction.name]!!.hasUnique(UniqueType.TakeReligionOverBirthCity)
val hasUniqueToTakeCivReligion = inquisitorConstruction.hasUnique(UniqueType.TakeReligionOverBirthCity)
val validCitiesToBuy = civInfo.cities.filter {
(hasUniqueToTakeCivReligion || it.religion.getMajorityReligion() == civInfo.religionManager.religion)
@ -183,16 +181,10 @@ object ReligionAutomation {
&& inquisitorConstruction.isPurchasable(it.cityConstructions)
&& inquisitorConstruction.canBePurchasedWithStat(it, Stat.Faith)
}
if (validCitiesToBuy.isEmpty()) return
val cityToBuy = validCitiesToBuy
.filter {
inquisitorConstruction.isPurchasable(it.cityConstructions)
&& inquisitorConstruction.canBePurchasedWithStat(it, Stat.Faith)
}
.minByOrNull { it.getCenterTile().aerialDistanceTo(city.getCenterTile()) } ?: return
cityToBuy.cityConstructions.purchaseConstruction(inquisitorConstruction.name, -1, true, Stat.Faith)
cityToBuy.cityConstructions.purchaseConstruction(inquisitorConstruction, -1, true, Stat.Faith)
}
// endregion
@ -331,7 +323,7 @@ object ReligionAutomation {
for (unique in belief.uniqueObjects) {
val modifier =
if (unique.conditionals.any { it.type == UniqueType.ConditionalOurUnit && it.params[0] == civInfo.religionManager.getGreatProphetEquivalent() }) 1/2f
if (unique.conditionals.any { it.type == UniqueType.ConditionalOurUnit && it.params[0] == civInfo.religionManager.getGreatProphetEquivalent()?.name }) 1/2f
else 1f
// Some city-filters are modified by personality (non-enemy foreign cities)
score += modifier * when (unique.type) {

View File

@ -736,7 +736,7 @@ object Battle {
.any { unique -> unique.params[0] == "Land" } }
if (workerTypeUnit != null)
capturingCiv.units.placeUnitNearTile(capturedUnit.currentTile.position, workerTypeUnit.name)
capturingCiv.units.placeUnitNearTile(capturedUnit.currentTile.position, workerTypeUnit)
}
else capturedUnit.capturedBy(capturingCiv)
}

View File

@ -16,6 +16,7 @@ import com.unciv.logic.map.mapunit.MapUnit
import com.unciv.logic.map.tile.RoadStatus
import com.unciv.logic.map.tile.Tile
import com.unciv.models.Counter
import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.ModOptionsConstants
import com.unciv.models.ruleset.tile.ResourceSupplyList
import com.unciv.models.ruleset.tile.ResourceType
@ -150,13 +151,13 @@ class City : IsPartOfGameInfoSerialization {
fun isCapital(): Boolean = cityConstructions.getBuiltBuildings().any { it.hasUnique(UniqueType.IndicatesCapital) }
fun isCoastal(): Boolean = centerTile.isCoastalTile()
fun capitalCityIndicator(): String {
fun capitalCityIndicator(): Building {
val indicatorBuildings = getRuleset().buildings.values
.asSequence()
.filter { it.hasUnique(UniqueType.IndicatesCapital) }
val civSpecificBuilding = indicatorBuildings.firstOrNull { it.uniqueTo == civ.civName }
return civSpecificBuilding?.name ?: indicatorBuildings.first().name
return civSpecificBuilding ?: indicatorBuildings.first()
}
fun isConnectedToCapital(connectionTypePredicate: (Set<String>) -> Boolean = { true }): Boolean {
@ -542,8 +543,12 @@ class City : IsPartOfGameInfoSerialization {
getRuleset().buildings[buildingName]!!.cost / 10
fun sellBuilding(buildingName: String) {
cityConstructions.removeBuilding(buildingName)
civ.addGold(getGoldForSellingBuilding(buildingName))
sellBuilding(getRuleset().buildings[buildingName]!!)
}
fun sellBuilding(building: Building) {
cityConstructions.removeBuilding(building)
civ.addGold(getGoldForSellingBuilding(building.name))
hasSoldBuildingThisTurn = true
population.unassignExtraPopulation() // If the building provided specialists, release them to other work

View File

@ -492,6 +492,11 @@ class CityConstructions : IsPartOfGameInfoSerialization {
fun addBuilding(buildingName: String) {
val building = city.getRuleset().buildings[buildingName]!!
addBuilding(building)
}
fun addBuilding(building: Building) {
val buildingName = building.name
val civ = city.civ
if (building.cityHealth > 0) {
@ -501,14 +506,12 @@ class CityConstructions : IsPartOfGameInfoSerialization {
}
builtBuildingObjects = builtBuildingObjects.withItem(building)
builtBuildings.add(buildingName)
city.civ.cache.updateCitiesConnectedToCapital(false) // could be a connecting building, like a harbor
updateUniques()
/** Support for [UniqueType.CreatesOneImprovement] */
applyCreateOneImprovement(building)
triggerNewBuildingUniques(building)
if (building.hasUnique(UniqueType.EnemyUnitsSpendExtraMovement))
@ -518,21 +521,13 @@ class CityConstructions : IsPartOfGameInfoSerialization {
if (building.isStatRelated(Stat.Science) && civ.hasUnique(UniqueType.TechBoostWhenScientificBuildingsBuiltInCapital))
civ.tech.addScience(civ.tech.scienceOfLast8Turns.sum() / 8)
val uniqueTypesModifyingYields = listOf(
UniqueType.StatsFromTiles, UniqueType.StatsFromTilesWithout, UniqueType.StatsFromObject,
UniqueType.StatPercentFromObject, UniqueType.AllStatsPercentFromObject
)
updateUniques()
// Happiness is global, so it could affect all cities
if (building.isStatRelated(Stat.Happiness)) {
for (city in civ.cities) {
city.reassignPopulationDeferred()
}
}
else if(uniqueTypesModifyingYields.any { building.hasUnique(it) })
city.reassignPopulationDeferred()
else city.reassignPopulationDeferred()
addFreeBuildings()
}
@ -561,7 +556,12 @@ class CityConstructions : IsPartOfGameInfoSerialization {
builtBuildingObjects = builtBuildingObjects.withoutItem(buildingObject)
else builtBuildingObjects.removeAll{ it.name == buildingName }
builtBuildings.remove(buildingName)
city.civ.cache.updateCitiesConnectedToCapital(false) // could be a connecting building, like a harbor
updateUniques()
}
fun removeBuilding(building: Building) {
builtBuildingObjects = builtBuildingObjects.withoutItem(building)
builtBuildings.remove(building.name)
updateUniques()
}
@ -570,6 +570,7 @@ class CityConstructions : IsPartOfGameInfoSerialization {
for (building in getBuiltBuildings())
builtBuildingUniqueMap.addUniques(building.uniqueObjects)
if (!onLoadGame) {
city.civ.cache.updateCitiesConnectedToCapital(false) // could be a connecting building, like a harbor
city.cityStats.update()
city.civ.cache.updateCivResources()
}
@ -580,7 +581,7 @@ class CityConstructions : IsPartOfGameInfoSerialization {
val freeBuildingUniques = city.getLocalMatchingUniques(UniqueType.GainFreeBuildings, StateForConditionals(city.civ, city))
for (unique in freeBuildingUniques) {
val freeBuildingName = city.civ.getEquivalentBuilding(unique.params[0]).name
val freeBuilding = city.civ.getEquivalentBuilding(unique.params[0])
val citiesThatApply = when (unique.params[1]) {
"in this city" -> listOf(city)
"in other cities" -> city.civ.cities.filter { it !== city }
@ -588,24 +589,24 @@ class CityConstructions : IsPartOfGameInfoSerialization {
}
for (city in citiesThatApply) {
if (city.cityConstructions.containsBuildingOrEquivalent(freeBuildingName)) continue
city.cityConstructions.addBuilding(freeBuildingName)
if (city.cityConstructions.containsBuildingOrEquivalent(freeBuilding.name)) continue
city.cityConstructions.addBuilding(freeBuilding)
if (city.id !in freeBuildingsProvidedFromThisCity)
freeBuildingsProvidedFromThisCity[city.id] = hashSetOf()
freeBuildingsProvidedFromThisCity[city.id]!!.add(freeBuildingName)
freeBuildingsProvidedFromThisCity[city.id]!!.add(freeBuilding.name)
}
}
// Civ-level uniques - for these only add free buildings from each city to itself to avoid weirdness on city conquest
for (unique in city.civ.getMatchingUniques(UniqueType.GainFreeBuildings, stateForConditionals = StateForConditionals(city.civ, city))) {
val freeBuildingName = city.civ.getEquivalentBuilding(unique.params[0]).name
val freeBuilding = city.civ.getEquivalentBuilding(unique.params[0])
if (city.matchesFilter(unique.params[1])) {
if (city.id !in freeBuildingsProvidedFromThisCity)
freeBuildingsProvidedFromThisCity[city.id] = hashSetOf()
freeBuildingsProvidedFromThisCity[city.id]!!.add(freeBuildingName)
if (!isBuilt(freeBuildingName))
addBuilding(freeBuildingName)
freeBuildingsProvidedFromThisCity[city.id]!!.add(freeBuilding.name)
if (!isBuilt(freeBuilding.name))
addBuilding(freeBuilding)
}
}
@ -615,7 +616,7 @@ class CityConstructions : IsPartOfGameInfoSerialization {
for (building in autoGrantedBuildings)
if (building.isBuildable(city.cityConstructions))
addBuilding(building.name)
addBuilding(building)
}
/**
@ -641,7 +642,31 @@ class CityConstructions : IsPartOfGameInfoSerialization {
tile: Tile? = null
): Boolean {
val construction = getConstruction(constructionName) as? INonPerpetualConstruction ?: return false
return purchaseConstruction(construction, queuePosition, automatic, stat, tile)
}
/**
* Purchase a construction for gold (or another stat)
* called from NextTurnAutomation and the City UI
* Build / place the new item, deduct cost, and maintain queue.
*
* @param construction What to buy (needed since buying something not queued is allowed)
* @param queuePosition Position in the queue or -1 if not from queue
* Note: -1 does not guarantee queue will remain unchanged (validation)
* @param automatic Flag whether automation should try to choose what next to build (not coming from UI)
* Note: settings.autoAssignCityProduction is handled later
* @param stat Stat object of the stat with which was paid for the construction
* @param tile Supports [UniqueType.CreatesOneImprovement] the tile to place the improvement from that unique on.
* Ignored when the [constructionName] does not have that unique. If null and the building has the unique, a tile is chosen automatically.
* @return Success (false e.g. unit cannot be placed)
*/
fun purchaseConstruction(
construction: INonPerpetualConstruction,
queuePosition: Int,
automatic: Boolean,
stat: Stat = Stat.Gold,
tile: Tile? = null
): Boolean {
// Support UniqueType.CreatesOneImprovement: it is active when getImprovementToCreate returns an improvement
val improvementToPlace = (construction as? Building)?.getImprovementToCreate(city.getRuleset())
if (improvementToPlace != null) {
@ -675,7 +700,7 @@ class CityConstructions : IsPartOfGameInfoSerialization {
&& it.params[2] == stat.name
}
) {
city.civ.civConstructions.boughtItemsWithIncreasingPrice.add(constructionName, 1)
city.civ.civConstructions.boughtItemsWithIncreasingPrice.add(construction.name, 1)
}
}
@ -688,14 +713,14 @@ class CityConstructions : IsPartOfGameInfoSerialization {
fun addCheapestBuildableStatBuilding(stat: Stat): String? {
val cheapestBuildableStatBuilding = getBasicStatBuildings(stat)
.map { city.civ.getEquivalentBuilding(it.name) }
.map { city.civ.getEquivalentBuilding(it) }
.filter { it.isBuildable(this) || isBeingConstructedOrEnqueued(it.name) }
.minByOrNull { it.cost }?.name
.minByOrNull { it.cost }
?: return null
constructionComplete(getConstruction(cheapestBuildableStatBuilding) as INonPerpetualConstruction)
constructionComplete(cheapestBuildableStatBuilding)
return cheapestBuildableStatBuilding
return cheapestBuildableStatBuilding.name
}
private fun removeCurrentConstruction() = removeFromQueue(0, true)

View File

@ -41,9 +41,9 @@ class CityConquestFunctions(val city: City){
building.hasUnique(UniqueType.NotDestroyedWhenCityCaptured) || building.isWonder -> continue
building.hasUnique(UniqueType.IndicatesCapital) -> continue // Palace needs to stay a just a bit longer so moveToCiv isn't confused
building.hasUnique(UniqueType.DestroyedWhenCityCaptured) ->
city.cityConstructions.removeBuilding(building.name)
city.cityConstructions.removeBuilding(building)
// Regular buildings have a 34% chance of removal
tileBasedRandom.nextInt(100) < 34 -> city.cityConstructions.removeBuilding(building.name)
tileBasedRandom.nextInt(100) < 34 -> city.cityConstructions.removeBuilding(building)
}
}
}
@ -67,7 +67,7 @@ class CityConquestFunctions(val city: City){
for (building in city.cityConstructions.getBuiltBuildings()) {
// Remove national wonders
if (building.isNationalWonder && !building.hasUnique(UniqueType.NotDestroyedWhenCityCaptured))
city.cityConstructions.removeBuilding(building.name)
city.cityConstructions.removeBuilding(building)
// Check if we exceed MaxNumberBuildable for any buildings
for (unique in building.getMatchingUniques(UniqueType.MaxNumberBuildable)) {
@ -78,7 +78,7 @@ class CityConquestFunctions(val city: City){
} >= unique.params[0].toInt()
) {
// For now, just destroy in new city. Even if constructing in own cities
this.city.cityConstructions.removeBuilding(building.name)
this.city.cityConstructions.removeBuilding(building)
}
}
}
@ -289,10 +289,10 @@ class CityConquestFunctions(val city: City){
// Transfer unique buildings
for (building in city.cityConstructions.getBuiltBuildings()) {
val civEquivalentBuilding = newCiv.getEquivalentBuilding(building.name)
val civEquivalentBuilding = newCiv.getEquivalentBuilding(building)
if (building != civEquivalentBuilding) {
city.cityConstructions.removeBuilding(building.name)
city.cityConstructions.addBuilding(civEquivalentBuilding.name)
city.cityConstructions.removeBuilding(building)
city.cityConstructions.addBuilding(civEquivalentBuilding)
}
}

View File

@ -205,7 +205,7 @@ class CityFounder {
val building = ruleset.buildings[buildingName] ?: continue
val uniqueBuilding = civInfo.getEquivalentBuilding(building)
if (uniqueBuilding.isBuildable(city.cityConstructions))
city.cityConstructions.addBuilding(uniqueBuilding.name)
city.cityConstructions.addBuilding(uniqueBuilding)
}
civInfo.civConstructions.tryAddFreeBuildings()

View File

@ -76,7 +76,7 @@ class CityStateFunctions(val civInfo: Civilization) {
return
val giftedUnit = giftableUnits.random()
val cities = NextTurnAutomation.getClosestCities(receivingCiv, civInfo) ?: return
val placedUnit = receivingCiv.units.placeUnitNearTile(cities.city1.location, giftedUnit.name)
val placedUnit = receivingCiv.units.placeUnitNearTile(cities.city1.location, giftedUnit)
?: return
val locations = LocationAction(placedUnit.getTile().position, cities.city2.location)
receivingCiv.addNotification( "[${civInfo.civName}] gave us a [${giftedUnit.name}] as a gift!", locations,
@ -438,7 +438,7 @@ class CityStateFunctions(val civInfo: Civilization) {
it.value.isCivilian() && it.value.isBuildable(civInfo)
}
if (buildableWorkerLikeUnits.isEmpty()) return // Bad luck?
demandingCiv.units.placeUnitNearTile(civInfo.getCapital()!!.location, buildableWorkerLikeUnits.keys.random())
demandingCiv.units.placeUnitNearTile(civInfo.getCapital()!!.location, buildableWorkerLikeUnits.values.random())
civInfo.getDiplomacyManager(demandingCiv).addInfluence(-50f)
cityStateBullied(demandingCiv)

View File

@ -11,6 +11,7 @@ import com.unciv.models.ruleset.Belief
import com.unciv.models.ruleset.BeliefType
import com.unciv.models.ruleset.unique.UniqueTriggerActivation
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.ui.components.extensions.toPercent
import java.lang.Integer.max
import java.lang.Integer.min
@ -143,7 +144,7 @@ class ReligionManager : IsPartOfGameInfoSerialization {
// https://www.reddit.com/r/civ/comments/2m82wu/can_anyone_detail_the_finer_points_of_great/
// Game files (globaldefines.xml)
fun faithForNextGreatProphet(): Int {
val greatProphetsEarned = civInfo.civConstructions.boughtItemsWithIncreasingPrice[getGreatProphetEquivalent()!!]
val greatProphetsEarned = civInfo.civConstructions.boughtItemsWithIncreasingPrice[getGreatProphetEquivalent()!!.name]
var faithCost =
(200 + 100 * greatProphetsEarned * (greatProphetsEarned + 1) / 2f) *
@ -166,12 +167,12 @@ class ReligionManager : IsPartOfGameInfoSerialization {
return true
}
fun getGreatProphetEquivalent(): String? {
return civInfo.gameInfo.ruleset.units.values.firstOrNull { it.hasUnique(UniqueType.MayFoundReligion) }?.name
fun getGreatProphetEquivalent(): BaseUnit? {
return civInfo.gameInfo.ruleset.units.values.firstOrNull { it.hasUnique(UniqueType.MayFoundReligion) }
}
private fun generateProphet() {
val prophetUnitName = getGreatProphetEquivalent() ?: return // No prophet units in this mod
val prophetUnit = getGreatProphetEquivalent() ?: return // No prophet units in this mod
val prophetSpawnChange = (5f + storedFaith - faithForNextGreatProphet()) / 100f
@ -179,10 +180,10 @@ class ReligionManager : IsPartOfGameInfoSerialization {
val birthCity =
if (religionState <= ReligionState.Pantheon) civInfo.getCapital()
else civInfo.religionManager.getHolyCity()
val prophet = civInfo.units.addUnit(prophetUnitName, birthCity) ?: return
val prophet = civInfo.units.addUnit(prophetUnit, birthCity) ?: return
prophet.religion = religion!!.name
storedFaith -= faithForNextGreatProphet()
civInfo.civConstructions.boughtItemsWithIncreasingPrice.add(prophetUnitName, 1)
civInfo.civConstructions.boughtItemsWithIncreasingPrice.add(prophetUnit.name, 1)
}
}

View File

@ -46,7 +46,7 @@ class RuinsManager : IsPartOfGameInfoSerialization {
if (civInfo.gameInfo.difficulty in possibleReward.excludedDifficulties) continue
if (possibleReward.hasUnique(UniqueType.HiddenWithoutReligion) && !civInfo.gameInfo.isReligionEnabled()) continue
if (possibleReward.hasUnique(UniqueType.HiddenAfterGreatProphet)
&& (civInfo.civConstructions.boughtItemsWithIncreasingPrice[civInfo.religionManager.getGreatProphetEquivalent()] ?: 0) > 0
&& (civInfo.civConstructions.boughtItemsWithIncreasingPrice[civInfo.religionManager.getGreatProphetEquivalent()?.name] ?: 0) > 0
) continue
if (possibleReward.getMatchingUniques(UniqueType.OnlyAvailableWhen, StateForConditionals.IgnoreConditionals)

View File

@ -191,7 +191,7 @@ class TurnManager(val civInfo: Civilization) {
repeat(rebelCount) {
civInfo.gameInfo.tileMap.placeUnitNearTile(
spawnTile.position,
unitToSpawn.name,
unitToSpawn,
barbarians
)
}

View File

@ -28,12 +28,16 @@ class UnitManager(val civInfo:Civilization) {
private var nextPotentiallyDueAt = 0
fun addUnit(unitName: String, city: City? = null): MapUnit? {
if (civInfo.cities.isEmpty()) return null
if (!civInfo.gameInfo.ruleset.units.containsKey(unitName)) return null
val unit = civInfo.gameInfo.ruleset.units[unitName] ?: return null
return addUnit(unit, city)
}
val unit = civInfo.getEquivalentUnit(unitName)
fun addUnit(baseUnit: BaseUnit, city: City? = null): MapUnit? {
if (civInfo.cities.isEmpty()) return null
val unit = civInfo.getEquivalentUnit(baseUnit)
val cityToAddTo = when {
unit.isWaterUnit() && (city==null || !city.isCoastal()) ->
unit.isWaterUnit() && (city == null || !city.isCoastal()) ->
civInfo.cities.filter { it.isCoastal() }.randomOrNull()
city != null -> city
else -> civInfo.cities.random()
@ -46,22 +50,11 @@ class UnitManager(val civInfo:Civilization) {
}
if (placedUnit.hasUnique(UniqueType.ReligiousUnit) && civInfo.gameInfo.isReligionEnabled()) {
placedUnit.religion =
when {
placedUnit.hasUnique(UniqueType.TakeReligionOverBirthCity)
&& civInfo.religionManager.religion?.isMajorReligion() == true ->
civInfo.religionManager.religion!!.name
city != null -> city.cityConstructions.city.religion.getMajorityReligionName()
else -> civInfo.religionManager.religion?.name
}
placedUnit.setupAbilityUses(cityToAddTo)
}
for (unique in civInfo.getMatchingUniques(UniqueType.LandUnitsCrossTerrainAfterUnitGained)) {
if (unit.matchesFilter(unique.params[1])) {
civInfo.passThroughImpassableUnlocked = true // Update the cached Boolean
civInfo.passableImpassables.add(unique.params[0]) // Add to list of passable impassables
if (!placedUnit.hasUnique(UniqueType.TakeReligionOverBirthCity)
|| civInfo.religionManager.religion?.isMajorReligion() == false) {
placedUnit.religion = cityToAddTo.religion.getMajorityReligionName()
}
placedUnit.setupAbilityUses(cityToAddTo) // Seting up abilies a second time in case the city or religion has a different ability count
}
return placedUnit
@ -73,7 +66,17 @@ class UnitManager(val civInfo:Civilization) {
* @return created [MapUnit] or null if no suitable location was found
* */
fun placeUnitNearTile(location: Vector2, unitName: String): MapUnit? {
val unit = civInfo.gameInfo.tileMap.placeUnitNearTile(location, unitName, civInfo)
val unit = civInfo.gameInfo.ruleset.units[unitName]!!
return placeUnitNearTile(location, unit)
}
/** Tries to place the a [baseUnit] unit into the [Tile] closest to the given the [location]
* @param location where to try to place the unit
* @param baseUnit [BaseUnit] to create and place
* @return created [MapUnit] or null if no suitable location was found
* */
fun placeUnitNearTile(location: Vector2, baseUnit: BaseUnit): MapUnit? {
val unit = civInfo.gameInfo.tileMap.placeUnitNearTile(location, baseUnit, civInfo)
if (unit != null) {
val triggerNotificationText = "due to gaining a [${unit.name}]"
@ -86,6 +89,18 @@ class UnitManager(val civInfo:Civilization) {
UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
if (unit.baseUnit.getResourceRequirementsPerTurn().isNotEmpty())
civInfo.cache.updateCivResources()
for (unique in civInfo.getMatchingUniques(UniqueType.LandUnitsCrossTerrainAfterUnitGained)) {
if (unit.matchesFilter(unique.params[1])) {
civInfo.passThroughImpassableUnlocked = true // Update the cached Boolean
civInfo.passableImpassables.add(unique.params[0]) // Add to list of passable impassables
}
}
if (unit.hasUnique(UniqueType.ReligiousUnit) && civInfo.gameInfo.isReligionEnabled()) {
unit.religion = civInfo.religionManager.religion?.name
unit.setupAbilityUses()
}
}
return unit
}

View File

@ -14,6 +14,7 @@ import com.unciv.models.ruleset.nation.Nation
import com.unciv.models.ruleset.tile.TerrainType
import com.unciv.models.ruleset.unique.UniqueMap
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.unit.BaseUnit
import java.lang.Integer.max
import java.util.concurrent.ConcurrentHashMap
import kotlin.math.abs
@ -486,12 +487,27 @@ class TileMap(initialCapacity: Int = 10) : IsPartOfGameInfoSerialization {
* @param civInfo civilization to assign unit to
* @return created [MapUnit] or null if no suitable location was found
* */
fun placeUnitNearTile(
position: Vector2,
unitName: String,
civInfo: Civilization
): MapUnit? {
val unit = gameInfo.ruleset.units[unitName]!!
return placeUnitNearTile(position, unit, civInfo)
}
/** Tries to place the [baseUnit] into the [Tile] closest to the given [position]
* @param position where to try to place the unit (or close - max 10 tiles distance)
* @param baseUnit [BaseUnit][com.unciv.models.ruleset.unit.BaseUnit] to create and place
* @param civInfo civilization to assign unit to
* @return created [MapUnit] or null if no suitable location was found
* */
fun placeUnitNearTile(
position: Vector2,
unitName: String,
baseUnit: BaseUnit,
civInfo: Civilization
): MapUnit? {
val unit = gameInfo.ruleset.units[unitName]!!.getMapUnit(civInfo)
val unit = baseUnit.getMapUnit(civInfo)
fun getPassableNeighbours(tile: Tile): Set<Tile> =
tile.neighbors.filter { unit.movement.canPassThrough(it) }.toSet()

View File

@ -208,7 +208,7 @@ class TileInfoImprovementFunctions(val tile: Tile) {
val city = tile.owningCity
if (city != null) {
city.cityStats.update()
if (civToActivateBroaderEffects!=null) city.civ.cache.updateCivResources()
city.civ.cache.updateCivResources()
city.reassignPopulationDeferred()
}
}

View File

@ -645,7 +645,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
return true
}
cityConstructions.addBuilding(name)
cityConstructions.addBuilding(this)
return true
}

View File

@ -209,23 +209,13 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
override fun postBuildEvent(cityConstructions: CityConstructions, boughtWith: Stat?): Boolean {
val civInfo = cityConstructions.city.civ
val unit = civInfo.units.placeUnitNearTile(cityConstructions.city.location, name)
val unit = civInfo.units.addUnit(this, cityConstructions.city)
?: return false // couldn't place the unit, so there's actually no unit =(
//movement penalty
if (boughtWith != null && !civInfo.gameInfo.gameParameters.godMode && !unit.hasUnique(UniqueType.MoveImmediatelyOnceBought))
unit.currentMovement = 0f
// If this unit has special abilities that need to be kept track of, start doing so here
if (unit.hasUnique(UniqueType.ReligiousUnit) && civInfo.gameInfo.isReligionEnabled()) {
unit.religion =
if (unit.hasUnique(UniqueType.TakeReligionOverBirthCity))
civInfo.religionManager.religion?.name
else cityConstructions.city.religion.getMajorityReligionName()
unit.setupAbilityUses(cityConstructions.city)
}
if (this.isCivilian()) return true // tiny optimization makes save files a few bytes smaller
addConstructionBonuses(unit, cityConstructions)

View File

@ -456,7 +456,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
private fun cannotAddConstructionToQueue(construction: IConstruction, city: City, cityConstructions: CityConstructions): Boolean {
return cityConstructions.isQueueFull()
|| !cityConstructions.getConstruction(construction.name).isBuildable(cityConstructions)
|| !construction.isBuildable(cityConstructions)
|| !cityScreen.canChangeState
|| construction is PerpetualConstruction && cityConstructions.isBeingConstructedOrEnqueued(construction.name)
|| city.isPuppet
@ -631,7 +631,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
) {
SoundPlayer.play(stat.purchaseSound)
val city = cityScreen.city
if (!city.cityConstructions.purchaseConstruction(construction.name, selectedQueueEntry, false, stat, tile)) {
if (!city.cityConstructions.purchaseConstruction(construction, selectedQueueEntry, false, stat, tile)) {
Popup(cityScreen).apply {
add("No space available to place [${construction.name}] near [${city.name}]".tr()).row()
addCloseButton()

View File

@ -111,7 +111,7 @@ class ConstructionInfoTable(val cityScreen: CityScreen): Table() {
cityScreen.update()
}
) {
cityScreen.city.sellBuilding(construction.name)
cityScreen.city.sellBuilding(construction)
cityScreen.clearSelection()
cityScreen.update()
}.open()

View File

@ -91,7 +91,7 @@ class ReligionOverviewTab(
if (manager.canGenerateProphet(ignoreFaithAmount = true)) {
add("Minimal Faith required for\nthe next [great prophet equivalent]:"
.fillPlaceholders(manager.getGreatProphetEquivalent()!!)
.fillPlaceholders(manager.getGreatProphetEquivalent()!!.name)
.toLabel()
)
add(

View File

@ -44,7 +44,7 @@ class GreatPersonPickerScreen(val civInfo:Civilization) : PickerScreen() {
}
private fun confirmAction(useMayaLongCount: Boolean){
civInfo.units.addUnit(theChosenOne!!.name, civInfo.getCapital())
civInfo.units.addUnit(theChosenOne!!, civInfo.getCapital())
civInfo.greatPeople.freeGreatPeople--
if (useMayaLongCount) {
civInfo.greatPeople.mayaLimitedFreeGP--

View File

@ -350,13 +350,13 @@ object UnitActions {
title = title,
action = {
unit.destroy()
val newUnit = civInfo.units.placeUnitNearTile(unitTile.position, unitToTransformTo.name)
val newUnit = civInfo.units.placeUnitNearTile(unitTile.position, unitToTransformTo)
/** We were UNABLE to place the new unit, which means that the unit failed to upgrade!
* The only known cause of this currently is "land units upgrading to water units" which fail to be placed.
*/
if (newUnit == null) {
val resurrectedUnit = civInfo.units.placeUnitNearTile(unitTile.position, unit.name)!!
val resurrectedUnit = civInfo.units.placeUnitNearTile(unitTile.position, unit.baseUnit)!!
unit.copyStatisticsTo(resurrectedUnit)
} else { // Managed to upgrade
unit.copyStatisticsTo(newUnit)

View File

@ -67,7 +67,7 @@ object UnitActionsUpgrade {
newResourceRequirements = resourceRequirementsDelta,
action = {
unit.destroy(destroyTransportedUnit = false)
val newUnit = civInfo.units.placeUnitNearTile(unitTile.position, upgradedUnit.name)
val newUnit = civInfo.units.placeUnitNearTile(unitTile.position, upgradedUnit)
/** We were UNABLE to place the new unit, which means that the unit failed to upgrade!
* The only known cause of this currently is "land units upgrading to water units" which fail to be placed.
@ -77,7 +77,7 @@ object UnitActionsUpgrade {
* The only known cause of this currently is "land units upgrading to water units" which fail to be placed.
*/
if (newUnit == null) {
val resurrectedUnit = civInfo.units.placeUnitNearTile(unitTile.position, unit.name)!!
val resurrectedUnit = civInfo.units.placeUnitNearTile(unitTile.position, unit.baseUnit)!!
unit.copyStatisticsTo(resurrectedUnit)
} else { // Managed to upgrade
if (!isFree) civInfo.addGold(-goldCostOfUpgrade)

View File

@ -119,7 +119,7 @@ class CityTest {
fun `should get resources from unique buildings`() {
// given
val building = testGame.createBuilding("Provides [4] [Iron]")
capitalCity.cityConstructions.addBuilding(building.name)
capitalCity.cityConstructions.addBuilding(building)
// when
val cityResources = capitalCity.getCityResources()

View File

@ -31,9 +31,9 @@ class GlobalUniquesTests {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val city = game.addCity(civInfo, tile, true)
val buildingName = game.createBuilding("[+1 Food]").name
val building = game.createBuilding("[+1 Food]")
city.cityConstructions.addBuilding(buildingName)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.equals(Stats(food=1f)))
}
@ -59,9 +59,9 @@ class GlobalUniquesTests {
val civInfo = game.addCiv()
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val city = game.addCity(civInfo, tile, true)
val buildingName = game.createBuilding("[+1 Production] [in this city]").name
val building = game.createBuilding("[+1 Production] [in this city]")
city.cityConstructions.addBuilding(buildingName)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.equals(Stats(production=1f)))
}
@ -76,7 +76,7 @@ class GlobalUniquesTests {
building.specialistSlots.add(specialistName, 2)
city.population.specialistAllocations[specialistName] = 2
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Specialists"]!!.equals(Stats(gold=6f)))
}
@ -88,7 +88,7 @@ class GlobalUniquesTests {
val city = game.addCity(civInfo, tile, true, initialPopulation = 4)
val building = game.createBuilding("[+3 Gold] per [2] population [in this city]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.gold == 6f)
}
@ -100,7 +100,7 @@ class GlobalUniquesTests {
val city = game.addCity(civInfo, tile, true, initialPopulation = 2)
val building = game.createBuilding("[+3 Gold] <in cities with at least [3] [Population]>")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.gold == 0f)
@ -115,7 +115,7 @@ class GlobalUniquesTests {
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val city = game.addCity(civInfo, tile, true)
val building = game.createBuilding("[+3 Gold] in cities on [${Constants.desert}] tiles")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.gold == 3f)
@ -131,7 +131,7 @@ class GlobalUniquesTests {
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val city = game.addCity(civInfo, tile, true)
val building = game.createBuilding("[+4 Gold] from [${Constants.grassland}] tiles [in all cities]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
Assert.assertTrue(tile2.stats.getTileStats(city, civInfo).gold == 4f)
@ -144,7 +144,7 @@ class GlobalUniquesTests {
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val city = game.addCity(civInfo, tile, true)
val building = game.createBuilding("[+4 Gold] from [${Constants.grassland}] tiles without [${Constants.forest}] [in this city]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
game.addTileToCity(city, tile2)
@ -164,26 +164,26 @@ class GlobalUniquesTests {
val specialist = game.createSpecialist()
val building = game.createBuilding("[+3 Faith] from every [${specialist}]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.population.specialistAllocations[specialist] = 2
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Specialists"]!!.faith == 6f)
city.cityConstructions.removeBuilding(building.name)
city.cityConstructions.removeBuilding(building)
val building2 = game.createBuilding("[+3 Faith] from every [${Constants.grassland}]")
city.cityConstructions.addBuilding(building2.name)
city.cityConstructions.addBuilding(building2)
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
Assert.assertTrue(tile2.stats.getTileStats(city, civInfo).faith == 3f)
city.cityConstructions.removeBuilding(building2.name)
city.cityConstructions.removeBuilding(building2)
val emptyBuilding = game.createBuilding()
val building3 = game.createBuilding("[+3 Faith] from every [${emptyBuilding.name}]")
city.cityConstructions.addBuilding(emptyBuilding.name)
city.cityConstructions.addBuilding(building3.name)
city.cityConstructions.addBuilding(emptyBuilding)
city.cityConstructions.addBuilding(building3)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.faith == 3f)
}
@ -283,7 +283,7 @@ class GlobalUniquesTests {
val tile = game.getTile(Vector2(0f, 0f))
val city = game.addCity(civ, tile, true)
val building = game.createBuilding("[+10 Science]", "[+200]% [Science]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.science == 30f)
@ -295,7 +295,7 @@ class GlobalUniquesTests {
val tile = game.getTile(Vector2(0f, 0f))
val city = game.addCity(civ, tile, true)
val building = game.createBuilding("[+10 Science]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.science == 30f)
@ -314,13 +314,13 @@ class GlobalUniquesTests {
val city = game.addCity(civInfo, tile, true)
val faithBuilding = game.createBuilding()
faithBuilding.faith = 3f
city.cityConstructions.addBuilding(faithBuilding.name)
city.cityConstructions.addBuilding(faithBuilding)
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
tile2.changeImprovement("Farm")
Assert.assertTrue(tile2.stats.getTileStats(city, civInfo).faith == 9f)
city.cityConstructions.addBuilding(emptyBuilding.name)
city.cityConstructions.addBuilding(emptyBuilding)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.faith == 9f)
@ -339,13 +339,13 @@ class GlobalUniquesTests {
val city = game.addCity(civInfo, tile, true)
val faithBuilding = game.createBuilding()
faithBuilding.faith = 3f
city.cityConstructions.addBuilding(faithBuilding.name)
city.cityConstructions.addBuilding(faithBuilding)
val tile2 = game.setTileFeatures(Vector2(0f,1f), Constants.grassland)
tile2.changeImprovement("Farm")
Assert.assertTrue(tile2.stats.getTileStats(city, civInfo).faith == 9f)
city.cityConstructions.addBuilding(emptyBuilding.name)
city.cityConstructions.addBuilding(emptyBuilding)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["Buildings"]!!.faith == 9f)
@ -391,7 +391,7 @@ class GlobalUniquesTests {
Assert.assertTrue(city.cityStats.finalStatList[Constants.cityStates]!!.food == 3f)
val building = game.createBuilding("[+100]% [Food] from City-States")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList[Constants.cityStates]!!.food == 6f)
}
@ -431,7 +431,7 @@ class GlobalUniquesTests {
val city = game.addCity(civInfo, tile, true, 1)
val building = game.createBuilding("Nullifies [Faith] [in this city]", "[+10 Gold, +10 Faith] [in this city]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList.map { it.value.gold }.sum() >= 10f)
Assert.assertTrue(city.cityStats.finalStatList.map { it.value.faith }.sum() == 0f)
@ -445,7 +445,7 @@ class GlobalUniquesTests {
val city = game.addCity(civInfo, tile, true, 1)
val building = game.createBuilding("Nullifies Growth [in this city]", "[+10 Food, +10 Gold] [in this city]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList.map { it.value.gold }.sum() >= 10f)
Assert.assertTrue(city.cityStats.finalStatList.map { it.value.food }.sum() == 0f)
@ -467,7 +467,7 @@ class GlobalUniquesTests {
val buildingToConstruct = game.createBuilding()
val building = game.createBuilding("[+300]% Production when constructing [${buildingToConstruct.name}] buildings [in all cities]", "[+1 Production]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityConstructions.addToQueue(buildingToConstruct.name)
city.cityStats.update()
Assert.assertTrue(city.cityStats.statPercentBonusTree.totalStats.production == 300f)
@ -481,7 +481,7 @@ class GlobalUniquesTests {
val unitToConstruct = game.createBaseUnit()
val building = game.createBuilding("[+300]% Production when constructing [${unitToConstruct.name}] units [in all cities]", "[+1 Production]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityConstructions.addToQueue(unitToConstruct.name)
city.cityStats.update()
Assert.assertTrue(city.cityStats.statPercentBonusTree.totalStats.production == 300f)
@ -495,7 +495,7 @@ class GlobalUniquesTests {
val buildingToConstruct = game.createBuilding()
val building = game.createBuilding("[+300]% Production when constructing [${buildingToConstruct.name}] wonders [in all cities]", "[+1 Production]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityConstructions.addToQueue(buildingToConstruct.name)
city.cityStats.update()
Assert.assertTrue(city.cityStats.statPercentBonusTree.totalStats.production == 0f)
@ -518,7 +518,7 @@ class GlobalUniquesTests {
city2.cityStats.update()
Assert.assertTrue(city2.cityStats.statPercentBonusTree.totalStats.production == 0f)
city.cityConstructions.addBuilding(buildingToConstruct.name)
city.cityConstructions.addBuilding(buildingToConstruct)
city2.cityStats.update()
Assert.assertTrue(city2.cityStats.statPercentBonusTree.totalStats.production == 300f)
}
@ -535,7 +535,7 @@ class GlobalUniquesTests {
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val city = game.addCity(civInfo, tile, true)
val building = game.createBuilding("[+100]% growth [in all cities]")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
Assert.assertTrue(city.cityStats.finalStatList["[Buildings] ([Growth])"]!!.equals(Stats(food=2f)))
@ -604,7 +604,7 @@ class GlobalUniquesTests {
val specialist = game.createSpecialist()
building.specialistSlots[specialist] = 2
city.population.specialistAllocations[specialist] = 2
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
city.cityStats.update()
println(city.cityStats.happinessList)
@ -624,7 +624,7 @@ class GlobalUniquesTests {
val city = game.addCity(civInfo, tile, true)
val unit = game.addUnit("Great Engineer", civInfo, tile)
val building = game.createBuilding("[+250 Gold] whenever a Great Person is expended")
city.cityConstructions.addBuilding(building.name)
city.cityConstructions.addBuilding(building)
civInfo.addGold(-civInfo.gold) // reset gold just to be sure

View File

@ -15,7 +15,7 @@ class ResourceTests {
@Test
fun testConsumesResourceUnique() {
val consumesCoal = game.createBuilding("Consumes [1] [Coal]")
city.cityConstructions.addBuilding(consumesCoal.name)
city.cityConstructions.addBuilding(consumesCoal)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == -1)
}
@ -25,13 +25,13 @@ class ResourceTests {
val doubleCoal = game.createBuilding("Double quantity of [Coal] produced")
val doubleStrategic = game.createBuilding("Quantity of strategic resources produced by the empire +[100]%")
city.cityConstructions.addBuilding(consumesCoal.name)
city.cityConstructions.addBuilding(consumesCoal)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == -1)
city.cityConstructions.addBuilding(doubleCoal.name)
city.cityConstructions.addBuilding(doubleCoal)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == -1)
city.cityConstructions.addBuilding(doubleStrategic.name)
city.cityConstructions.addBuilding(doubleStrategic)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == -1)
}
@ -42,16 +42,16 @@ class ResourceTests {
val doubleCoal = game.createBuilding("Double quantity of [Coal] produced")
val doubleStrategic = game.createBuilding("Quantity of strategic resources produced by the empire +[100]%")
city.cityConstructions.addBuilding(providesCoal.name)
city.cityConstructions.addBuilding(providesCoal)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == 1)
city.cityConstructions.addBuilding(doubleCoal.name)
city.cityConstructions.addBuilding(doubleCoal)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == 2)
city.cityConstructions.addBuilding(doubleStrategic.name)
city.cityConstructions.addBuilding(doubleStrategic)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == 4)
city.cityConstructions.addBuilding(consumesCoal.name)
city.cityConstructions.addBuilding(consumesCoal)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == 3) // Produce 4 (1*2*2), consume 1
}
@ -59,7 +59,7 @@ class ResourceTests {
fun testBuildingGrantedByUniqueGrantsResource() {
val resourceProvider = game.createBuilding("Provides [1] [Coal]")
val resourceProviderProvider = game.createBuilding("Gain a free [${resourceProvider.name}] [in this city]")
city.cityConstructions.addBuilding(resourceProviderProvider.name)
city.cityConstructions.addBuilding(resourceProviderProvider)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == 1)
}
@ -67,8 +67,8 @@ class ResourceTests {
fun testTileProvidesResourceOnlyWithRequiredTech() {
val tile = game.tileMap[1,1]
tile.resource = "Coal"
tile.improvement = "Mine"
tile.resourceAmount = 1
tile.changeImprovement("Mine")
civInfo.tech.addTechnology(game.ruleset.tileImprovements["Mine"]!!.techRequired!!)
Assert.assertEquals(civInfo.getCivResourcesByName()["Coal"], 0)
@ -83,8 +83,8 @@ class ResourceTests {
fun testTileDoesNotProvideResourceWithPillagedImprovement() {
val tile = game.tileMap[1,1]
tile.resource = "Coal"
tile.improvement = "Mine"
tile.resourceAmount = 1
tile.changeImprovement("Mine")
civInfo.tech.addTechnology(game.ruleset.tileImprovements["Mine"]!!.techRequired!!)
civInfo.tech.addTechnology(game.ruleset.tileResources["Coal"]!!.revealedBy!!)
@ -99,8 +99,7 @@ class ResourceTests {
fun testImprovementProvidesResourceEvenWithoutTech() {
val tile = game.tileMap[1,1]
val improvement = game.createTileImprovement("Provides [1] [Coal]", "Consumes [1] [Silver]")
tile.improvement = improvement.name
civInfo.cache.updateCivResources()
tile.changeImprovement(improvement.name)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == 1)
Assert.assertTrue(civInfo.getCivResourcesByName()["Silver"] == -1)
}
@ -110,16 +109,15 @@ class ResourceTests {
fun testImprovementProvidesResourceWithUniqueBonuses() {
val tile = game.tileMap[1,1]
val improvement = game.createTileImprovement("Provides [1] [Coal]")
tile.improvement = improvement.name
civInfo.cache.updateCivResources()
tile.changeImprovement(improvement.name)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == 1)
val doubleCoal = game.createBuilding("Double quantity of [Coal] produced")
city.cityConstructions.addBuilding(doubleCoal.name)
city.cityConstructions.addBuilding(doubleCoal)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == 2)
val doubleStrategic = game.createBuilding("Quantity of strategic resources produced by the empire +[100]%")
city.cityConstructions.addBuilding(doubleStrategic.name)
city.cityConstructions.addBuilding(doubleStrategic)
Assert.assertTrue(civInfo.getCivResourcesByName()["Coal"] == 4)
}
}

View File

@ -147,7 +147,7 @@ class TestGame {
// Add a capital indicator without any other stats
val palaceWithoutStats = createBuilding(UniqueType.IndicatesCapital.text)
city.cityConstructions.removeBuilding("Palace")
city.cityConstructions.addBuilding(palaceWithoutStats.name)
city.cityConstructions.addBuilding(palaceWithoutStats)
}
return city
}