mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-13 09:18:43 +07:00
Resolved #3384 - Civ uniques now take all researched tech uniques!
This commit is contained in:
@ -102,7 +102,7 @@ class CityStats {
|
||||
private fun getStatPercentBonusesFromComputers(): Stats {
|
||||
val stats = Stats()
|
||||
|
||||
if (cityInfo.civInfo.tech.getTechUniques().contains("+10% science and production in all cities")) {
|
||||
if (cityInfo.civInfo.hasUnique("+10% science and production in all cities")) {
|
||||
stats.production += 10f
|
||||
stats.science += 10f
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ open class PerpetualConstruction(override var name: String, val description: Str
|
||||
const val CONVERSION_RATE: Int = 4
|
||||
val science = object : PerpetualConstruction("Science", "Convert production to science at a rate of [rate] to 1") {
|
||||
override fun isBuildable(cityConstructions: CityConstructions): Boolean {
|
||||
return cityConstructions.cityInfo.civInfo.tech.getTechUniques().contains("Enables conversion of city production to science")
|
||||
return cityConstructions.cityInfo.civInfo.hasUnique("Enables conversion of city production to science")
|
||||
}
|
||||
override fun getProductionTooltip(cityInfo: CityInfo): String {
|
||||
return "\r\n${(cityInfo.cityStats.currentCityStats.production / getConversionRate(cityInfo)).roundToInt()}/${Fonts.turn}"
|
||||
@ -41,7 +41,7 @@ open class PerpetualConstruction(override var name: String, val description: Str
|
||||
}
|
||||
val gold = object : PerpetualConstruction("Gold", "Convert production to gold at a rate of $CONVERSION_RATE to 1") {
|
||||
override fun isBuildable(cityConstructions: CityConstructions): Boolean {
|
||||
return cityConstructions.cityInfo.civInfo.tech.getTechUniques().contains("Enables conversion of city production to gold")
|
||||
return cityConstructions.cityInfo.civInfo.hasUnique("Enables conversion of city production to gold")
|
||||
}
|
||||
}
|
||||
val idle = object : PerpetualConstruction("Nothing", "The city will not produce anything.") {
|
||||
|
@ -11,7 +11,6 @@ import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.trade.TradeEvaluation
|
||||
@ -34,6 +33,7 @@ class CivilizationInfo {
|
||||
|
||||
@Transient
|
||||
lateinit var gameInfo: GameInfo
|
||||
|
||||
@Transient
|
||||
lateinit var nation: Nation
|
||||
|
||||
@ -44,8 +44,10 @@ class CivilizationInfo {
|
||||
*/
|
||||
@Transient
|
||||
private var units = listOf<MapUnit>()
|
||||
|
||||
@Transient
|
||||
var viewableTiles = setOf<TileInfo>()
|
||||
|
||||
@Transient
|
||||
var viewableInvisibleUnitsTiles = setOf<TileInfo>()
|
||||
|
||||
@ -56,14 +58,18 @@ class CivilizationInfo {
|
||||
/** This is for performance since every movement calculation depends on this, see MapUnit comment */
|
||||
@Transient
|
||||
var hasActiveGreatWall = false
|
||||
|
||||
@Transient
|
||||
var statsForNextTurn = Stats()
|
||||
|
||||
@Transient
|
||||
var happinessForNextTurn = 0
|
||||
|
||||
@Transient
|
||||
var detailedCivResources = ResourceSupplyList()
|
||||
|
||||
var playerType = PlayerType.AI
|
||||
|
||||
/** Used in online multiplayer for human players */
|
||||
var playerId = ""
|
||||
var gold = 0
|
||||
@ -223,7 +229,8 @@ class CivilizationInfo {
|
||||
fun getMatchingUniques(uniqueTemplate: String): Sequence<Unique> {
|
||||
return nation.uniqueObjects.asSequence().filter { it.placeholderText == uniqueTemplate } +
|
||||
cities.asSequence().flatMap { it.cityConstructions.builtBuildingUniqueMap.getUniques(uniqueTemplate).asSequence() } +
|
||||
policies.policyUniques.getUniques(uniqueTemplate)
|
||||
policies.policyUniques.getUniques(uniqueTemplate) +
|
||||
tech.getTechUniques()
|
||||
}
|
||||
|
||||
//region Units
|
||||
@ -365,7 +372,7 @@ class CivilizationInfo {
|
||||
|
||||
fun canSignResearchAgreement(): Boolean {
|
||||
if (!isMajorCiv()) return false
|
||||
if (!tech.getTechUniques().contains("Enables Research agreements")) return false
|
||||
if (!hasUnique("Enables Research agreements")) return false
|
||||
if (gameInfo.ruleSet.technologies.values
|
||||
.none { tech.canBeResearched(it.name) && !tech.isResearched(it.name) }) return false
|
||||
return true
|
||||
|
@ -2,7 +2,6 @@ package com.unciv.logic.civilization
|
||||
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.map.MapSize
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.models.ruleset.Unique
|
||||
@ -17,18 +16,26 @@ import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class TechManager {
|
||||
@Transient lateinit var civInfo: CivilizationInfo
|
||||
@Transient var researchedTechnologies = ArrayList<Technology>()
|
||||
@Transient private var researchedTechUniques = ArrayList<String>()
|
||||
@Transient
|
||||
lateinit var civInfo: CivilizationInfo
|
||||
@Transient
|
||||
var researchedTechnologies = ArrayList<Technology>()
|
||||
@Transient
|
||||
private var researchedTechUniques = ArrayList<Unique>()
|
||||
|
||||
// MapUnit.canPassThrough is the most called function in the game, and having these extremey specific booleans is or way of improving the time cost
|
||||
@Transient var wayfinding = false
|
||||
@Transient var unitsCanEmbark = false
|
||||
@Transient var embarkedUnitsCanEnterOcean = false
|
||||
@Transient
|
||||
var wayfinding = false
|
||||
@Transient
|
||||
var unitsCanEmbark = false
|
||||
@Transient
|
||||
var embarkedUnitsCanEnterOcean = false
|
||||
|
||||
// UnitMovementAlgorithms.getMovementCostBetweenAdjacentTiles is a close second =)
|
||||
@Transient var movementSpeedOnRoadsImproved = false
|
||||
@Transient var roadsConnectAcrossRivers = false
|
||||
@Transient
|
||||
var movementSpeedOnRoadsImproved = false
|
||||
@Transient
|
||||
var roadsConnectAcrossRivers = false
|
||||
|
||||
var freeTechs = 0
|
||||
|
||||
@ -167,7 +174,7 @@ class TechManager {
|
||||
private fun scienceFromResearchAgreements(): Int {
|
||||
// https://forums.civfanatics.com/resources/research-agreements-bnw.25568/
|
||||
var researchAgreementModifier = 0.5f
|
||||
for(unique in civInfo.getMatchingUniques("Science gained from research agreements +50%"))
|
||||
for (unique in civInfo.getMatchingUniques("Science gained from research agreements +50%"))
|
||||
researchAgreementModifier += 0.25f
|
||||
return (scienceFromResearchAgreements / 3 * researchAgreementModifier).toInt()
|
||||
}
|
||||
@ -194,7 +201,7 @@ class TechManager {
|
||||
addScience(finalScienceToAdd)
|
||||
}
|
||||
|
||||
fun addScience(scienceGet : Int) {
|
||||
fun addScience(scienceGet: Int) {
|
||||
val currentTechnology = currentTechnologyName()
|
||||
if (currentTechnology == null) return
|
||||
techsInProgress[currentTechnology] = researchOfTech(currentTechnology) + scienceGet
|
||||
@ -225,7 +232,7 @@ class TechManager {
|
||||
techsToResearch.remove(techName)
|
||||
researchedTechnologies = researchedTechnologies.withItem(newTech)
|
||||
for (unique in newTech.uniques) {
|
||||
researchedTechUniques = researchedTechUniques.withItem(unique)
|
||||
researchedTechUniques = researchedTechUniques.withItem(Unique(unique))
|
||||
UniqueTriggerActivation.triggerCivwideUnique(Unique(unique), civInfo)
|
||||
}
|
||||
updateTransientBooleans()
|
||||
@ -277,12 +284,11 @@ class TechManager {
|
||||
if (constructionName in obsoleteUnits) {
|
||||
val text = "[$constructionName] has been obsolete and will be removed from construction queue in [${city.name}]!"
|
||||
civInfo.addNotification(text, city.location, Color.BROWN)
|
||||
}
|
||||
else city.cityConstructions.constructionQueue.add(newConstructionName)
|
||||
} else city.cityConstructions.constructionQueue.add(newConstructionName)
|
||||
}
|
||||
}
|
||||
|
||||
for(unique in civInfo.getMatchingUniques("Receive free [] when you discover []")) {
|
||||
for (unique in civInfo.getMatchingUniques("Receive free [] when you discover []")) {
|
||||
if (unique.params[1] != techName) continue
|
||||
civInfo.addUnit(unique.params[0])
|
||||
}
|
||||
@ -290,17 +296,17 @@ class TechManager {
|
||||
|
||||
fun setTransients() {
|
||||
researchedTechnologies.addAll(techsResearched.map { getRuleset().technologies[it]!! })
|
||||
researchedTechUniques.addAll(researchedTechnologies.flatMap { it.uniques })
|
||||
researchedTechUniques.addAll(researchedTechnologies.asSequence().flatMap { it.uniques.asSequence() }.map { Unique(it) })
|
||||
updateTransientBooleans()
|
||||
}
|
||||
|
||||
fun updateTransientBooleans() {
|
||||
wayfinding = civInfo.hasUnique("Can embark and move over Coasts and Oceans immediately")
|
||||
unitsCanEmbark = wayfinding || researchedTechUniques.contains("Enables embarkation for land units")
|
||||
unitsCanEmbark = wayfinding || civInfo.hasUnique("Enables embarkation for land units")
|
||||
|
||||
embarkedUnitsCanEnterOcean = wayfinding || researchedTechUniques.contains("Enables embarked units to enter ocean tiles")
|
||||
movementSpeedOnRoadsImproved = researchedTechUniques.contains("Improves movement speed on roads")
|
||||
roadsConnectAcrossRivers = researchedTechUniques.contains("Roads connect tiles across rivers")
|
||||
embarkedUnitsCanEnterOcean = wayfinding || civInfo.hasUnique("Enables embarked units to enter ocean tiles")
|
||||
movementSpeedOnRoadsImproved = civInfo.hasUnique("Improves movement speed on roads")
|
||||
roadsConnectAcrossRivers = civInfo.hasUnique("Roads connect tiles across rivers")
|
||||
}
|
||||
|
||||
fun getBestRoadAvailable(): RoadStatus {
|
||||
@ -308,7 +314,7 @@ class TechManager {
|
||||
if (roadImprovement == null || !isResearched(roadImprovement.techRequired!!)) return RoadStatus.None
|
||||
|
||||
val railroadImprovement = RoadStatus.Railroad.improvement(getRuleset())
|
||||
val canBuildRailroad = railroadImprovement!=null && isResearched(railroadImprovement.techRequired!!)
|
||||
val canBuildRailroad = railroadImprovement != null && isResearched(railroadImprovement.techRequired!!)
|
||||
|
||||
return if (canBuildRailroad) RoadStatus.Railroad else RoadStatus.Road
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ class MapUnit {
|
||||
|
||||
fun getEmbarkedMovement(): Int {
|
||||
var movement = 2
|
||||
movement += civInfo.tech.getTechUniques().count { it == "Increases embarked movement +1" }
|
||||
movement += civInfo.getMatchingUniques("Increases embarked movement +1").count()
|
||||
if (civInfo.hasUnique("+1 Movement for all embarked units")) movement += 1
|
||||
return movement
|
||||
}
|
||||
|
@ -8,11 +8,11 @@ import com.unciv.models.ruleset.ModOptionsConstants
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.translations.tr
|
||||
|
||||
class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: CivilizationInfo){
|
||||
class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: CivilizationInfo) {
|
||||
|
||||
/** Contains everything we could offer the other player, whether we've actually offered it or not */
|
||||
val ourAvailableOffers = getAvailableOffers(ourCivilization,otherCivilization)
|
||||
val theirAvailableOffers = getAvailableOffers(otherCivilization,ourCivilization)
|
||||
val ourAvailableOffers = getAvailableOffers(ourCivilization, otherCivilization)
|
||||
val theirAvailableOffers = getAvailableOffers(otherCivilization, ourCivilization)
|
||||
val currentTrade = Trade()
|
||||
|
||||
fun getAvailableOffers(civInfo: CivilizationInfo, otherCivilization: CivilizationInfo): TradeOffersList {
|
||||
@ -21,16 +21,16 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci
|
||||
if (civInfo.isAtWarWith(otherCivilization))
|
||||
offers.add(TradeOffer(Constants.peaceTreaty, TradeType.Treaty))
|
||||
|
||||
if(!otherCivilization.getDiplomacyManager(civInfo).hasOpenBorders
|
||||
if (!otherCivilization.getDiplomacyManager(civInfo).hasOpenBorders
|
||||
&& !otherCivilization.isCityState()
|
||||
&& civInfo.tech.getTechUniques().contains("Enables Open Borders agreements")
|
||||
&& otherCivilization.tech.getTechUniques().contains("Enables Open Borders agreements")) {
|
||||
&& civInfo.hasUnique("Enables Open Borders agreements")
|
||||
&& otherCivilization.hasUnique("Enables Open Borders agreements")) {
|
||||
offers.add(TradeOffer(Constants.openBorders, TradeType.Agreement))
|
||||
}
|
||||
|
||||
for(entry in civInfo.getCivResources()
|
||||
for (entry in civInfo.getCivResources()
|
||||
.filterNot { it.resource.resourceType == ResourceType.Bonus }) {
|
||||
val resourceTradeType = if(entry.resource.resourceType== ResourceType.Luxury) TradeType.Luxury_Resource
|
||||
val resourceTradeType = if (entry.resource.resourceType == ResourceType.Luxury) TradeType.Luxury_Resource
|
||||
else TradeType.Strategic_Resource
|
||||
offers.add(TradeOffer(entry.resource.name, resourceTradeType, entry.amount))
|
||||
}
|
||||
@ -116,5 +116,4 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci
|
||||
transferTrade(ourCivilization, otherCivilization, currentTrade)
|
||||
transferTrade(otherCivilization, ourCivilization, currentTrade.reverse())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -653,7 +653,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||
}
|
||||
displayTutorial(Tutorial.ApolloProgram) { viewingCiv.hasUnique("Enables construction of Spaceship parts") }
|
||||
displayTutorial(Tutorial.SiegeUnits) { viewingCiv.getCivUnits().any { it.type == UnitType.Siege } }
|
||||
displayTutorial(Tutorial.Embarking) { viewingCiv.tech.getTechUniques().contains("Enables embarkation for land units") }
|
||||
displayTutorial(Tutorial.Embarking) { viewingCiv.hasUnique("Enables embarkation for land units") }
|
||||
displayTutorial(Tutorial.NaturalWonders) { viewingCiv.naturalWonders.size > 0 }
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user