Separated trade logic from UI display
This commit is contained in:
parent
d8bb0eb9e5
commit
d8daf6dc88
5 changed files with 177 additions and 167 deletions
146
core/src/com/unciv/logic/trade/TradeLogic.kt
Normal file
146
core/src/com/unciv/logic/trade/TradeLogic.kt
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
package com.unciv.logic.trade
|
||||||
|
|
||||||
|
import com.unciv.UnCivGame
|
||||||
|
import com.unciv.logic.battle.CityCombatant
|
||||||
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
|
import com.unciv.logic.civilization.DiplomaticStatus
|
||||||
|
import com.unciv.models.gamebasics.GameBasics
|
||||||
|
import com.unciv.models.gamebasics.tile.ResourceType
|
||||||
|
import com.unciv.ui.utils.tr
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
class TradeLogic(val otherCivilization: CivilizationInfo){
|
||||||
|
val civInfo = UnCivGame.Current.gameInfo.getPlayerCivilization()
|
||||||
|
|
||||||
|
val ourAvailableOffers = getAvailableOffers(civInfo,otherCivilization)
|
||||||
|
val theirAvailableOffers = getAvailableOffers(otherCivilization,civInfo)
|
||||||
|
val currentTrade = Trade()
|
||||||
|
|
||||||
|
fun getAvailableOffers(civInfo: CivilizationInfo, otherCivilization: CivilizationInfo): TradeOffersList {
|
||||||
|
val offers = TradeOffersList()
|
||||||
|
if(civInfo.isAtWarWith(otherCivilization))
|
||||||
|
offers.add(TradeOffer("Peace Treaty", TradeType.Treaty, 20, 1))
|
||||||
|
for(entry in civInfo.getCivResources().filterNot { it.key.resourceType == ResourceType.Bonus }) {
|
||||||
|
val resourceTradeType = if(entry.key.resourceType== ResourceType.Luxury) TradeType.Luxury_Resource
|
||||||
|
else TradeType.Strategic_Resource
|
||||||
|
offers.add(TradeOffer(entry.key.name, resourceTradeType, 30, entry.value))
|
||||||
|
}
|
||||||
|
for(entry in civInfo.tech.techsResearched
|
||||||
|
.filterNot { otherCivilization.tech.isResearched(it) }
|
||||||
|
.filter { otherCivilization.tech.canBeResearched(it) }){
|
||||||
|
offers.add(TradeOffer(entry, TradeType.Technology, 0, 1))
|
||||||
|
}
|
||||||
|
offers.add(TradeOffer("Gold".tr(), TradeType.Gold, 0, civInfo.gold))
|
||||||
|
offers.add(TradeOffer("Gold per turn".tr(), TradeType.Gold_Per_Turn, 30, civInfo.getStatsForNextTurn().gold.toInt()))
|
||||||
|
for(city in civInfo.cities.filterNot { it.isCapital() })
|
||||||
|
offers.add(TradeOffer(city.name, TradeType.City, 0, 1))
|
||||||
|
return offers
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun isTradeAcceptable(): Boolean {
|
||||||
|
val sumOfTheirOffers = currentTrade.theirOffers.filter { it.type!= TradeType.Treaty } // since treaties should only be evaluated once for 2 sides
|
||||||
|
.map { evaluateOffer(it,false) }.sum()
|
||||||
|
val sumOfOurOffers = currentTrade.ourOffers.map { evaluateOffer(it,true)}.sum()
|
||||||
|
return sumOfOurOffers >= sumOfTheirOffers
|
||||||
|
}
|
||||||
|
|
||||||
|
fun evaluateOffer(offer: TradeOffer, otherCivIsRecieving:Boolean): Int {
|
||||||
|
when(offer.type) {
|
||||||
|
TradeType.Gold -> return offer.amount
|
||||||
|
TradeType.Gold_Per_Turn -> return offer.amount*offer.duration
|
||||||
|
TradeType.Luxury_Resource -> {
|
||||||
|
if(!otherCivIsRecieving){ // they're giving us
|
||||||
|
var value = 300*offer.amount
|
||||||
|
if(!theirAvailableOffers.any { it.name==offer.name }) // We want to take away their last luxury or give them one they don't have
|
||||||
|
value += 400
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
var value = 50*offer.amount // they'll buy at 50 each only, and that's so they can trade it away
|
||||||
|
if(!theirAvailableOffers.any { it.name==offer.name })
|
||||||
|
value+=250 // only if they're lacking will they buy the first one at 300
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
TradeType.Technology -> return sqrt(GameBasics.Technologies[offer.name]!!.cost.toDouble()).toInt()*10
|
||||||
|
TradeType.Strategic_Resource -> return 50 * offer.amount
|
||||||
|
TradeType.City -> {
|
||||||
|
val civ = if(otherCivIsRecieving) civInfo else otherCivilization
|
||||||
|
val city = civ.cities.first { it.name==offer.name }
|
||||||
|
val stats = city.cityStats.currentCityStats
|
||||||
|
val sumOfStats = stats.culture+stats.gold+stats.science+stats.production+stats.happiness+stats.food
|
||||||
|
return sumOfStats.toInt() * 100
|
||||||
|
}
|
||||||
|
TradeType.Treaty -> {
|
||||||
|
if(offer.name=="Peace Treaty")
|
||||||
|
return evaluatePeaceCostForThem() // Since it will be evaluated twice, once when they evaluate our offer and once when they evaluate theirs
|
||||||
|
else return 1000
|
||||||
|
}
|
||||||
|
// Dunno what this is?
|
||||||
|
else -> return 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun evaluteCombatStrength(civInfo: CivilizationInfo): Int {
|
||||||
|
// Since units become exponentially stronger per combat strength increase, we square em all
|
||||||
|
fun square(x:Int) = x*x
|
||||||
|
val unitStrength = civInfo.getCivUnits().map { square(max(it.getBaseUnit().strength, it.getBaseUnit().rangedStrength)) }.sum()
|
||||||
|
val cityStrength = civInfo.cities.map { square(CityCombatant(it).getCityStrength()) }.sum()
|
||||||
|
return (sqrt(unitStrength.toDouble()) /*+ sqrt(cityStrength.toDouble())*/).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun evaluatePeaceCostForThem(): Int {
|
||||||
|
val ourCombatStrength = evaluteCombatStrength(civInfo)
|
||||||
|
val theirCombatStrength = evaluteCombatStrength(otherCivilization)
|
||||||
|
if(ourCombatStrength==theirCombatStrength) return 0
|
||||||
|
if(ourCombatStrength==0) return 1000
|
||||||
|
if(theirCombatStrength==0) return -1000 // Chumps got no cities or units
|
||||||
|
if(ourCombatStrength>theirCombatStrength){
|
||||||
|
val absoluteAdvantage = ourCombatStrength-theirCombatStrength
|
||||||
|
val percentageAdvantage = absoluteAdvantage / theirCombatStrength.toFloat()
|
||||||
|
return (absoluteAdvantage*percentageAdvantage).toInt() * 10
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
val absoluteAdvantage = theirCombatStrength-ourCombatStrength
|
||||||
|
val percentageAdvantage = absoluteAdvantage / ourCombatStrength.toFloat()
|
||||||
|
return -(absoluteAdvantage*percentageAdvantage).toInt() * 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun acceptTrade() {
|
||||||
|
|
||||||
|
civInfo.diplomacy[otherCivilization.civName]!!.trades.add(currentTrade)
|
||||||
|
otherCivilization.diplomacy[civInfo.civName]!!.trades.add(currentTrade.reverse())
|
||||||
|
|
||||||
|
// instant transfers
|
||||||
|
fun transfer(us: CivilizationInfo, them: CivilizationInfo, trade: Trade) {
|
||||||
|
for (offer in trade.theirOffers) {
|
||||||
|
if (offer.type == TradeType.Gold) {
|
||||||
|
us.gold += offer.amount
|
||||||
|
them.gold -= offer.amount
|
||||||
|
}
|
||||||
|
if (offer.type == TradeType.Technology) {
|
||||||
|
us.tech.techsResearched.add(offer.name)
|
||||||
|
}
|
||||||
|
if(offer.type== TradeType.City){
|
||||||
|
val city = them.cities.first { it.name==offer.name }
|
||||||
|
city.moveToCiv(us)
|
||||||
|
city.getCenterTile().getUnits().forEach { it.movementAlgs().teleportToClosestMoveableTile() }
|
||||||
|
}
|
||||||
|
if(offer.type== TradeType.Treaty){
|
||||||
|
if(offer.name=="Peace Treaty"){
|
||||||
|
us.diplomacy[them.civName]!!.diplomaticStatus= DiplomaticStatus.Peace
|
||||||
|
for(unit in us.getCivUnits().filter { it.getTile().getOwner()==them })
|
||||||
|
unit.movementAlgs().teleportToClosestMoveableTile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transfer(civInfo,otherCivilization,currentTrade)
|
||||||
|
transfer(otherCivilization,civInfo,currentTrade.reverse())
|
||||||
|
}
|
||||||
|
}
|
12
core/src/com/unciv/logic/trade/TradeOffer.kt
Normal file
12
core/src/com/unciv/logic/trade/TradeOffer.kt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package com.unciv.logic.trade
|
||||||
|
|
||||||
|
data class TradeOffer(var name:String, var type: TradeType, var duration:Int, var amount:Int) {
|
||||||
|
|
||||||
|
constructor() : this("", TradeType.Gold,0,0) // so that the json deserializer can work
|
||||||
|
|
||||||
|
fun equals(offer: TradeOffer): Boolean {
|
||||||
|
return offer.name==name
|
||||||
|
&& offer.type==type
|
||||||
|
&& offer.amount==amount
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package com.unciv.logic.trade
|
package com.unciv.logic.trade
|
||||||
|
|
||||||
import com.unciv.ui.TradeOffer
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class TradeOffersList: ArrayList<TradeOffer>(){
|
class TradeOffersList: ArrayList<TradeOffer>(){
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package com.unciv.logic.trade
|
package com.unciv.ui
|
||||||
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
|
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||||
|
import com.unciv.logic.trade.TradeOffersList
|
||||||
|
import com.unciv.logic.trade.TradeType
|
||||||
import com.unciv.ui.utils.CameraStageBaseScreen
|
import com.unciv.ui.utils.CameraStageBaseScreen
|
||||||
import com.unciv.ui.utils.addClickListener
|
import com.unciv.ui.utils.addClickListener
|
||||||
import com.unciv.ui.utils.disable
|
import com.unciv.ui.utils.disable
|
||||||
|
@ -10,7 +12,7 @@ import com.unciv.ui.utils.tr
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class OffersList(val offers: TradeOffersList, val correspondingOffers: TradeOffersList,
|
class OffersList(val offers: TradeOffersList, val correspondingOffers: TradeOffersList,
|
||||||
val otherCivOffers: TradeOffersList, val otherCivCorrespondingOffers:TradeOffersList,
|
val otherCivOffers: TradeOffersList, val otherCivCorrespondingOffers: TradeOffersList,
|
||||||
val onChange: () -> Unit) : ScrollPane(null) {
|
val onChange: () -> Unit) : ScrollPane(null) {
|
||||||
val table= Table(CameraStageBaseScreen.skin).apply { defaults().pad(5f) }
|
val table= Table(CameraStageBaseScreen.skin).apply { defaults().pad(5f) }
|
||||||
init {
|
init {
|
||||||
|
@ -33,7 +35,7 @@ class OffersList(val offers: TradeOffersList, val correspondingOffers: TradeOffe
|
||||||
val amountTransferred = min(amountPerClick, offer.amount)
|
val amountTransferred = min(amountPerClick, offer.amount)
|
||||||
offers += offer.copy(amount = -amountTransferred)
|
offers += offer.copy(amount = -amountTransferred)
|
||||||
correspondingOffers += offer.copy(amount = amountTransferred)
|
correspondingOffers += offer.copy(amount = amountTransferred)
|
||||||
if(offer.type==TradeType.Treaty) { // this goes both ways, so it doesn't matter which side you click
|
if(offer.type== TradeType.Treaty) { // this goes both ways, so it doesn't matter which side you click
|
||||||
otherCivOffers += offer.copy(amount = -amountTransferred)
|
otherCivOffers += offer.copy(amount = -amountTransferred)
|
||||||
otherCivCorrespondingOffers += offer.copy(amount = amountTransferred)
|
otherCivCorrespondingOffers += offer.copy(amount = amountTransferred)
|
||||||
}
|
}
|
|
@ -4,39 +4,13 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||||
import com.unciv.UnCivGame
|
import com.unciv.UnCivGame
|
||||||
import com.unciv.logic.battle.CityCombatant
|
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
import com.unciv.logic.civilization.DiplomaticStatus
|
import com.unciv.logic.trade.TradeLogic
|
||||||
import com.unciv.logic.trade.OffersList
|
|
||||||
import com.unciv.logic.trade.Trade
|
|
||||||
import com.unciv.logic.trade.TradeOffersList
|
|
||||||
import com.unciv.logic.trade.TradeType
|
|
||||||
import com.unciv.models.gamebasics.GameBasics
|
|
||||||
import com.unciv.models.gamebasics.tile.ResourceType
|
|
||||||
import com.unciv.ui.utils.*
|
import com.unciv.ui.utils.*
|
||||||
import kotlin.math.max
|
|
||||||
import kotlin.math.sqrt
|
|
||||||
|
|
||||||
|
class TradeScreen(otherCivilization: CivilizationInfo) : CameraStageBaseScreen(){
|
||||||
|
|
||||||
data class TradeOffer(var name:String, var type: TradeType, var duration:Int, var amount:Int) {
|
val tradeLogic = TradeLogic(otherCivilization)
|
||||||
|
|
||||||
constructor() : this("", TradeType.Gold,0,0) // so that the json deserializer can work
|
|
||||||
|
|
||||||
fun equals(offer:TradeOffer): Boolean {
|
|
||||||
return offer.name==name
|
|
||||||
&& offer.type==type
|
|
||||||
&& offer.amount==amount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TradeScreen(val otherCivilization: CivilizationInfo) : CameraStageBaseScreen(){
|
|
||||||
|
|
||||||
val civInfo = UnCivGame.Current.gameInfo.getPlayerCivilization()
|
|
||||||
val ourAvailableOffers = getAvailableOffers(civInfo,otherCivilization)
|
|
||||||
val theirAvailableOffers = getAvailableOffers(otherCivilization,civInfo)
|
|
||||||
val currentTrade = Trade()
|
|
||||||
|
|
||||||
val table = Table(skin)
|
val table = Table(skin)
|
||||||
val tradeText = Label("What do you have in mind?".tr(),skin)
|
val tradeText = Label("What do you have in mind?".tr(),skin)
|
||||||
val offerButton = TextButton("Offer trade".tr(),skin)
|
val offerButton = TextButton("Offer trade".tr(),skin)
|
||||||
|
@ -48,18 +22,16 @@ class TradeScreen(val otherCivilization: CivilizationInfo) : CameraStageBaseScre
|
||||||
tradeText.setText("What do you have in mind?".tr())
|
tradeText.setText("What do you have in mind?".tr())
|
||||||
}
|
}
|
||||||
|
|
||||||
val ourAvailableOffersTable = OffersList(ourAvailableOffers, currentTrade.ourOffers,
|
val ourAvailableOffersTable = OffersList(tradeLogic.ourAvailableOffers, tradeLogic.currentTrade.ourOffers,
|
||||||
theirAvailableOffers, currentTrade.theirOffers) { onChange() }
|
tradeLogic.theirAvailableOffers, tradeLogic.currentTrade.theirOffers) { onChange() }
|
||||||
val ourOffersTable = OffersList(currentTrade.ourOffers, ourAvailableOffers,
|
val ourOffersTable = OffersList(tradeLogic.currentTrade.ourOffers, tradeLogic.ourAvailableOffers,
|
||||||
currentTrade.theirOffers, theirAvailableOffers) { onChange() }
|
tradeLogic.currentTrade.theirOffers, tradeLogic.theirAvailableOffers) { onChange() }
|
||||||
val theirOffersTable = OffersList(currentTrade.theirOffers, theirAvailableOffers,
|
val theirOffersTable = OffersList(tradeLogic.currentTrade.theirOffers, tradeLogic.theirAvailableOffers,
|
||||||
currentTrade.ourOffers, ourAvailableOffers) { onChange() }
|
tradeLogic.currentTrade.ourOffers, tradeLogic.ourAvailableOffers) { onChange() }
|
||||||
val theirAvailableOffersTable = OffersList(theirAvailableOffers, currentTrade.theirOffers,
|
val theirAvailableOffersTable = OffersList(tradeLogic.theirAvailableOffers, tradeLogic.currentTrade.theirOffers,
|
||||||
ourAvailableOffers, currentTrade.ourOffers) { onChange() }
|
tradeLogic.ourAvailableOffers, tradeLogic.currentTrade.ourOffers) { onChange() }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val peaceCost = evaluatePeaceCostForThem()
|
|
||||||
|
|
||||||
val closeButton = TextButton("Close".tr(), skin)
|
val closeButton = TextButton("Close".tr(), skin)
|
||||||
closeButton.addClickListener { UnCivGame.Current.setWorldScreen() }
|
closeButton.addClickListener { UnCivGame.Current.setWorldScreen() }
|
||||||
closeButton.y = stage.height - closeButton.height - 5
|
closeButton.y = stage.height - closeButton.height - 5
|
||||||
|
@ -72,10 +44,10 @@ class TradeScreen(val otherCivilization: CivilizationInfo) : CameraStageBaseScre
|
||||||
|
|
||||||
offerButton.addClickListener {
|
offerButton.addClickListener {
|
||||||
if(offerButton.text.toString() == "Offer trade".tr()) {
|
if(offerButton.text.toString() == "Offer trade".tr()) {
|
||||||
if(currentTrade.theirOffers.size==0 && currentTrade.ourOffers.size==0){
|
if(tradeLogic.currentTrade.theirOffers.size==0 && tradeLogic.currentTrade.ourOffers.size==0){
|
||||||
tradeText.setText("There's nothing on the table.".tr())
|
tradeText.setText("There's nothing on the table.".tr())
|
||||||
}
|
}
|
||||||
else if (isTradeAcceptable(currentTrade)){
|
else if (tradeLogic.isTradeAcceptable()){
|
||||||
tradeText.setText("That is acceptable.".tr())
|
tradeText.setText("That is acceptable.".tr())
|
||||||
offerButton.setText("Accept".tr())
|
offerButton.setText("Accept".tr())
|
||||||
}
|
}
|
||||||
|
@ -84,37 +56,7 @@ class TradeScreen(val otherCivilization: CivilizationInfo) : CameraStageBaseScre
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(offerButton.text.toString() == "Accept".tr()){
|
else if(offerButton.text.toString() == "Accept".tr()){
|
||||||
civInfo.diplomacy[otherCivilization.civName]!!.trades.add(currentTrade)
|
tradeLogic.acceptTrade()
|
||||||
otherCivilization.diplomacy[civInfo.civName]!!.trades.add(currentTrade.reverse())
|
|
||||||
|
|
||||||
// instant transfers
|
|
||||||
fun transfer(us: CivilizationInfo,them:CivilizationInfo, trade: Trade) {
|
|
||||||
for (offer in trade.theirOffers) {
|
|
||||||
if (offer.type == TradeType.Gold) {
|
|
||||||
us.gold += offer.amount
|
|
||||||
them.gold -= offer.amount
|
|
||||||
}
|
|
||||||
if (offer.type == TradeType.Technology) {
|
|
||||||
us.tech.techsResearched.add(offer.name)
|
|
||||||
}
|
|
||||||
if(offer.type==TradeType.City){
|
|
||||||
val city = them.cities.first { it.name==offer.name }
|
|
||||||
city.moveToCiv(us)
|
|
||||||
city.getCenterTile().getUnits().forEach { it.movementAlgs().teleportToClosestMoveableTile() }
|
|
||||||
}
|
|
||||||
if(offer.type==TradeType.Treaty){
|
|
||||||
if(offer.name=="Peace Treaty"){
|
|
||||||
us.diplomacy[them.civName]!!.diplomaticStatus=DiplomaticStatus.Peace
|
|
||||||
for(unit in us.getCivUnits().filter { it.getTile().getOwner()==them })
|
|
||||||
unit.movementAlgs().teleportToClosestMoveableTile()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transfer(civInfo,otherCivilization,currentTrade)
|
|
||||||
transfer(otherCivilization,civInfo,currentTrade.reverse())
|
|
||||||
|
|
||||||
val newTradeScreen = TradeScreen(otherCivilization)
|
val newTradeScreen = TradeScreen(otherCivilization)
|
||||||
newTradeScreen.tradeText.setText("Pleasure doing business with you!".tr())
|
newTradeScreen.tradeText.setText("Pleasure doing business with you!".tr())
|
||||||
UnCivGame.Current.screen = newTradeScreen
|
UnCivGame.Current.screen = newTradeScreen
|
||||||
|
@ -151,96 +93,5 @@ class TradeScreen(val otherCivilization: CivilizationInfo) : CameraStageBaseScre
|
||||||
theirOffersTable.update()
|
theirOffersTable.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAvailableOffers(civInfo: CivilizationInfo, otherCivilization: CivilizationInfo): TradeOffersList {
|
|
||||||
val offers = TradeOffersList()
|
|
||||||
if(civInfo.isAtWarWith(otherCivilization))
|
|
||||||
offers.add(TradeOffer("Peace Treaty",TradeType.Treaty,20,1))
|
|
||||||
for(entry in civInfo.getCivResources().filterNot { it.key.resourceType == ResourceType.Bonus }) {
|
|
||||||
val resourceTradeType = if(entry.key.resourceType==ResourceType.Luxury) TradeType.Luxury_Resource
|
|
||||||
else TradeType.Strategic_Resource
|
|
||||||
offers.add(TradeOffer(entry.key.name, resourceTradeType, 30, entry.value))
|
|
||||||
}
|
|
||||||
for(entry in civInfo.tech.techsResearched
|
|
||||||
.filterNot { otherCivilization.tech.isResearched(it) }
|
|
||||||
.filter { otherCivilization.tech.canBeResearched(it) }){
|
|
||||||
offers.add(TradeOffer(entry, TradeType.Technology,0,1))
|
|
||||||
}
|
|
||||||
offers.add(TradeOffer("Gold".tr(), TradeType.Gold,0,civInfo.gold))
|
|
||||||
offers.add(TradeOffer("Gold per turn".tr(), TradeType.Gold_Per_Turn,30,civInfo.getStatsForNextTurn().gold.toInt()))
|
|
||||||
for(city in civInfo.cities.filterNot { it.isCapital() })
|
|
||||||
offers.add(TradeOffer(city.name,TradeType.City,0,1))
|
|
||||||
return offers
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isTradeAcceptable(trade: Trade): Boolean {
|
|
||||||
val sumOfTheirOffers = trade.theirOffers.filter { it.type!=TradeType.Treaty } // since treaties should only be evaluated once for 2 sides
|
|
||||||
.map { evaluateOffer(it,false) }.sum()
|
|
||||||
val sumOfOurOffers = trade.ourOffers.map { evaluateOffer(it,true)}.sum()
|
|
||||||
return sumOfOurOffers >= sumOfTheirOffers
|
|
||||||
}
|
|
||||||
|
|
||||||
fun evaluateOffer(offer:TradeOffer, otherCivIsRecieving:Boolean): Int {
|
|
||||||
when(offer.type) {
|
|
||||||
TradeType.Gold -> return offer.amount
|
|
||||||
TradeType.Gold_Per_Turn -> return offer.amount*offer.duration
|
|
||||||
TradeType.Luxury_Resource -> {
|
|
||||||
if(!otherCivIsRecieving){ // they're giving us
|
|
||||||
var value = 300*offer.amount
|
|
||||||
if(!theirAvailableOffers.any { it.name==offer.name }) // We want to take away their last luxury or give them one they don't have
|
|
||||||
value += 400
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
var value = 50*offer.amount // they'll buy at 50 each only, and that's so they can trade it away
|
|
||||||
if(!theirAvailableOffers.any { it.name==offer.name })
|
|
||||||
value+=250 // only if they're lacking will they buy the first one at 300
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
TradeType.Technology -> return sqrt(GameBasics.Technologies[offer.name]!!.cost.toDouble()).toInt()*10
|
|
||||||
TradeType.Strategic_Resource -> return 50 * offer.amount
|
|
||||||
TradeType.City -> {
|
|
||||||
val civ = if(otherCivIsRecieving) civInfo else otherCivilization
|
|
||||||
val city = civ.cities.first { it.name==offer.name }
|
|
||||||
val stats = city.cityStats.currentCityStats
|
|
||||||
val sumOfStats = stats.culture+stats.gold+stats.science+stats.production+stats.happiness+stats.food
|
|
||||||
return sumOfStats.toInt() * 100
|
|
||||||
}
|
|
||||||
TradeType.Treaty -> {
|
|
||||||
if(offer.name=="Peace Treaty")
|
|
||||||
return evaluatePeaceCostForThem() // Since it will be evaluated twice, once when they evaluate our offer and once when they evaluate theirs
|
|
||||||
else return 1000
|
|
||||||
}
|
|
||||||
// Dunno what this is?
|
|
||||||
else -> return 1000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun evaluteCombatStrength(civInfo: CivilizationInfo): Int {
|
|
||||||
// Since units become exponentially stronger per combat strength increase, we square em all
|
|
||||||
fun square(x:Int) = x*x
|
|
||||||
val unitStrength = civInfo.getCivUnits().map { square(max(it.getBaseUnit().strength,it.getBaseUnit().rangedStrength)) }.sum()
|
|
||||||
val cityStrength = civInfo.cities.map { square(CityCombatant(it).getCityStrength()) }.sum()
|
|
||||||
return (sqrt(unitStrength.toDouble()) /*+ sqrt(cityStrength.toDouble())*/).toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun evaluatePeaceCostForThem(): Int {
|
|
||||||
val ourCombatStrength = evaluteCombatStrength(civInfo)
|
|
||||||
val theirCombatStrength = evaluteCombatStrength(otherCivilization)
|
|
||||||
if(ourCombatStrength==theirCombatStrength) return 0
|
|
||||||
if(ourCombatStrength==0) return 1000
|
|
||||||
if(theirCombatStrength==0) return -1000 // Chumps got no cities or units
|
|
||||||
if(ourCombatStrength>theirCombatStrength){
|
|
||||||
val absoluteAdvantage = ourCombatStrength-theirCombatStrength
|
|
||||||
val percentageAdvantage = absoluteAdvantage / theirCombatStrength.toFloat()
|
|
||||||
return (absoluteAdvantage*percentageAdvantage).toInt() * 10
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
val absoluteAdvantage = theirCombatStrength-ourCombatStrength
|
|
||||||
val percentageAdvantage = absoluteAdvantage / ourCombatStrength.toFloat()
|
|
||||||
return -(absoluteAdvantage*percentageAdvantage).toInt() * 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue