diff --git a/core/src/com/unciv/logic/trade/TradeEvaluation.kt b/core/src/com/unciv/logic/trade/TradeEvaluation.kt index 402f779bb9..c7363af8a7 100644 --- a/core/src/com/unciv/logic/trade/TradeEvaluation.kt +++ b/core/src/com/unciv/logic/trade/TradeEvaluation.kt @@ -6,6 +6,8 @@ import com.unciv.logic.automation.ThreatLevel import com.unciv.logic.city.CityInfo import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.diplomacy.RelationshipLevel +import com.unciv.models.ruleset.ModOptionsConstants +import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.tile.ResourceType import kotlin.math.min import kotlin.math.sqrt @@ -21,32 +23,32 @@ class TradeEvaluation { return false for (offer in trade.ourOffers) - if (!isOfferValid(offer, offerer)) + if (!isOfferValid(offer, offerer, tradePartner)) return false for (offer in trade.theirOffers) - if (!isOfferValid(offer, tradePartner)) + if (!isOfferValid(offer, tradePartner, offerer)) return false return true } - private fun isOfferValid(tradeOffer: TradeOffer, offerer: CivilizationInfo): Boolean { + private fun isOfferValid(tradeOffer: TradeOffer, offerer: CivilizationInfo, tradePartner: CivilizationInfo): Boolean { fun hasResource(tradeOffer: TradeOffer): Boolean { val resourcesByName = offerer.getCivResourcesByName() return resourcesByName.containsKey(tradeOffer.name) && resourcesByName[tradeOffer.name]!! >= 0 } - when (tradeOffer.type) { - TradeType.Gold -> return true // even if they go negative it's okay - TradeType.Gold_Per_Turn -> return true // even if they go negative it's okay - TradeType.Treaty -> return true - TradeType.Agreement -> return true - TradeType.Luxury_Resource -> return hasResource(tradeOffer) - TradeType.Strategic_Resource -> return hasResource(tradeOffer) - TradeType.Technology -> return true - TradeType.Introduction -> return true - TradeType.WarDeclaration -> return true - TradeType.City -> return offerer.cities.any { it.id == tradeOffer.name } + return when (tradeOffer.type) { + TradeType.Gold -> true // even if they go negative it's okay + TradeType.Gold_Per_Turn -> true // even if they go negative it's okay + TradeType.Treaty -> true + TradeType.Agreement -> true + TradeType.Luxury_Resource -> hasResource(tradeOffer) + TradeType.Strategic_Resource -> hasResource(tradeOffer) + TradeType.Technology -> true + TradeType.Introduction -> !tradePartner.knows(tradeOffer.name) // You can't introduce them to someone they already know! + TradeType.WarDeclaration -> true + TradeType.City -> offerer.cities.any { it.id == tradeOffer.name } } } @@ -68,7 +70,7 @@ class TradeEvaluation { return sumOfOurOffers <= sumOfTheirOffers } - fun evaluateBuyCost(offer: TradeOffer, civInfo: CivilizationInfo, tradePartner: CivilizationInfo): Int { + private fun evaluateBuyCost(offer: TradeOffer, civInfo: CivilizationInfo, tradePartner: CivilizationInfo): Int { when (offer.type) { TradeType.Gold -> return offer.amount TradeType.Gold_Per_Turn -> return offer.amount * offer.duration @@ -131,7 +133,7 @@ class TradeEvaluation { TradeType.Technology -> return (sqrt(civInfo.gameInfo.ruleSet.technologies[offer.name]!!.cost.toDouble()) * civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt() * 20 - TradeType.Introduction -> return 250 + TradeType.Introduction -> return introductionValue(civInfo.gameInfo.ruleSet) TradeType.WarDeclaration -> { val civToDeclareWarOn = civInfo.gameInfo.getCivilization(offer.name) val threatToThem = Automation.threatAssessment(civInfo, civToDeclareWarOn) @@ -160,7 +162,7 @@ class TradeEvaluation { } } } - fun surroundedByOurCities(city: CityInfo, civInfo: CivilizationInfo): Int{ + private fun surroundedByOurCities(city: CityInfo, civInfo: CivilizationInfo): Int{ val borderingCivs: List = city.getNeighbouringCivs() if (borderingCivs.size == 1 && borderingCivs.contains(civInfo.civName)){ return 10*civInfo.getEraNumber() // if the city is surrounded only by trading civ @@ -171,7 +173,7 @@ class TradeEvaluation { } - fun evaluateSellCost(offer: TradeOffer, civInfo: CivilizationInfo, tradePartner: CivilizationInfo): Int { + private fun evaluateSellCost(offer: TradeOffer, civInfo: CivilizationInfo, tradePartner: CivilizationInfo): Int { when (offer.type) { TradeType.Gold -> return offer.amount TradeType.Gold_Per_Turn -> return offer.amount * offer.duration @@ -213,7 +215,7 @@ class TradeEvaluation { return totalCost } TradeType.Technology -> return sqrt(civInfo.gameInfo.ruleSet.technologies[offer.name]!!.cost.toDouble()).toInt() * 20 - TradeType.Introduction -> return 250 + TradeType.Introduction -> return introductionValue(civInfo.gameInfo.ruleSet) TradeType.WarDeclaration -> { val civToDeclareWarOn = civInfo.gameInfo.getCivilization(offer.name) val threatToUs = Automation.threatAssessment(civInfo, civToDeclareWarOn) @@ -274,4 +276,9 @@ class TradeEvaluation { } } + private fun introductionValue(ruleSet: Ruleset): Int { + val unique = ruleSet.modOptions.uniqueObjects.firstOrNull{ it.placeholderText == ModOptionsConstants.tradeCivIntroductions } + if (unique == null) return 0 + return unique.params[0].toInt() + } } \ No newline at end of file diff --git a/core/src/com/unciv/logic/trade/TradeLogic.kt b/core/src/com/unciv/logic/trade/TradeLogic.kt index bb4aa8959a..39f99db8fc 100644 --- a/core/src/com/unciv/logic/trade/TradeLogic.kt +++ b/core/src/com/unciv/logic/trade/TradeLogic.kt @@ -13,7 +13,7 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci val theirAvailableOffers = getAvailableOffers(otherCivilization, ourCivilization) val currentTrade = Trade() - fun getAvailableOffers(civInfo: CivilizationInfo, otherCivilization: CivilizationInfo): TradeOffersList { + private fun getAvailableOffers(civInfo: CivilizationInfo, otherCivilization: CivilizationInfo): TradeOffersList { val offers = TradeOffersList() if (civInfo.isCityState() && otherCivilization.isCityState()) return offers if (civInfo.isAtWarWith(otherCivilization)) @@ -43,12 +43,14 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci } val otherCivsWeKnow = civInfo.getKnownCivs() - .filter { it.civName != otherCivilization.civName && it.isMajorCiv() && !it.isDefeated() } - val civsWeKnowAndTheyDont = otherCivsWeKnow - .filter { !otherCivilization.diplomacy.containsKey(it.civName) && !it.isDefeated() } + .filter { it.civName != otherCivilization.civName && it.isMajorCiv() && !it.isDefeated() } - for (thirdCiv in civsWeKnowAndTheyDont) { - offers.add(TradeOffer(thirdCiv.civName, TradeType.Introduction)) + if (civInfo.gameInfo.ruleSet.modOptions.uniqueObjects.any{ it.placeholderText == ModOptionsConstants.tradeCivIntroductions }) { + val civsWeKnowAndTheyDont = otherCivsWeKnow + .filter { !otherCivilization.diplomacy.containsKey(it.civName) && !it.isDefeated() } + for (thirdCiv in civsWeKnowAndTheyDont) { + offers.add(TradeOffer(thirdCiv.civName, TradeType.Introduction)) + } } if (!civInfo.isCityState() && !otherCivilization.isCityState() @@ -106,7 +108,6 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci } if (offer.type == TradeType.Introduction) to.makeCivilizationsMeet(to.gameInfo.getCivilization(offer.name)) - if (offer.type == TradeType.WarDeclaration) { val nameOfCivToDeclareWarOn = offer.name from.getDiplomacyManager(nameOfCivToDeclareWarOn).declareWar() diff --git a/core/src/com/unciv/models/ruleset/Ruleset.kt b/core/src/com/unciv/models/ruleset/Ruleset.kt index 525da72c69..9b145defd9 100644 --- a/core/src/com/unciv/models/ruleset/Ruleset.kt +++ b/core/src/com/unciv/models/ruleset/Ruleset.kt @@ -25,9 +25,10 @@ object ModOptionsConstants { const val diplomaticRelationshipsCannotChange = "Diplomatic relationships cannot change" const val convertGoldToScience = "Can convert gold to science with sliders" const val allowCityStatesSpawnUnits = "Allow City States to spawn with additional units" + const val tradeCivIntroductions = "Can trade civilization introductions for [] Gold" } -class ModOptions { +class ModOptions : IHasUniques { var isBaseRuleset = false var techsToRemove = HashSet() var buildingsToRemove = HashSet() @@ -41,7 +42,10 @@ class ModOptions { var modSize = 0 val maxXPfromBarbarians = 30 - var uniques = HashSet() // No reason for now to use IHasUniques here, in that case needs to change to ArrayList + + override var uniques = ArrayList() + // If this is delegated with "by lazy", the mod download process crashes and burns + override var uniqueObjects: List = listOf() } class Ruleset { @@ -145,6 +149,7 @@ class Ruleset { try { modOptions = jsonParser.getFromJson(ModOptions::class.java, modOptionsFile) } catch (ex: Exception) {} + modOptions.uniqueObjects = modOptions.uniques.map { Unique(it) } } val techFile = folderHandle.child("Techs.json") diff --git a/core/src/com/unciv/ui/trade/OffersListScroll.kt b/core/src/com/unciv/ui/trade/OffersListScroll.kt index c402355a6f..10de655ff4 100644 --- a/core/src/com/unciv/ui/trade/OffersListScroll.kt +++ b/core/src/com/unciv/ui/trade/OffersListScroll.kt @@ -29,7 +29,7 @@ class OffersListScroll(val onOfferClicked: (TradeOffer) -> Unit) : ScrollPane(nu for (offerType in values()) { val labelName = when(offerType){ - Gold, Gold_Per_Turn, Treaty,Agreement,Introduction -> "" + Gold, Gold_Per_Turn, Treaty, Agreement, Introduction -> "" Luxury_Resource -> "Luxury resources" Strategic_Resource -> "Strategic resources" Technology -> "Technologies"