Allow trading stockpiled resources

This commit is contained in:
yairm210 2025-03-06 20:15:35 +02:00
parent a94b6fdf18
commit b4cfb50ca7
10 changed files with 55 additions and 5 deletions

View File

@ -349,6 +349,7 @@ Introduction to [nation] =
Declare war on [nation] =
Luxury resources =
Strategic resources =
Stockpiled resources =
Owned by you: [amountOwned] =
Non-existent city =

View File

@ -449,7 +449,7 @@ class Civilization : IsPartOfGameInfoSerialization {
/** Preserves some origins for resources so we can separate them for trades
* Stockpiled uniques cannot be traded currently
*/
fun getCivResourcesWithOriginsForTrade(): ResourceSupplyList {
fun getPerTurnResourcesWithOriginsForTrade(): ResourceSupplyList {
val newResourceSupplyList = ResourceSupplyList(keepZeroAmounts = true)
for (resourceSupply in detailedCivResources) {
@ -465,6 +465,20 @@ class Civilization : IsPartOfGameInfoSerialization {
}
return newResourceSupplyList
}
fun getStockpiledResourcesForTrade(): ResourceSupplyList {
val newResourceSupplyList = ResourceSupplyList(keepZeroAmounts = false)
for (resourceSupply in detailedCivResources) {
val resource = resourceSupply.resource
if (!resource.isStockpiled) continue
if (resource.hasUnique(UniqueType.CannotBeTraded, state)) continue
if (!resource.hasUnique(UniqueType.AiWillSellAt, state) && !resource.hasUnique(UniqueType.AiWillBuyAt, state)) continue
newResourceSupplyList.add(resource, Constants.tradable, resourceSupply.amount)
}
return newResourceSupplyList
}
fun isCapitalConnectedToCity(city: City): Boolean = cache.citiesConnectedToCapitalToMediums.keys.contains(city)

View File

@ -288,7 +288,7 @@ class TurnManager(val civInfo: Civilization) {
} while (civInfo.gold <= -200 && nextTurnStats.gold.toInt() < 0)
}
civInfo.addGold( nextTurnStats.gold.toInt() )
civInfo.addGold(nextTurnStats.gold.toInt() )
if (civInfo.cities.isNotEmpty() && civInfo.gameInfo.ruleset.technologies.isNotEmpty())
civInfo.tech.endTurn(nextTurnStats.science.toInt())

View File

@ -10,6 +10,7 @@ import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
import com.unciv.logic.map.tile.Tile
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.ui.components.extensions.toPercent
import com.unciv.ui.screens.victoryscreen.RankingType
@ -67,6 +68,7 @@ class TradeEvaluation {
TradeOfferType.Agreement -> true
TradeOfferType.Luxury_Resource -> hasResource(tradeOffer)
TradeOfferType.Strategic_Resource -> hasResource(tradeOffer)
TradeOfferType.Stockpiled_Resource -> hasResource(tradeOffer)
TradeOfferType.Technology -> true
TradeOfferType.Introduction -> !tradePartner.knows(tradeOffer.name) // You can't introduce them to someone they already know!
TradeOfferType.WarDeclaration -> offerer.getDiplomacyManager(tradeOffer.name)!!.canDeclareWar()
@ -167,6 +169,13 @@ class TradeEvaluation {
return 50 * amountToBuyInOffer
}
TradeOfferType.Stockpiled_Resource -> {
val resource = civInfo.gameInfo.ruleset.tileResources[offer.name] ?: return 0
val lowestBuyCost = resource.getMatchingUniques(UniqueType.AiWillBuyAt, StateForConditionals(civInfo))
.minOfOrNull { it.params[0].toInt() }
return lowestBuyCost ?: 0
}
TradeOfferType.Technology -> // Currently unused
return (sqrt(civInfo.gameInfo.ruleset.technologies[offer.name]!!.cost.toDouble())
@ -290,6 +299,14 @@ class TradeEvaluation {
}
return totalCost
}
TradeOfferType.Stockpiled_Resource -> {
val resource = civInfo.gameInfo.ruleset.tileResources[offer.name] ?: return 0
val lowestSellCost = resource.getMatchingUniques(UniqueType.AiWillSellAt, StateForConditionals(civInfo))
.minOfOrNull { it.params[0].toInt() }
return lowestSellCost ?: Int.MAX_VALUE
}
TradeOfferType.Technology -> return sqrt(civInfo.gameInfo.ruleset.technologies[offer.name]!!.cost.toDouble()).toInt() * 20
TradeOfferType.Introduction -> return introductionValue(civInfo.gameInfo.ruleset)
TradeOfferType.WarDeclaration -> {

View File

@ -38,7 +38,7 @@ class TradeLogic(val ourCivilization: Civilization, val otherCivilization: Civil
if (civInfo.diplomacyFunctions.canSignDefensivePactWith(otherCivilization))
offers.add(TradeOffer(Constants.defensivePact, TradeOfferType.Treaty, speed = civInfo.gameInfo.speed))
for (entry in civInfo.getCivResourcesWithOriginsForTrade()
for (entry in civInfo.getPerTurnResourcesWithOriginsForTrade()
.filterNot { it.resource.resourceType == ResourceType.Bonus }
.filter { it.origin == Constants.tradable }
) {
@ -46,6 +46,10 @@ class TradeLogic(val ourCivilization: Civilization, val otherCivilization: Civil
else TradeOfferType.Strategic_Resource
offers.add(TradeOffer(entry.resource.name, resourceTradeOfferType, entry.amount, speed = civInfo.gameInfo.speed))
}
for (entry in civInfo.getStockpiledResourcesForTrade()){
offers.add(TradeOffer(entry.resource.name, TradeOfferType.Stockpiled_Resource, entry.amount, speed = civInfo.gameInfo.speed))
}
offers.add(TradeOffer("Gold", TradeOfferType.Gold, civInfo.gold, speed = civInfo.gameInfo.speed))
offers.add(TradeOffer("Gold per turn", TradeOfferType.Gold_Per_Turn, civInfo.stats.statsForNextTurn.gold.toInt(), civInfo.gameInfo.speed))

View File

@ -14,6 +14,7 @@ enum class TradeOfferType(val numberType: TradeTypeNumberType, val isImmediate:
Agreement (TradeTypeNumberType.Simple, false),
Luxury_Resource (TradeTypeNumberType.Simple, false),
Strategic_Resource (TradeTypeNumberType.Simple, false),
Stockpiled_Resource (TradeTypeNumberType.Simple, true),
Technology (TradeTypeNumberType.None, true),
Introduction (TradeTypeNumberType.None, true),
WarDeclaration (TradeTypeNumberType.None, true),

View File

@ -621,6 +621,8 @@ enum class UniqueType(
LuxurySpecialPlacement("Special placement during map generation", UniqueTarget.Resource, flags = UniqueFlag.setOfHiddenToUsers),
ResourceFrequency("Generated on every [amount] tiles", UniqueTarget.Resource, flags = UniqueFlag.setOfHiddenToUsers),
StrategicBalanceResource("Guaranteed with Strategic Balance resource option", UniqueTarget.Resource),
AiWillSellAt("AI will sell at [amount] Gold", UniqueTarget.Resource, flags = UniqueFlag.setOfHiddenToUsers),
AiWillBuyAt("AI will buy at [amount] Gold", UniqueTarget.Resource, flags = UniqueFlag.setOfHiddenToUsers),
////// Improvement uniques
ImprovementBuildableByFreshWater("Can also be built on tiles adjacent to fresh water", UniqueTarget.Improvement),

View File

@ -102,9 +102,9 @@ class OfferColumnsTable(
fun update() {
val ourFilteredOffers = tradeLogic.ourAvailableOffers.without(tradeLogic.currentTrade.ourOffers)
val theirFilteredOffers = tradeLogic.theirAvailableOffers.without(tradeLogic.currentTrade.theirOffers)
val ourUntradables = tradeLogic.ourCivilization.getCivResourcesWithOriginsForTrade()
val ourUntradables = tradeLogic.ourCivilization.getPerTurnResourcesWithOriginsForTrade()
.removeAll(Constants.tradable)
val theirUntradables = tradeLogic.otherCivilization.getCivResourcesWithOriginsForTrade()
val theirUntradables = tradeLogic.otherCivilization.getPerTurnResourcesWithOriginsForTrade()
.removeAll(Constants.tradable)
ourAvailableOffersTable.update(ourFilteredOffers, tradeLogic.theirAvailableOffers, ourUntradables, ourCiv, theirCiv)
ourOffersTable.update(tradeLogic.currentTrade.ourOffers, tradeLogic.theirAvailableOffers, ourCiv = ourCiv, theirCiv = theirCiv)

View File

@ -60,6 +60,7 @@ class OffersListScroll(
Gold, Gold_Per_Turn, Treaty, Agreement, Introduction -> ""
Luxury_Resource -> "Luxury resources"
Strategic_Resource -> "Strategic resources"
Stockpiled_Resource -> "Stockpiled resources"
Technology -> "Technologies"
WarDeclaration -> "Declarations of war"
City -> "Cities"

View File

@ -2612,6 +2612,16 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
??? example "Guaranteed with Strategic Balance resource option"
Applicable to: Resource
??? example "AI will sell at [amount] Gold"
Example: "AI will sell at [3] Gold"
Applicable to: Resource
??? example "AI will buy at [amount] Gold"
Example: "AI will buy at [3] Gold"
Applicable to: Resource
??? example "Will not be displayed in Civilopedia"
Applicable to: Nation, Tech, Policy, FounderBelief, FollowerBelief, Building, Unit, UnitType, Promotion, Terrain, Improvement, Resource, Ruins, Speed, EventChoice