From 07663bfc548c1aadd0f68900fa154c71eaf86a13 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Sun, 10 Feb 2019 16:34:46 +0200 Subject: [PATCH] Added "Diplomatic Incidents" for diplomatic messages between civs (as of now, only declaration of war) --- android/assets/jsons/Nations.json | 10 ++++ core/src/com/unciv/logic/GameInfo.kt | 5 +- .../unciv/logic/automation/UnitAutomation.kt | 2 +- .../logic/civilization/CivilizationInfo.kt | 8 +++- .../{ => diplomacy}/DiplomacyManager.kt | 11 ++--- .../diplomacy/DiplomaticIncident.kt | 5 ++ .../diplomacy/DiplomaticIncidentType.kt | 6 +++ .../diplomacy/DiplomaticStatus.kt | 6 +++ core/src/com/unciv/logic/map/TileInfo.kt | 2 +- core/src/com/unciv/logic/trade/Trade.kt | 8 ++-- core/src/com/unciv/logic/trade/TradeLogic.kt | 12 ++--- .../src/com/unciv/models/gamebasics/Nation.kt | 1 + core/src/com/unciv/ui/EmpireOverviewScreen.kt | 4 +- core/src/com/unciv/ui/NationTable.kt | 2 +- core/src/com/unciv/ui/utils/Tutorials.kt | 2 +- .../com/unciv/ui/worldscreen/WorldScreen.kt | 48 ++++++++++++++++++- 16 files changed, 104 insertions(+), 28 deletions(-) rename core/src/com/unciv/logic/civilization/{ => diplomacy}/DiplomacyManager.kt (93%) create mode 100644 core/src/com/unciv/logic/civilization/diplomacy/DiplomaticIncident.kt create mode 100644 core/src/com/unciv/logic/civilization/diplomacy/DiplomaticIncidentType.kt create mode 100644 core/src/com/unciv/logic/civilization/diplomacy/DiplomaticStatus.kt diff --git a/android/assets/jsons/Nations.json b/android/assets/jsons/Nations.json index 20947d14..f8c099f4 100644 --- a/android/assets/jsons/Nations.json +++ b/android/assets/jsons/Nations.json @@ -1,6 +1,7 @@ [ { name:"Babylon", + leaderName:"Nebuchadnezzar II", mainColor:[27,53,63], secondaryColor:[213,249,255], unique:"Receive free Great Scientist when you discover Writing, Earn Great Scientists 50% faster", @@ -10,6 +11,7 @@ }, { name:"Greece", + leaderName:"Alexander", mainColor:[181, 232, 232], secondaryColor:[68,142,249], cities:["Athens","Sparta","Corinth","Argos","Knossos","Mycenae","Pharsalos","Ephesus","Halicarnassus","Rhodes", @@ -18,6 +20,7 @@ }, { name:"China", + leaderName:"Wu Zetian", mainColor:[9, 112, 84], secondaryColor:[255,255,255], unique:"Great general provides double combat bonus, and spawns 50% faster" @@ -27,6 +30,7 @@ }, { name:"Egypt", + leaderName:"Ramesses II", mainColor:[ 231, 213, 0], secondaryColor:[98,10,210], unique:"+20% production towards Wonder construction" @@ -36,6 +40,7 @@ }, { name:"England", + leaderName:"Elizabeth", mainColor:[ 114, 0, 0], secondaryColor:[255,255,255], unique:"+2 movement for all naval units" @@ -45,6 +50,7 @@ }, { name:"France", + leaderName:"Napoleon", mainColor:[ 38, 98, 255], secondaryColor:[239,236,148], unique:"+2 Culture per turn from cities before discovering Steam Power", @@ -54,6 +60,7 @@ }, { name:"Russia", + leaderName:"Catherine", mainColor:[ 236, 178, 0], secondaryColor:[0,0,0], unique:"Strategic Resources provide +1 Production, and Horses, Iron and Uranium Resources provide double quantity", @@ -63,6 +70,7 @@ }, { name:"Rome", + leaderName:"Augustus Caesar", mainColor:[ 53,0,87], secondaryColor:[238,201,9], unique:"+25% Production towards any buildings that already exist in the Capital", @@ -72,6 +80,7 @@ }, { name:"Arabia", + leaderName:"Harun al-Rashid", mainColor:[ 41,83,42], secondaryColor:[146,221,9], cities:["Mecca","Medina","Damascus","Baghdad","Najran","Kufah","Basra","Khurasan","Anjar","Fustat", @@ -80,6 +89,7 @@ }, { name:"America", + leaderName:"Washington", mainColor:[ 28,51,119], secondaryColor:[255,255,255], unique:"All land military units have +1 sight, 50% discount when purchasing tiles", diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index 7c96abe3..e31b37b8 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -31,8 +31,9 @@ class GameInfo { return toReturn } - fun getCurrentPlayerCivilization(): CivilizationInfo = civilizations.first { it.civName==currentPlayer } - fun getBarbarianCivilization(): CivilizationInfo = civilizations.first { it.civName=="Barbarians" } + fun getCivilization(civName:String) = civilizations.first { it.civName==civName } + fun getCurrentPlayerCivilization() = getCivilization(currentPlayer) + fun getBarbarianCivilization() = getCivilization("Barbarians") fun getDifficulty() = GameBasics.Difficulties[difficulty]!! //endregion diff --git a/core/src/com/unciv/logic/automation/UnitAutomation.kt b/core/src/com/unciv/logic/automation/UnitAutomation.kt index ae5c01cc..cfff8ae2 100644 --- a/core/src/com/unciv/logic/automation/UnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/UnitAutomation.kt @@ -4,7 +4,7 @@ import com.unciv.UnCivGame import com.unciv.logic.battle.* import com.unciv.logic.city.CityInfo import com.unciv.logic.civilization.CivilizationInfo -import com.unciv.logic.civilization.DiplomaticStatus +import com.unciv.logic.civilization.diplomacy.DiplomaticStatus import com.unciv.logic.civilization.GreatPersonManager import com.unciv.logic.map.MapUnit import com.unciv.logic.map.TileInfo diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index 97582d35..f59a80dd 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -4,6 +4,9 @@ import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.math.Vector2 import com.unciv.logic.GameInfo import com.unciv.logic.city.CityInfo +import com.unciv.logic.civilization.diplomacy.DiplomacyManager +import com.unciv.logic.civilization.diplomacy.DiplomaticIncident +import com.unciv.logic.civilization.diplomacy.DiplomaticStatus import com.unciv.logic.map.BFS import com.unciv.logic.map.MapUnit import com.unciv.logic.map.RoadStatus @@ -51,8 +54,9 @@ class CivilizationInfo { var greatPeople = GreatPersonManager() @Deprecated("As of 2.11.3") var scienceVictory = ScienceVictoryManager() var victoryManager=VictoryManager() - var diplomacy = HashMap() + var diplomacy = HashMap() var notifications = ArrayList() + val diplomaticIncidents = ArrayList() // if we only use lists, and change the list each time the cities are changed, // we won't get concurrent modification exceptions. @@ -294,7 +298,7 @@ class CivilizationInfo { return diplomacy[otherCiv.civName]!!.diplomaticStatus == DiplomaticStatus.War } - fun isAtWar() = diplomacy.values.any { it.diplomaticStatus==DiplomaticStatus.War && !it.otherCiv().isDefeated() } + fun isAtWar() = diplomacy.values.any { it.diplomaticStatus== DiplomaticStatus.War && !it.otherCiv().isDefeated() } //endregion //region state-changing functions diff --git a/core/src/com/unciv/logic/civilization/DiplomacyManager.kt b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt similarity index 93% rename from core/src/com/unciv/logic/civilization/DiplomacyManager.kt rename to core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt index 84d83582..8ed491af 100644 --- a/core/src/com/unciv/logic/civilization/DiplomacyManager.kt +++ b/core/src/com/unciv/logic/civilization/diplomacy/DiplomacyManager.kt @@ -1,6 +1,7 @@ -package com.unciv.logic.civilization +package com.unciv.logic.civilization.diplomacy import com.badlogic.gdx.graphics.Color +import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.trade.Trade import com.unciv.logic.trade.TradeType import com.unciv.models.Counter @@ -8,11 +9,6 @@ import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.tile.TileResource import com.unciv.models.gamebasics.tr -enum class DiplomaticStatus{ - Peace, - War -} - class DiplomacyManager() { @Transient lateinit var civInfo: CivilizationInfo lateinit var otherCivName:String @@ -42,7 +38,7 @@ class DiplomacyManager() { fun canDeclareWar() = turnsToPeaceTreaty()==0 - fun otherCiv() = civInfo.gameInfo.civilizations.first{it.civName==otherCivName} + fun otherCiv() = civInfo.gameInfo.getCivilization(otherCivName) fun goldPerTurn():Int{ var goldPerTurnForUs = 0 @@ -103,6 +99,7 @@ class DiplomacyManager() { diplomaticStatus = DiplomaticStatus.War otherCiv().diplomacy[civInfo.civName]!!.diplomaticStatus = DiplomaticStatus.War otherCiv().addNotification("[${civInfo.civName}] has declared war on us!",null, Color.RED) + otherCiv().diplomaticIncidents.add(DiplomaticIncident(civInfo.civName,DiplomaticIncidentType.WarDeclaration)) } //endregion } \ No newline at end of file diff --git a/core/src/com/unciv/logic/civilization/diplomacy/DiplomaticIncident.kt b/core/src/com/unciv/logic/civilization/diplomacy/DiplomaticIncident.kt new file mode 100644 index 00000000..23954f17 --- /dev/null +++ b/core/src/com/unciv/logic/civilization/diplomacy/DiplomaticIncident.kt @@ -0,0 +1,5 @@ +package com.unciv.logic.civilization.diplomacy + +import com.unciv.logic.trade.Trade + +class DiplomaticIncident(val civName:String, val type: DiplomaticIncidentType, val trade: Trade?=null) \ No newline at end of file diff --git a/core/src/com/unciv/logic/civilization/diplomacy/DiplomaticIncidentType.kt b/core/src/com/unciv/logic/civilization/diplomacy/DiplomaticIncidentType.kt new file mode 100644 index 00000000..39ab9654 --- /dev/null +++ b/core/src/com/unciv/logic/civilization/diplomacy/DiplomaticIncidentType.kt @@ -0,0 +1,6 @@ +package com.unciv.logic.civilization.diplomacy + +enum class DiplomaticIncidentType{ + WarDeclaration, + TradeOffer +} \ No newline at end of file diff --git a/core/src/com/unciv/logic/civilization/diplomacy/DiplomaticStatus.kt b/core/src/com/unciv/logic/civilization/diplomacy/DiplomaticStatus.kt new file mode 100644 index 00000000..168f08ca --- /dev/null +++ b/core/src/com/unciv/logic/civilization/diplomacy/DiplomaticStatus.kt @@ -0,0 +1,6 @@ +package com.unciv.logic.civilization.diplomacy + +enum class DiplomaticStatus{ + Peace, + War +} \ No newline at end of file diff --git a/core/src/com/unciv/logic/map/TileInfo.kt b/core/src/com/unciv/logic/map/TileInfo.kt index 4b71d2cf..f4a35612 100644 --- a/core/src/com/unciv/logic/map/TileInfo.kt +++ b/core/src/com/unciv/logic/map/TileInfo.kt @@ -281,7 +281,7 @@ open class TileInfo { if(civilianUnit!=null) civilianUnit!!.currentTile = this for (unit in getUnits()) { - unit.assignOwner(tileMap.gameInfo.civilizations.first { it.civName == unit.owner }) + unit.assignOwner(tileMap.gameInfo.getCivilization(unit.owner)) unit.setTransients() } } diff --git a/core/src/com/unciv/logic/trade/Trade.kt b/core/src/com/unciv/logic/trade/Trade.kt index 9f959806..d27a25b6 100644 --- a/core/src/com/unciv/logic/trade/Trade.kt +++ b/core/src/com/unciv/logic/trade/Trade.kt @@ -1,6 +1,10 @@ package com.unciv.logic.trade class Trade{ + + val theirOffers = TradeOffersList() + val ourOffers = TradeOffersList() + fun reverse(): Trade { val newTrade = Trade() newTrade.theirOffers+=ourOffers.map { it.copy() } @@ -8,10 +12,6 @@ class Trade{ return newTrade } - - val theirOffers = TradeOffersList() - val ourOffers = TradeOffersList() - fun equals(trade: Trade):Boolean{ if(trade.ourOffers.size!=ourOffers.size || trade.theirOffers.size!=theirOffers.size) return false diff --git a/core/src/com/unciv/logic/trade/TradeLogic.kt b/core/src/com/unciv/logic/trade/TradeLogic.kt index 830e48f0..db14f051 100644 --- a/core/src/com/unciv/logic/trade/TradeLogic.kt +++ b/core/src/com/unciv/logic/trade/TradeLogic.kt @@ -3,7 +3,7 @@ package com.unciv.logic.trade import com.unciv.logic.automation.Automation import com.unciv.logic.automation.ThreatLevel import com.unciv.logic.civilization.CivilizationInfo -import com.unciv.logic.civilization.DiplomaticStatus +import com.unciv.logic.civilization.diplomacy.DiplomaticStatus import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.tile.ResourceType import com.unciv.models.gamebasics.tr @@ -46,7 +46,7 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci val civsWeBothKnow = otherCivsWeKnow .filter { otherCivilization.diplomacy.containsKey(it.civName) } val civsWeArentAtWarWith = civsWeBothKnow - .filter { civInfo.diplomacy[it.civName]!!.diplomaticStatus==DiplomaticStatus.Peace } + .filter { civInfo.diplomacy[it.civName]!!.diplomaticStatus== DiplomaticStatus.Peace } for(thirdCiv in civsWeArentAtWarWith){ offers.add(TradeOffer("Declare war on "+thirdCiv.civName,TradeType.WarDeclaration,0)) } @@ -120,7 +120,7 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci TradeType.Introduction -> return 250 TradeType.WarDeclaration -> { val nameOfCivToDeclareWarOn = offer.name.split(' ').last() - val civToDeclareWarOn = ourCivilization.gameInfo.civilizations.first { it.civName==nameOfCivToDeclareWarOn } + val civToDeclareWarOn = ourCivilization.gameInfo.getCivilization(nameOfCivToDeclareWarOn) val threatToThem = Automation().threatAssessment(otherCivilization,civToDeclareWarOn) if(!otherCivIsRecieving) { // we're getting this from them, that is, they're declaring war @@ -133,7 +133,7 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci } } else{ - if(otherCivilization.diplomacy[nameOfCivToDeclareWarOn]!!.diplomaticStatus==DiplomaticStatus.War){ + if(otherCivilization.diplomacy[nameOfCivToDeclareWarOn]!!.diplomaticStatus== DiplomaticStatus.War){ when (threatToThem) { ThreatLevel.VeryLow -> return 0 ThreatLevel.Low -> return 0 @@ -199,8 +199,8 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci } } if(offer.type==TradeType.Introduction) - to.meetCivilization(to.gameInfo.civilizations - .first { it.civName==offer.name.split(" ")[2] }) + to.meetCivilization(to.gameInfo.getCivilization(offer.name.split(" ")[2])) + if(offer.type==TradeType.WarDeclaration){ val nameOfCivToDeclareWarOn = offer.name.split(' ').last() from.diplomacy[nameOfCivToDeclareWarOn]!!.declareWar() diff --git a/core/src/com/unciv/models/gamebasics/Nation.kt b/core/src/com/unciv/models/gamebasics/Nation.kt index 319b3da5..1839a893 100644 --- a/core/src/com/unciv/models/gamebasics/Nation.kt +++ b/core/src/com/unciv/models/gamebasics/Nation.kt @@ -6,6 +6,7 @@ import com.unciv.ui.utils.colorFromRGB class Nation : INamed { override lateinit var name: String + lateinit var leaderName: String lateinit var mainColor: List var unique:String?=null var secondaryColor: List?=null diff --git a/core/src/com/unciv/ui/EmpireOverviewScreen.kt b/core/src/com/unciv/ui/EmpireOverviewScreen.kt index 16e92d26..ed9c8070 100644 --- a/core/src/com/unciv/ui/EmpireOverviewScreen.kt +++ b/core/src/com/unciv/ui/EmpireOverviewScreen.kt @@ -11,7 +11,7 @@ import com.badlogic.gdx.utils.Align import com.unciv.UnCivGame import com.unciv.logic.HexMath import com.unciv.logic.civilization.CivilizationInfo -import com.unciv.logic.civilization.DiplomaticStatus +import com.unciv.logic.civilization.diplomacy.DiplomaticStatus import com.unciv.logic.trade.Trade import com.unciv.logic.trade.TradeOffersList import com.unciv.models.gamebasics.tr @@ -328,7 +328,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){ val statusLine = ImageGetter.getLine(civGroup.x+civGroup.width/2,civGroup.y+civGroup.height/2, otherCivGroup.x+otherCivGroup.width/2,otherCivGroup.y+otherCivGroup.height/2,3f) - statusLine.color = if(diplomacy.diplomaticStatus==DiplomaticStatus.War) Color.RED + statusLine.color = if(diplomacy.diplomaticStatus== DiplomaticStatus.War) Color.RED else Color.GREEN group.addActor(statusLine) diff --git a/core/src/com/unciv/ui/NationTable.kt b/core/src/com/unciv/ui/NationTable.kt index e8d6ba5a..75bd78b7 100644 --- a/core/src/com/unciv/ui/NationTable.kt +++ b/core/src/com/unciv/ui/NationTable.kt @@ -19,7 +19,7 @@ class NationTable(val nation: Nation, val newGameParameters: GameParameters, ski background= ImageGetter.getBackground(nation.getSecondaryColor()) innerTable.pad(10f) innerTable.background= ImageGetter.getBackground(nation.getColor()) - innerTable.add(Label(nation.name.tr(), skin).apply { setFontColor(nation.getSecondaryColor())}).row() + innerTable.add(Label(nation.leaderName.tr()+" - "+nation.name.tr(), skin).apply { setFontColor(nation.getSecondaryColor())}).row() innerTable.add(Label(getUniqueLabel(nation), skin) .apply { setWrap(true);setFontColor(nation.getSecondaryColor())}) .width(width) diff --git a/core/src/com/unciv/ui/utils/Tutorials.kt b/core/src/com/unciv/ui/utils/Tutorials.kt index bec5c156..12ea959e 100644 --- a/core/src/com/unciv/ui/utils/Tutorials.kt +++ b/core/src/com/unciv/ui/utils/Tutorials.kt @@ -22,7 +22,7 @@ class Tutorials{ private val tutorialTexts = mutableListOf() - private var isTutorialShowing = false + var isTutorialShowing = false fun displayTutorials(name: String, stage: Stage) { diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index 41ba916f..3db5387f 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -10,7 +10,9 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.unciv.UnCivGame import com.unciv.logic.GameSaver import com.unciv.logic.civilization.CivilizationInfo -import com.unciv.logic.civilization.DiplomaticStatus +import com.unciv.logic.civilization.diplomacy.DiplomaticIncident +import com.unciv.logic.civilization.diplomacy.DiplomaticIncidentType +import com.unciv.logic.civilization.diplomacy.DiplomaticStatus import com.unciv.models.gamebasics.tile.ResourceType import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.unit.UnitType @@ -22,6 +24,7 @@ import com.unciv.ui.pickerscreens.TechPickerScreen import com.unciv.ui.trade.DiplomacyScreen import com.unciv.ui.utils.* import com.unciv.ui.worldscreen.bottombar.WorldScreenBottomBar +import com.unciv.ui.worldscreen.optionstable.PopupTable import com.unciv.ui.worldscreen.unit.UnitActionsTable class WorldScreen : CameraStageBaseScreen() { @@ -157,6 +160,11 @@ class WorldScreen : CameraStageBaseScreen() { 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.diplomaticIncidents.any() && !DiplomaticIncidentPopup.isOpen){ + DiplomaticIncidentPopup(this,currentPlayerCiv.diplomaticIncidents.first()) + } } private fun updateDiplomacyButton(civInfo: CivilizationInfo) { @@ -300,4 +308,42 @@ class WorldScreen : CameraStageBaseScreen() { super.render(delta) } +} + +class DiplomaticIncidentPopup(val worldScreen: WorldScreen, val diplomaticIncident: DiplomaticIncident):PopupTable(worldScreen){ + init{ + val otherCiv = worldScreen.gameInfo.getCivilization(diplomaticIncident.civName) + val otherCivLeaderName = otherCiv.getNation().leaderName+" of "+otherCiv.civName + add(Label(otherCivLeaderName,skin)) + addSeparator() + when(diplomaticIncident.type){ + DiplomaticIncidentType.WarDeclaration -> { + add(Label("We've decided to declare war on you, k?",skin)).row() + val responseTable = Table() + + val angryResponse = TextButton("You'll pay for this",skin) + angryResponse.onClick { close() } + + val acceptingResponse= TextButton("This is fine",skin) + acceptingResponse.onClick { close() } + + responseTable.add(angryResponse) + responseTable.add(acceptingResponse) + add(responseTable) + } + DiplomaticIncidentType.TradeOffer -> TODO() + } + open() + isOpen = true + } + + fun close(){ + worldScreen.currentPlayerCiv.diplomaticIncidents.remove(diplomaticIncident) + isOpen = false + remove() + } + + companion object { + var isOpen = false + } } \ No newline at end of file