AI can now offer you trades - this is a big step towards proper diplomacy relations!
As of now they only offer luxury-to-luxury trades
This commit is contained in:
parent
046fe1088f
commit
5d8d7ca89b
14 changed files with 314 additions and 157 deletions
Binary file not shown.
Before Width: | Height: | Size: 968 KiB After Width: | Height: | Size: 966 KiB |
|
@ -21,8 +21,8 @@ android {
|
|||
applicationId "com.unciv.app"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 28
|
||||
versionCode 229
|
||||
versionName "2.14.9"
|
||||
versionCode 230
|
||||
versionName "2.14.10"
|
||||
}
|
||||
|
||||
// Had to add this crap for Travis to build, it wanted to sign the app
|
||||
|
|
|
@ -2,12 +2,10 @@ package com.unciv.logic.automation
|
|||
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.logic.civilization.TradeRequest
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.trade.TradeEvaluation
|
||||
import com.unciv.logic.trade.TradeLogic
|
||||
import com.unciv.logic.trade.TradeOffer
|
||||
import com.unciv.logic.trade.TradeType
|
||||
import com.unciv.logic.trade.*
|
||||
import com.unciv.models.gamebasics.GameBasics
|
||||
import com.unciv.models.gamebasics.tech.Technology
|
||||
import com.unciv.models.gamebasics.tr
|
||||
|
@ -115,30 +113,62 @@ class NextTurnAutomation{
|
|||
}
|
||||
}
|
||||
|
||||
fun potentialLuxuryTrades(civInfo:CivilizationInfo, otherCivInfo:CivilizationInfo): ArrayList<Trade> {
|
||||
val tradeLogic = TradeLogic(civInfo, otherCivInfo)
|
||||
val ourTradableLuxuryResources = tradeLogic.ourAvailableOffers
|
||||
.filter { it.type == TradeType.Luxury_Resource && it.amount > 1 }
|
||||
val theirTradableLuxuryResources = tradeLogic.theirAvailableOffers
|
||||
.filter { it.type == TradeType.Luxury_Resource && it.amount > 1 }
|
||||
val weHaveTheyDont = ourTradableLuxuryResources
|
||||
.filter { resource ->
|
||||
tradeLogic.theirAvailableOffers
|
||||
.none { it.name == resource.name && it.type == TradeType.Luxury_Resource }
|
||||
}
|
||||
val theyHaveWeDont = theirTradableLuxuryResources
|
||||
.filter { resource ->
|
||||
tradeLogic.ourAvailableOffers
|
||||
.none { it.name == resource.name && it.type == TradeType.Luxury_Resource }
|
||||
}
|
||||
val trades = ArrayList<Trade>()
|
||||
for(i in 0..min(weHaveTheyDont.lastIndex, theyHaveWeDont.lastIndex)){
|
||||
val trade = Trade()
|
||||
trade.ourOffers.add(weHaveTheyDont[i].copy(amount = 1))
|
||||
trade.theirOffers.add(theyHaveWeDont[i].copy(amount = 1))
|
||||
trades.add(trade)
|
||||
}
|
||||
return trades
|
||||
}
|
||||
|
||||
private fun exchangeLuxuries(civInfo: CivilizationInfo) {
|
||||
for (otherCiv in civInfo.diplomacy.values.map { it.otherCiv() }.filterNot { it.isPlayerCivilization() }) {
|
||||
val tradeLogic = TradeLogic(civInfo, otherCiv)
|
||||
val ourTradableLuxuryResources = tradeLogic.ourAvailableOffers
|
||||
.filter { it.type == TradeType.Luxury_Resource && it.amount > 1 }
|
||||
val theirTradableLuxuryResources = tradeLogic.theirAvailableOffers
|
||||
.filter { it.type == TradeType.Luxury_Resource && it.amount > 1 }
|
||||
val weHaveTheyDont = ourTradableLuxuryResources
|
||||
.filter { resource ->
|
||||
tradeLogic.theirAvailableOffers
|
||||
.none { it.name == resource.name && it.type == TradeType.Luxury_Resource }
|
||||
}
|
||||
val theyHaveWeDont = theirTradableLuxuryResources
|
||||
.filter { resource ->
|
||||
tradeLogic.ourAvailableOffers
|
||||
.none { it.name == resource.name && it.type == TradeType.Luxury_Resource }
|
||||
}
|
||||
val numberOfTrades = min(weHaveTheyDont.size, theyHaveWeDont.size)
|
||||
if (numberOfTrades > 0) {
|
||||
tradeLogic.currentTrade.ourOffers.addAll(weHaveTheyDont.take(numberOfTrades).map { it.copy(amount = 1) })
|
||||
tradeLogic.currentTrade.theirOffers.addAll(theyHaveWeDont.take(numberOfTrades).map { it.copy(amount = 1) })
|
||||
val knownCivs = civInfo.diplomacy.values.map { it.otherCiv() }
|
||||
|
||||
// Player trades are... more complicated.
|
||||
// When the AI offers a trade, it's not immediately accepted,
|
||||
// so what if it thinks that it has a spare luxury and offers it to two human players?
|
||||
// What's to stop the AI "nagging" the player to accept a luxury trade?
|
||||
// We should A. add some sort of timer (20? 30 turns?) between luxury trade requests if they're denied
|
||||
// B. have a way for the AI to keep track of the "pending offers" - see DiplomacyManager.resourcesFromTrade
|
||||
|
||||
for (otherCiv in knownCivs.filter { it.isPlayerCivilization() }) {
|
||||
val trades = potentialLuxuryTrades(civInfo,otherCiv)
|
||||
for(trade in trades){
|
||||
val tradeRequest = TradeRequest(civInfo.civName, trade.reverse())
|
||||
otherCiv.tradeRequests.add(tradeRequest)
|
||||
}
|
||||
}
|
||||
|
||||
// AI trades are automatically accepted
|
||||
for (otherCiv in knownCivs.filterNot { it.isPlayerCivilization() }) {
|
||||
val trades = potentialLuxuryTrades(civInfo,otherCiv)
|
||||
for(trade in trades){
|
||||
val tradeLogic = TradeLogic(civInfo,otherCiv)
|
||||
tradeLogic.currentTrade.ourOffers.addAll(trade.ourOffers)
|
||||
tradeLogic.currentTrade.theirOffers.addAll(trade.theirOffers)
|
||||
tradeLogic.acceptTrade()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fun getMinDistanceBetweenCities(civ1: CivilizationInfo, civ2: CivilizationInfo): Int {
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.unciv.logic.map.BFS
|
|||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.trade.Trade
|
||||
import com.unciv.models.Counter
|
||||
import com.unciv.models.gamebasics.Difficulty
|
||||
import com.unciv.models.gamebasics.GameBasics
|
||||
|
@ -33,18 +34,23 @@ enum class PlayerType{
|
|||
Human
|
||||
}
|
||||
|
||||
class TradeRequest(val requestingCiv:String,
|
||||
/** Their offers are what they offer us, and our offers are what they want in return */
|
||||
val trade: Trade){
|
||||
}
|
||||
|
||||
class CivilizationInfo {
|
||||
@Transient lateinit var gameInfo: GameInfo
|
||||
/**
|
||||
* never add or remove from here directly, could cause comodification problems.
|
||||
* Instead, create a copy list with the change, and replace this list.
|
||||
* We never add or remove from here directly, could cause comodification problems.
|
||||
* Instead, we create a copy list with the change, and replace this list.
|
||||
* The other solution, casting toList() every "get", has a performance cost
|
||||
*/
|
||||
@Transient private var units=ArrayList<MapUnit>()
|
||||
@Transient var viewableTiles = HashSet<TileInfo>()
|
||||
@Transient var viewableInvisibleUnitsTiles = HashSet<TileInfo>()
|
||||
@Transient private var units=listOf<MapUnit>()
|
||||
@Transient var viewableTiles = setOf<TileInfo>()
|
||||
@Transient var viewableInvisibleUnitsTiles = setOf<TileInfo>()
|
||||
|
||||
// This is for performance since every movement calculation depends on this, see MapUnit comment
|
||||
/** This is for performance since every movement calculation depends on this, see MapUnit comment */
|
||||
@Transient var hasActiveGreatWall = false
|
||||
|
||||
var gold = 0
|
||||
|
@ -61,6 +67,7 @@ class CivilizationInfo {
|
|||
var diplomacy = HashMap<String, DiplomacyManager>()
|
||||
var notifications = ArrayList<Notification>()
|
||||
val popupAlerts = ArrayList<PopupAlert>()
|
||||
val tradeRequests = ArrayList<TradeRequest>()
|
||||
|
||||
// if we only use lists, and change the list each time the cities are changed,
|
||||
// we won't get concurrent modification exceptions.
|
||||
|
@ -79,14 +86,14 @@ class CivilizationInfo {
|
|||
fun clone(): CivilizationInfo {
|
||||
val toReturn = CivilizationInfo()
|
||||
toReturn.gold = gold
|
||||
toReturn.happiness=happiness
|
||||
toReturn.playerType=playerType
|
||||
toReturn.civName=civName
|
||||
toReturn.happiness = happiness
|
||||
toReturn.playerType = playerType
|
||||
toReturn.civName = civName
|
||||
toReturn.tech = tech.clone()
|
||||
toReturn.policies = policies.clone()
|
||||
toReturn.goldenAges = goldenAges.clone()
|
||||
toReturn.greatPeople=greatPeople.clone()
|
||||
toReturn.victoryManager=victoryManager.clone()
|
||||
toReturn.greatPeople = greatPeople.clone()
|
||||
toReturn.victoryManager = victoryManager.clone()
|
||||
toReturn.diplomacy.putAll(diplomacy.values.map { it.clone() }.associateBy { it.otherCivName })
|
||||
toReturn.cities = cities.map { it.clone() }
|
||||
toReturn.exploredTiles.addAll(exploredTiles)
|
||||
|
@ -116,10 +123,7 @@ class CivilizationInfo {
|
|||
fun isPlayerCivilization() = playerType==PlayerType.Human
|
||||
fun isCurrentPlayer() = gameInfo.getCurrentPlayerCivilization()==this
|
||||
fun isBarbarianCivilization() = gameInfo.getBarbarianCivilization()==this
|
||||
|
||||
fun getStatsForNextTurn():Stats{
|
||||
return getStatMapForNextTurn().values.toList().reduce{a,b->a+b}
|
||||
}
|
||||
fun getStatsForNextTurn():Stats = getStatMapForNextTurn().values.toList().reduce{a,b->a+b}
|
||||
|
||||
fun getStatMapForNextTurn(): HashMap<String, Stats> {
|
||||
val statMap = HashMap<String,Stats>()
|
||||
|
|
|
@ -16,6 +16,8 @@ class DiplomacyManager() {
|
|||
lateinit var otherCivName:String
|
||||
var trades = ArrayList<Trade>()
|
||||
var diplomaticStatus = DiplomaticStatus.War
|
||||
/** Contains various flags (declared war, promised to not settle, declined luxury trade) and the number of turns in which they will expire */
|
||||
var flagsCountdown = HashMap<String,Int>()
|
||||
|
||||
fun clone(): DiplomacyManager {
|
||||
val toReturn = DiplomacyManager()
|
||||
|
@ -63,6 +65,11 @@ class DiplomacyManager() {
|
|||
if(offer.type== TradeType.Strategic_Resource || offer.type== TradeType.Luxury_Resource)
|
||||
counter.add(GameBasics.TileResources[offer.name]!!,offer.amount)
|
||||
}
|
||||
for(tradeRequest in otherCiv().tradeRequests.filter { it.requestingCiv==civInfo.civName }){
|
||||
for(offer in tradeRequest.trade.theirOffers) // "theirOffers" in the other civ's trade request, is actually out civ's offers
|
||||
if(offer.type== TradeType.Strategic_Resource || offer.type== TradeType.Luxury_Resource)
|
||||
counter.add(GameBasics.TileResources[offer.name]!!,-offer.amount)
|
||||
}
|
||||
return counter
|
||||
}
|
||||
//endregion
|
||||
|
@ -95,6 +102,12 @@ class DiplomacyManager() {
|
|||
}
|
||||
}
|
||||
removeUntenebleTrades()
|
||||
|
||||
for(flag in flagsCountdown.keys.toList()) {
|
||||
flagsCountdown[flag] = flagsCountdown[flag]!! - 1
|
||||
if(flagsCountdown[flag]==0) flagsCountdown.remove(flag)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun declareWar(){
|
||||
|
|
|
@ -31,4 +31,11 @@ class Trade{
|
|||
toReturn.ourOffers.addAll(ourOffers)
|
||||
return toReturn
|
||||
}
|
||||
|
||||
fun set(trade: Trade) {
|
||||
ourOffers.clear()
|
||||
ourOffers.addAll(trade.ourOffers)
|
||||
theirOffers.clear()
|
||||
theirOffers.addAll(trade.theirOffers)
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package com.unciv.logic.trade
|
||||
|
||||
import com.unciv.models.gamebasics.tr
|
||||
|
||||
data class TradeOffer(var name:String, var type: TradeType, var duration:Int, var amount:Int=1) {
|
||||
|
||||
constructor() : this("", TradeType.Gold,0,0) // so that the json deserializer can work
|
||||
|
@ -9,4 +11,18 @@ data class TradeOffer(var name:String, var type: TradeType, var duration:Int, va
|
|||
&& offer.type==type
|
||||
&& offer.amount==amount
|
||||
}
|
||||
|
||||
|
||||
fun getOfferText(): String {
|
||||
var offerText = name.tr()
|
||||
if (type !in tradesToNotHaveNumbers) offerText += " (" + amount + ")"
|
||||
if (duration > 1) offerText += "\n" + duration + " {turns}".tr()
|
||||
return offerText
|
||||
}
|
||||
|
||||
private companion object{
|
||||
val tradesToNotHaveNumbers = listOf(TradeType.Technology, TradeType.City,
|
||||
TradeType.Introduction, TradeType.Treaty, TradeType.WarDeclaration)
|
||||
}
|
||||
|
||||
}
|
|
@ -12,12 +12,13 @@ class Nation : INamed {
|
|||
else return name
|
||||
}
|
||||
|
||||
lateinit var leaderName: String
|
||||
var leaderName=""
|
||||
|
||||
lateinit var declaringWar:String
|
||||
lateinit var attacked:String
|
||||
lateinit var defeated:String
|
||||
lateinit var introduction:String
|
||||
var declaringWar=""
|
||||
var attacked=""
|
||||
var defeated=""
|
||||
var introduction=""
|
||||
var tradeRequest=""
|
||||
|
||||
var neutralLetsHearIt = ArrayList<String>()
|
||||
var neutralYes = ArrayList<String>()
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
|||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.trade.TradeLogic
|
||||
import com.unciv.models.gamebasics.tr
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.worldscreen.optionstable.PopupTable
|
||||
|
@ -59,6 +60,13 @@ class DiplomacyScreen:CameraStageBaseScreen() {
|
|||
}
|
||||
}
|
||||
|
||||
fun setTrade(civ: CivilizationInfo): TradeTable {
|
||||
rightSideTable.clear()
|
||||
val tradeTable =TradeTable(civ, stage) { updateLeftSideTable() }
|
||||
rightSideTable.add(tradeTable)
|
||||
return tradeTable
|
||||
}
|
||||
|
||||
private fun getDiplomacyTable(civ: CivilizationInfo): Table {
|
||||
val diplomacyTable = Table()
|
||||
diplomacyTable.defaults().pad(10f)
|
||||
|
@ -67,10 +75,7 @@ class DiplomacyScreen:CameraStageBaseScreen() {
|
|||
diplomacyTable.addSeparator()
|
||||
|
||||
val tradeButton = TextButton("Trade".tr(), skin)
|
||||
tradeButton.onClick {
|
||||
rightSideTable.clear()
|
||||
rightSideTable.add(TradeTable(civ, stage) { updateLeftSideTable() })
|
||||
}
|
||||
tradeButton.onClick { setTrade(civ) }
|
||||
diplomacyTable.add(tradeButton).row()
|
||||
|
||||
val currentPlayerCiv = UnCivGame.Current.gameInfo.getCurrentPlayerCivilization()
|
||||
|
|
|
@ -7,7 +7,6 @@ import com.unciv.logic.trade.TradeOffer
|
|||
import com.unciv.logic.trade.TradeOffersList
|
||||
import com.unciv.logic.trade.TradeType
|
||||
import com.unciv.logic.trade.TradeType.*
|
||||
import com.unciv.models.gamebasics.tr
|
||||
import com.unciv.ui.cityscreen.ExpanderTab
|
||||
import com.unciv.ui.utils.CameraStageBaseScreen
|
||||
import com.unciv.ui.utils.disable
|
||||
|
@ -16,8 +15,7 @@ import kotlin.math.min
|
|||
|
||||
class OffersListScroll(val onOfferClicked: (TradeOffer) -> Unit) : ScrollPane(null) {
|
||||
val table = Table(CameraStageBaseScreen.skin).apply { defaults().pad(5f) }
|
||||
val tradesToNotHaveNumbers = listOf(Technology, City,
|
||||
Introduction, Treaty, WarDeclaration)
|
||||
|
||||
|
||||
val expanderTabs = HashMap<TradeType, ExpanderTab>()
|
||||
|
||||
|
@ -50,10 +48,7 @@ class OffersListScroll(val onOfferClicked: (TradeOffer) -> Unit) : ScrollPane(nu
|
|||
}
|
||||
|
||||
for (offer in offersOfType) {
|
||||
var buttonText = offer.name.tr()
|
||||
if (offer.type !in tradesToNotHaveNumbers) buttonText += " (" + offer.amount + ")"
|
||||
if (offer.duration > 1) buttonText += "\n" + offer.duration + " {turns}".tr()
|
||||
val tradeButton = TextButton(buttonText, CameraStageBaseScreen.skin)
|
||||
val tradeButton = TextButton(offer.getOfferText(), CameraStageBaseScreen.skin)
|
||||
val amountPerClick =
|
||||
if (offer.type == Gold) 50
|
||||
else 1
|
||||
|
|
74
core/src/com/unciv/ui/worldscreen/AlertPopup.kt
Normal file
74
core/src/com/unciv/ui/worldscreen/AlertPopup.kt
Normal file
|
@ -0,0 +1,74 @@
|
|||
package com.unciv.ui.worldscreen
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.unciv.logic.civilization.AlertType
|
||||
import com.unciv.logic.civilization.PopupAlert
|
||||
import com.unciv.models.gamebasics.Nation
|
||||
import com.unciv.models.gamebasics.tr
|
||||
import com.unciv.ui.utils.addSeparator
|
||||
import com.unciv.ui.utils.onClick
|
||||
import com.unciv.ui.utils.toLabel
|
||||
import com.unciv.ui.worldscreen.optionstable.PopupTable
|
||||
|
||||
class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): PopupTable(worldScreen){
|
||||
fun getCloseButton(text:String): TextButton {
|
||||
val button = TextButton(text.tr(), skin)
|
||||
button.onClick { close() }
|
||||
return button
|
||||
}
|
||||
|
||||
fun addLeaderName(translatedNation: Nation){
|
||||
val otherCivLeaderName = "[${translatedNation.leaderName}] of [${translatedNation.getNameTranslation()}]".tr()
|
||||
add(otherCivLeaderName.toLabel())
|
||||
addSeparator()
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
when(popupAlert.type){
|
||||
AlertType.WarDeclaration -> {
|
||||
val translatedNation = worldScreen.gameInfo.getCivilization(popupAlert.value).getTranslatedNation()
|
||||
addLeaderName(translatedNation)
|
||||
addGoodSizedLabel(translatedNation.declaringWar).row()
|
||||
val responseTable = Table()
|
||||
responseTable.add(getCloseButton("You'll pay for this!"))
|
||||
responseTable.add(getCloseButton("Very well."))
|
||||
add(responseTable)
|
||||
}
|
||||
AlertType.Defeated -> {
|
||||
val translatedNation = worldScreen.gameInfo.getCivilization(popupAlert.value).getTranslatedNation()
|
||||
addLeaderName(translatedNation)
|
||||
addGoodSizedLabel(translatedNation.defeated).row()
|
||||
add(getCloseButton("Farewell."))
|
||||
}
|
||||
AlertType.FirstContact -> {
|
||||
val translatedNation = worldScreen.gameInfo.getCivilization(popupAlert.value).getTranslatedNation()
|
||||
addLeaderName(translatedNation)
|
||||
addGoodSizedLabel(translatedNation.introduction).row()
|
||||
add(getCloseButton("A pleasure to meet you."))
|
||||
}
|
||||
AlertType.CityConquered -> {
|
||||
addGoodSizedLabel("What would you like to do with the city?").row()
|
||||
add(getCloseButton("Annex")).row()
|
||||
add(TextButton("Raze", skin).onClick {
|
||||
worldScreen.currentPlayerCiv.cities.first { it.name==popupAlert.value }.isBeingRazed=true
|
||||
worldScreen.shouldUpdate=true
|
||||
close()
|
||||
})
|
||||
}
|
||||
}
|
||||
open()
|
||||
isOpen = true
|
||||
}
|
||||
|
||||
fun close(){
|
||||
worldScreen.currentPlayerCiv.popupAlerts.remove(popupAlert)
|
||||
isOpen = false
|
||||
remove()
|
||||
}
|
||||
|
||||
companion object {
|
||||
var isOpen = false
|
||||
}
|
||||
}
|
74
core/src/com/unciv/ui/worldscreen/TradePopup.kt
Normal file
74
core/src/com/unciv/ui/worldscreen/TradePopup.kt
Normal file
|
@ -0,0 +1,74 @@
|
|||
package com.unciv.ui.worldscreen
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.logic.trade.TradeLogic
|
||||
import com.unciv.models.gamebasics.tr
|
||||
import com.unciv.ui.trade.DiplomacyScreen
|
||||
import com.unciv.ui.utils.addSeparator
|
||||
import com.unciv.ui.utils.toLabel
|
||||
import com.unciv.ui.worldscreen.optionstable.PopupTable
|
||||
import kotlin.math.max
|
||||
|
||||
class TradePopup(worldScreen: WorldScreen): PopupTable(worldScreen){
|
||||
init{
|
||||
val currentPlayerCiv = worldScreen.currentPlayerCiv
|
||||
val tradeRequest = currentPlayerCiv.tradeRequests.first()
|
||||
|
||||
val requestingCiv = worldScreen.gameInfo.getCivilization(tradeRequest.requestingCiv)
|
||||
val translatedNation = requestingCiv.getTranslatedNation()
|
||||
val otherCivLeaderName = "[${translatedNation.leaderName}] of [${translatedNation.getNameTranslation()}]".tr()
|
||||
|
||||
add(otherCivLeaderName.toLabel())
|
||||
addSeparator()
|
||||
|
||||
val trade = tradeRequest.trade
|
||||
val tradeOffersTable = Table().apply { defaults().pad(10f) }
|
||||
for(i in 0..max(trade.theirOffers.lastIndex, trade.ourOffers.lastIndex)){
|
||||
if(trade.theirOffers.lastIndex>=i) tradeOffersTable.add(trade.theirOffers[i].getOfferText().toLabel())
|
||||
else tradeOffersTable.add()
|
||||
if(trade.ourOffers.lastIndex>=i) tradeOffersTable.add(trade.ourOffers[i].getOfferText().toLabel())
|
||||
else tradeOffersTable.add()
|
||||
tradeOffersTable.row()
|
||||
}
|
||||
add(tradeOffersTable).row()
|
||||
|
||||
addGoodSizedLabel(translatedNation.tradeRequest).colspan(columns).row()
|
||||
|
||||
addButton("Sounds good!".tr()){
|
||||
val tradeLogic = TradeLogic(currentPlayerCiv, requestingCiv)
|
||||
tradeLogic.currentTrade.set(trade)
|
||||
tradeLogic.acceptTrade()
|
||||
currentPlayerCiv.tradeRequests.remove(tradeRequest)
|
||||
remove()
|
||||
PopupTable(worldScreen).apply {
|
||||
add(otherCivLeaderName.toLabel()).colspan(2)
|
||||
addSeparator()
|
||||
addGoodSizedLabel("Excellent!").row()
|
||||
addButton("Goodbye."){
|
||||
this.remove()
|
||||
worldScreen.shouldUpdate=true
|
||||
// in all cases, worldScreen.shouldUpdate should be set to true when we remove the last of the popups
|
||||
// in order for the next trade to appear immediately
|
||||
}
|
||||
open()
|
||||
}
|
||||
}
|
||||
addButton("Not this time.".tr()){
|
||||
currentPlayerCiv.tradeRequests.remove(tradeRequest)
|
||||
remove()
|
||||
worldScreen.shouldUpdate=true
|
||||
}
|
||||
addButton("How about something else...".tr()){
|
||||
currentPlayerCiv.tradeRequests.remove(tradeRequest)
|
||||
remove()
|
||||
|
||||
val diplomacyScreen= DiplomacyScreen()
|
||||
val tradeTable = diplomacyScreen.setTrade(requestingCiv)
|
||||
tradeTable.tradeLogic.currentTrade.set(trade)
|
||||
tradeTable.offerColumnsTable.update()
|
||||
worldScreen.game.screen=diplomacyScreen
|
||||
worldScreen.shouldUpdate=true
|
||||
}
|
||||
open()
|
||||
}
|
||||
}
|
|
@ -8,12 +8,9 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
|||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.GameSaver
|
||||
import com.unciv.logic.civilization.AlertType
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.civilization.PopupAlert
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||
import com.unciv.models.gamebasics.GameBasics
|
||||
import com.unciv.models.gamebasics.Nation
|
||||
import com.unciv.models.gamebasics.tile.ResourceType
|
||||
import com.unciv.models.gamebasics.tr
|
||||
import com.unciv.models.gamebasics.unit.UnitType
|
||||
|
@ -26,7 +23,6 @@ import com.unciv.ui.trade.DiplomacyScreen
|
|||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.worldscreen.bottombar.BattleTable
|
||||
import com.unciv.ui.worldscreen.bottombar.WorldScreenBottomBar
|
||||
import com.unciv.ui.worldscreen.optionstable.PopupTable
|
||||
import com.unciv.ui.worldscreen.unit.UnitActionsTable
|
||||
|
||||
class WorldScreen : CameraStageBaseScreen() {
|
||||
|
@ -167,13 +163,16 @@ class WorldScreen : CameraStageBaseScreen() {
|
|||
notificationsScroll.setPosition(stage.width - notificationsScroll.width - 5f,
|
||||
nextTurnButton.y - notificationsScroll.height - 5f)
|
||||
|
||||
if(!gameInfo.oneMoreTurnMode && currentPlayerCiv.victoryManager.hasWon()) game.screen = VictoryScreen()
|
||||
else if(currentPlayerCiv.policies.freePolicies>0) game.screen = PolicyPickerScreen(currentPlayerCiv)
|
||||
else if(currentPlayerCiv.greatPeople.freeGreatPeople>0) game.screen = GreatPersonPickerScreen()
|
||||
|
||||
if(game.screen==this && !tutorials.isTutorialShowing
|
||||
&& currentPlayerCiv.popupAlerts.any() && !AlertPopup.isOpen){
|
||||
AlertPopup(this,currentPlayerCiv.popupAlerts.first())
|
||||
when {
|
||||
!gameInfo.oneMoreTurnMode && currentPlayerCiv.victoryManager.hasWon() -> game.screen = VictoryScreen()
|
||||
currentPlayerCiv.policies.freePolicies>0 -> game.screen = PolicyPickerScreen(currentPlayerCiv)
|
||||
currentPlayerCiv.greatPeople.freeGreatPeople>0 -> game.screen = GreatPersonPickerScreen()
|
||||
currentPlayerCiv.tradeRequests.isNotEmpty() ->{
|
||||
TradePopup(this)
|
||||
}
|
||||
!tutorials.isTutorialShowing
|
||||
&& currentPlayerCiv.popupAlerts.any() && !AlertPopup.isOpen ->
|
||||
AlertPopup(this,currentPlayerCiv.popupAlerts.first())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,10 +221,10 @@ class WorldScreen : CameraStageBaseScreen() {
|
|||
}
|
||||
|
||||
private fun createNextTurnButton(): TextButton {
|
||||
val nextTurnButton = TextButton("Next turn".tr(), CameraStageBaseScreen.skin)
|
||||
val nextTurnButton = TextButton("Next turn".tr(), skin)
|
||||
nextTurnButton.onClick {
|
||||
if(currentPlayerCiv.policies.shouldOpenPolicyPicker && !currentPlayerCiv.policies.canAdoptPolicy())
|
||||
currentPlayerCiv.policies.shouldOpenPolicyPicker = false // something has chanhed and we can no longer adopt the policy, e.g. we conquered another city
|
||||
currentPlayerCiv.policies.shouldOpenPolicyPicker = false // something has changed and we can no longer adopt the policy, e.g. we conquered another city
|
||||
|
||||
if (currentPlayerCiv.tech.freeTechs != 0) {
|
||||
game.screen = TechPickerScreen(true, currentPlayerCiv)
|
||||
|
@ -281,7 +280,6 @@ class WorldScreen : CameraStageBaseScreen() {
|
|||
}
|
||||
|
||||
override fun resize(width: Int, height: Int) {
|
||||
|
||||
if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) {
|
||||
super.resize(width, height)
|
||||
game.worldScreen = WorldScreen() // start over.
|
||||
|
@ -299,95 +297,35 @@ class WorldScreen : CameraStageBaseScreen() {
|
|||
|
||||
// otherwise images will not load properly!
|
||||
update()
|
||||
|
||||
val shownTutorials = UnCivGame.Current.settings.tutorialsShown
|
||||
displayTutorials("NextTurn")
|
||||
if("BarbarianEncountered" !in shownTutorials
|
||||
&& currentPlayerCiv.viewableTiles.any { it.getUnits().any { unit -> unit.civInfo.isBarbarianCivilization() } })
|
||||
displayTutorials("BarbarianEncountered")
|
||||
if(currentPlayerCiv.cities.size > 2) displayTutorials("SecondCity")
|
||||
if(currentPlayerCiv.happiness < 0) displayTutorials("Unhappiness")
|
||||
if(currentPlayerCiv.goldenAges.isGoldenAge()) displayTutorials("GoldenAge")
|
||||
if(gameInfo.turns >= 100) displayTutorials("ContactMe")
|
||||
val resources = currentPlayerCiv.getCivResources()
|
||||
if(resources.keys.any { it.resourceType==ResourceType.Luxury }) displayTutorials("LuxuryResource")
|
||||
if(resources.keys.any { it.resourceType==ResourceType.Strategic}) displayTutorials("StrategicResource")
|
||||
if("EnemyCity" !in shownTutorials
|
||||
&& currentPlayerCiv.exploredTiles.asSequence().map { gameInfo.tileMap[it] }
|
||||
.any { it.isCityCenter() && it.getOwner()!=currentPlayerCiv })
|
||||
displayTutorials("EnemyCity")
|
||||
if("Enables construction of Spaceship parts" in currentPlayerCiv.getBuildingUniques())
|
||||
displayTutorials("ApolloProgram")
|
||||
if(currentPlayerCiv.getCivUnits().any { it.type == UnitType.Siege })
|
||||
displayTutorials("SiegeUnitTrained")
|
||||
if(currentPlayerCiv.tech.getUniques().contains("Enables embarkation for land units"))
|
||||
displayTutorials("CanEmbark")
|
||||
|
||||
showTutorialsOnNextTurn()
|
||||
shouldUpdate=false
|
||||
}
|
||||
super.render(delta)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert):PopupTable(worldScreen){
|
||||
fun getCloseButton(text:String): TextButton {
|
||||
val button = TextButton(text.tr(), skin)
|
||||
button.onClick { close() }
|
||||
return button
|
||||
}
|
||||
|
||||
fun addLeaderName(translatedNation:Nation){
|
||||
val otherCivLeaderName = "[${translatedNation.leaderName}] of [${translatedNation.getNameTranslation()}]".tr()
|
||||
add(otherCivLeaderName.toLabel())
|
||||
addSeparator()
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
when(popupAlert.type){
|
||||
AlertType.WarDeclaration -> {
|
||||
val translatedNation = worldScreen.gameInfo.getCivilization(popupAlert.value).getTranslatedNation()
|
||||
addLeaderName(translatedNation)
|
||||
addGoodSizedLabel(translatedNation.declaringWar).row()
|
||||
val responseTable = Table()
|
||||
responseTable.add(getCloseButton("You'll pay for this!"))
|
||||
responseTable.add(getCloseButton("Very well."))
|
||||
add(responseTable)
|
||||
}
|
||||
AlertType.Defeated -> {
|
||||
val translatedNation = worldScreen.gameInfo.getCivilization(popupAlert.value).getTranslatedNation()
|
||||
addLeaderName(translatedNation)
|
||||
addGoodSizedLabel(translatedNation.defeated).row()
|
||||
add(getCloseButton("Farewell."))
|
||||
}
|
||||
AlertType.FirstContact -> {
|
||||
val translatedNation = worldScreen.gameInfo.getCivilization(popupAlert.value).getTranslatedNation()
|
||||
addLeaderName(translatedNation)
|
||||
addGoodSizedLabel(translatedNation.introduction).row()
|
||||
add(getCloseButton("A pleasure to meet you."))
|
||||
}
|
||||
AlertType.CityConquered -> {
|
||||
addGoodSizedLabel("What would you like to do with the city?").row()
|
||||
add(getCloseButton("Annex")).row()
|
||||
add(TextButton("Raze",skin).onClick {
|
||||
worldScreen.currentPlayerCiv.cities.first { it.name==popupAlert.value }.isBeingRazed=true
|
||||
worldScreen.shouldUpdate=true
|
||||
close()
|
||||
})
|
||||
}
|
||||
}
|
||||
open()
|
||||
isOpen = true
|
||||
}
|
||||
|
||||
fun close(){
|
||||
worldScreen.currentPlayerCiv.popupAlerts.remove(popupAlert)
|
||||
isOpen = false
|
||||
remove()
|
||||
}
|
||||
|
||||
companion object {
|
||||
var isOpen = false
|
||||
}
|
||||
private fun showTutorialsOnNextTurn(){
|
||||
val shownTutorials = UnCivGame.Current.settings.tutorialsShown
|
||||
displayTutorials("NextTurn")
|
||||
if("BarbarianEncountered" !in shownTutorials
|
||||
&& currentPlayerCiv.viewableTiles.any { it.getUnits().any { unit -> unit.civInfo.isBarbarianCivilization() } })
|
||||
displayTutorials("BarbarianEncountered")
|
||||
if(currentPlayerCiv.cities.size > 2) displayTutorials("SecondCity")
|
||||
if(currentPlayerCiv.happiness < 0) displayTutorials("Unhappiness")
|
||||
if(currentPlayerCiv.goldenAges.isGoldenAge()) displayTutorials("GoldenAge")
|
||||
if(gameInfo.turns >= 100) displayTutorials("ContactMe")
|
||||
val resources = currentPlayerCiv.getCivResources()
|
||||
if(resources.keys.any { it.resourceType==ResourceType.Luxury }) displayTutorials("LuxuryResource")
|
||||
if(resources.keys.any { it.resourceType==ResourceType.Strategic}) displayTutorials("StrategicResource")
|
||||
if("EnemyCity" !in shownTutorials
|
||||
&& currentPlayerCiv.exploredTiles.asSequence().map { gameInfo.tileMap[it] }
|
||||
.any { it.isCityCenter() && it.getOwner()!=currentPlayerCiv })
|
||||
displayTutorials("EnemyCity")
|
||||
if("Enables construction of Spaceship parts" in currentPlayerCiv.getBuildingUniques())
|
||||
displayTutorials("ApolloProgram")
|
||||
if(currentPlayerCiv.getCivUnits().any { it.type == UnitType.Siege })
|
||||
displayTutorials("SiegeUnitTrained")
|
||||
if(currentPlayerCiv.tech.getUniques().contains("Enables embarkation for land units"))
|
||||
displayTutorials("CanEmbark")
|
||||
}
|
||||
|
||||
}
|
|
@ -32,10 +32,10 @@ open class PopupTable(val screen: CameraStageBaseScreen): Table(CameraStageBaseS
|
|||
return add(label).width(screen.stage.width/2)
|
||||
}
|
||||
|
||||
fun addButton(text:String, action:()->Unit){
|
||||
fun addButton(text:String, action:()->Unit): Cell<TextButton> {
|
||||
val button = TextButton(text.tr(), skin).apply { color= ImageGetter.getBlue() }
|
||||
button.onClick(action)
|
||||
add(button).row()
|
||||
return add(button).apply { row() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue