mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-05 00:18:13 +07:00
Added Diplomatic victory, United Nations, Globalization (#4619)
* Added globalization tech * Added united nations and backbone for diplomatic victory * You can now vote with the united nations every 20 * gameSpeed turns, and the results will be displayed the turn after * You can now win with diplomacy * AI will now vote in the united nations * Added the amount of turns till the next diplomatic vote in the diplomacy overview * Added translatable strings * Implemented most of the requested changes (rest coming soon) * Implemented further requested changes
This commit is contained in:
parent
bb5392db4a
commit
4d3195ec5a
BIN
android/Images/TechIcons/Globalization.png
Normal file
BIN
android/Images/TechIcons/Globalization.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
BIN
android/ImagesToPackSeparately/BuildingIcons/United Nations.png
Normal file
BIN
android/ImagesToPackSeparately/BuildingIcons/United Nations.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
@ -746,59 +746,66 @@ Theatre
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
University
|
||||
United Nations
|
||||
rotate: false
|
||||
xy: 1516, 760
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Utopia Project
|
||||
University
|
||||
rotate: false
|
||||
xy: 1624, 868
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Walls
|
||||
Utopia Project
|
||||
rotate: false
|
||||
xy: 868, 4
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Walls of Babylon
|
||||
Walls
|
||||
rotate: false
|
||||
xy: 976, 112
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Wat
|
||||
Walls of Babylon
|
||||
rotate: false
|
||||
xy: 1084, 220
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Water Mill
|
||||
Wat
|
||||
rotate: false
|
||||
xy: 1192, 328
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Windmill
|
||||
Water Mill
|
||||
rotate: false
|
||||
xy: 1300, 436
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Workshop
|
||||
Windmill
|
||||
rotate: false
|
||||
xy: 1408, 544
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Workshop
|
||||
rotate: false
|
||||
xy: 1516, 652
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 264 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.1 MiB |
@ -22,7 +22,7 @@
|
||||
},
|
||||
// Column 1
|
||||
{
|
||||
"name": "Granary",
|
||||
"name": "Granary",
|
||||
"food": 2,
|
||||
"maintenance": 1,
|
||||
"hurryCostModifier": 25,
|
||||
@ -121,7 +121,7 @@
|
||||
"hurryCostModifier": 25,
|
||||
"maintenance": 1,
|
||||
"percentStatBonus": {"food": 15},
|
||||
"requiredTech": "The Wheel"
|
||||
"requiredTech": "The Wheel"
|
||||
},
|
||||
{
|
||||
"name": "Walls",
|
||||
@ -185,7 +185,7 @@
|
||||
"quote": "'He spoke, the son of Kronos, and nodded his head with the dark brows, and the immortally anointed hair of the great god swept from his divine head, and all Olympos was shaken' - The Iliad"
|
||||
// "Requires [Honor]" in BNW
|
||||
},
|
||||
|
||||
|
||||
// Classical Era
|
||||
|
||||
// Column 3
|
||||
@ -210,11 +210,11 @@
|
||||
"quote": "'They that go down to the sea in ships, that do business in great waters; these see the works of the Lord, and his wonders in the deep.' - The Bible, Psalms 107:23-24"
|
||||
},
|
||||
{
|
||||
"name": "Stable",
|
||||
"name": "Stable",
|
||||
"maintenance": 1,
|
||||
"requiredNearbyImprovedResources": ["Horses","Sheep","Cattle"],
|
||||
"hurryCostModifier": 25,
|
||||
"uniques": ["+[15]% Production when constructing [Mounted] units [in this city]",
|
||||
"uniques": ["+[15]% Production when constructing [Mounted] units [in this city]",
|
||||
"[+1 Production] from [Cattle] tiles [in this city]",
|
||||
"[+1 Production] from [Horses] tiles [in this city]",
|
||||
"[+1 Production] from [Sheep] tiles [in this city]"],
|
||||
@ -248,7 +248,7 @@
|
||||
"quote": "'I think that if ever a mortal heard the word of God it would be in a garden at the cool of the day.' - F. Frankfort Moore"
|
||||
},
|
||||
{
|
||||
"name": "Colosseum",
|
||||
"name": "Colosseum",
|
||||
"maintenance": 1,
|
||||
"happiness": 2,
|
||||
"hurryCostModifier": 25,
|
||||
@ -320,7 +320,7 @@
|
||||
// stats, so it's a mish-mash of vanilla and G&K. It should be changed when faith is
|
||||
// implemented.
|
||||
|
||||
// Further edit: Temples are now implemented. However, due to Religion still being in
|
||||
// Further edit: Temples are now implemented. However, due to Religion still being in
|
||||
// its alpha stages, these buildings are still the culture variant. When religion is finally
|
||||
// fully released, this building should be replaced with amphitheatres in existing save files,
|
||||
// and then later the G&K faith version can be added
|
||||
@ -344,7 +344,7 @@
|
||||
// stats, so it's a mish-mash of vanilla and G&K. It should be changed when faith is
|
||||
// implemented.
|
||||
|
||||
// Further edit: Temples are now implemented. However, due to Religion still being in
|
||||
// Further edit: Temples are now implemented. However, due to Religion still being in
|
||||
// its alpha stages, these buildings are still the culture variant. When religion is finally
|
||||
// fully released, this building should be replaced with amphitheatres in existing save files,
|
||||
// and then later the G&K faith version can be added
|
||||
@ -431,7 +431,7 @@
|
||||
"requiredTech": "Iron Working",
|
||||
"quote": "'Why man, he doth bestride the narrow world like a colossus, and we petty men walk under his huge legs, and peep about to find ourselves dishonorable graves.' - William Shakespeare, Julius Caesar"
|
||||
},
|
||||
|
||||
|
||||
// Medieval Era
|
||||
|
||||
// Column 5
|
||||
@ -489,7 +489,7 @@
|
||||
"quote": "'Few romances can ever surpass that of the granite citadel on top of the beetling precipices of Machu Picchu, the crown of Inca Land.' - Hiram Bingham"
|
||||
},
|
||||
{
|
||||
"name": "Workshop",
|
||||
"name": "Workshop",
|
||||
"maintenance": 2,
|
||||
"production": 2,
|
||||
"specialistSlots": {"Engineer": 1},
|
||||
@ -631,7 +631,7 @@
|
||||
"uniques": ["New [Military] units start with [15] Experience [in this city]"]
|
||||
"requiredTech": "Steel"
|
||||
},
|
||||
|
||||
|
||||
// Renaissance Era
|
||||
|
||||
// Column 7
|
||||
@ -674,7 +674,7 @@
|
||||
{
|
||||
"name": "Satrap's Court",
|
||||
"replaces": "Bank",
|
||||
"uniqueTo": "Persia",
|
||||
"uniqueTo": "Persia",
|
||||
"gold": 2,
|
||||
"specialistSlots": {"Merchant": 1},
|
||||
"happiness": 2,
|
||||
@ -686,7 +686,7 @@
|
||||
{
|
||||
"name": "Hanse",
|
||||
"replaces": "Bank",
|
||||
"uniqueTo": "Germany",
|
||||
"uniqueTo": "Germany",
|
||||
"gold": 2,
|
||||
"specialistSlots": {"Merchant": 1},
|
||||
"hurryCostModifier": 15,
|
||||
@ -717,7 +717,7 @@
|
||||
"name": "Leaning Tower of Pisa",
|
||||
"culture": 1,
|
||||
"isWonder": true,
|
||||
"greatPersonPoints": {"Great Artist": 1},
|
||||
"greatPersonPoints": {"Great Artist": 1},
|
||||
"uniques": ["[+25]% great person generation [in all cities]", "Free Great Person"],
|
||||
"requiredTech": "Printing Press",
|
||||
"quote": "'Don't clap too hard - it's a very old building.' - John Osbourne"
|
||||
@ -769,7 +769,7 @@
|
||||
"uniques": ["Free [Great Scientist] appears","Science gained from research agreements [+50]%"],
|
||||
"requiredTech": "Architecture",
|
||||
"quote": "'Things always seem fairer when we look back at them, and it is out of that inaccessible tower of the past that Longing leans and beckons.' - James Russell Lowell"
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "Windmill",
|
||||
"production": 2,
|
||||
@ -797,7 +797,7 @@
|
||||
"requiredTech": "Metallurgy",
|
||||
"quote": "'The Law is a fortress on a hill that armies cannot take or floods wash away.' - The Prophet Muhammed"
|
||||
},
|
||||
|
||||
|
||||
// Industrial Era
|
||||
|
||||
// Column 9
|
||||
@ -896,7 +896,7 @@
|
||||
"requiredTech": "Electricity"
|
||||
},
|
||||
*/
|
||||
|
||||
|
||||
// Modern Era
|
||||
|
||||
// Column 11
|
||||
@ -1003,7 +1003,7 @@
|
||||
// Column 14
|
||||
{
|
||||
"name": "Solar Plant",
|
||||
"production": 5,
|
||||
"production": 5,
|
||||
"percentStatBonus": {"production": 15},
|
||||
"requiredBuilding": "Factory",
|
||||
"maintenance": 3,
|
||||
@ -1092,17 +1092,15 @@
|
||||
"requiredTech": "Robotics"
|
||||
},
|
||||
// Column 16
|
||||
/*
|
||||
{
|
||||
"name": "United Nations",
|
||||
"isWonder": true,
|
||||
"culture": 1,
|
||||
"greatPersonPoints": {"Great Merchant": 2},
|
||||
"uniques": ["Triggers voting for the Diplomatic Victory"],
|
||||
"quote": "'More than ever before in human history, we share a common destiny. We can master it only if we face it together. And that is why we have the United Nations.' - Kofi Annan"
|
||||
"requiredTech": "Globalization", // todo doesn't exist yet!
|
||||
"requiredTech": "Globalization",
|
||||
"uniques": ["Triggers voting for the Diplomatic Victory", "Hidden when [Diplomatic] Victory is disabled", "Triggers a global alert upon completion"],
|
||||
"quote": "'More than ever before in human history, we share a common destiny. We can master it only if we face it together. And that is why we have the United Nations.' - Kofi Annan"
|
||||
},
|
||||
*/
|
||||
{
|
||||
"name": "SS Engine",
|
||||
"requiredResource": "Aluminum",
|
||||
@ -1117,12 +1115,12 @@
|
||||
},
|
||||
|
||||
// All Eras
|
||||
|
||||
|
||||
{
|
||||
"name": "Utopia Project",
|
||||
"cost": 1500,
|
||||
"isNationalWonder": true,
|
||||
"uniques": ["Hidden until [5] social policy branches have been completed", "Triggers a global alert upon build start",
|
||||
"Triggers a Cultural Victory upon completion", "Hidden when cultural victory is disabled"]
|
||||
"uniques": ["Hidden until [5] social policy branches have been completed", "Triggers a global alert upon build start",
|
||||
"Triggers a Cultural Victory upon completion", "Hidden when [Cultural] Victory is disabled"]
|
||||
}
|
||||
]
|
||||
|
@ -606,6 +606,12 @@
|
||||
"buildingCost": 750,
|
||||
"wonderCost": 1250,
|
||||
"techs": [
|
||||
{
|
||||
"name": "Globalization",
|
||||
"row": 2,
|
||||
"prerequisites": ["Telecommunications"],
|
||||
"quote": "'The new electronic interdependence recreates the world in the image of a global village.' - Marshall McLuhan"
|
||||
},
|
||||
{
|
||||
"name": "Particle Physics",
|
||||
"row": 3,
|
||||
@ -642,7 +648,7 @@
|
||||
{
|
||||
"name": "Future Tech",
|
||||
"row": 5,
|
||||
"prerequisites": ["Particle Physics", "Nuclear Fusion", "Nanotechnology", "Stealth"],
|
||||
"prerequisites": ["Globalization","Particle Physics", "Nuclear Fusion", "Nanotechnology", "Stealth"],
|
||||
"uniques": ["Who knows what the future holds?", "Can be continually researched"],
|
||||
"quote": "'I think we agree, the past is over.' - George W. Bush"
|
||||
}
|
||||
|
@ -787,6 +787,7 @@ Treasury deficit =
|
||||
Science victory =
|
||||
Cultural victory =
|
||||
Conquest victory =
|
||||
Diplomatic victory =
|
||||
Complete all the spaceship parts\n to win! =
|
||||
Complete 5 policy branches\n to win! =
|
||||
Complete 5 policy branches and build\n the Utopia Project to win! =
|
||||
@ -794,12 +795,14 @@ Destroy all enemies\n to win! =
|
||||
You have won a scientific victory! =
|
||||
You have won a cultural victory! =
|
||||
You have won a domination victory! =
|
||||
You have won a diplomatic victory! =
|
||||
You have won! =
|
||||
You have achieved victory through the awesome power of your Culture. Your civilization's greatness - the magnificence of its monuments and the power of its artists - have astounded the world! Poets will honor you as long as beauty brings gladness to a weary heart. =
|
||||
The world has been convulsed by war. Many great and powerful civilizations have fallen, but you have survived - and emerged victorious! The world will long remember your glorious triumph! =
|
||||
You have achieved victory through mastery of Science! You have conquered the mysteries of nature and led your people on a voyage to a brave new world! Your triumph will be remembered as long as the stars burn in the night sky! =
|
||||
Your civilization stands above all others! The exploits of your people shall be remembered until the end of civilizaton itself! =
|
||||
You have been defeated. Your civilization has been overwhelmed by its many foes. But your people do not despair, for they know that one day you shall return - and lead them forward to victory! =
|
||||
You have triumphed over your foes through the art of diplomacy! Your cunning and wisdom have earned you great friends - and divided and sown confusion among your enemies! Forever will you be remembered as the leader who brought peace to this weary world! =
|
||||
One more turn...! =
|
||||
Built Apollo Program =
|
||||
Destroy [civName] =
|
||||
@ -809,6 +812,16 @@ Rankings =
|
||||
Spaceship parts remaining =
|
||||
Branches completed =
|
||||
Undefeated civs =
|
||||
# The \n here means: put a newline (enter) here. If this is omitted, the sidebox in the diplomacy overview will become _really_ wide.
|
||||
# Feel free to replace it with a space and put it somewhere else in your translation
|
||||
Turns until the next\ndiplomacy victory vote: [$turnsTillNextDiplomaticVote] =
|
||||
Choose a civ to vote for =
|
||||
Choose who should become the world leader and win a diplomatic victory! =
|
||||
Voted for =
|
||||
Vote for [civilizationName] =
|
||||
Continue =
|
||||
Abstained =
|
||||
Vote for World Leader =
|
||||
|
||||
# Capturing a city
|
||||
|
||||
|
@ -43,6 +43,9 @@ class GameInfo {
|
||||
var currentPlayer = ""
|
||||
var gameId = UUID.randomUUID().toString() // random string
|
||||
|
||||
// Maps a civ to the civ they voted for
|
||||
var diplomaticVictoryVotesCast = HashMap<String, String>()
|
||||
|
||||
/**Keep track of a custom location this game was saved to _or_ loaded from
|
||||
*
|
||||
* Note this was used as silent autosave destination, but it was decided (#3898) to
|
||||
@ -71,6 +74,7 @@ class GameInfo {
|
||||
toReturn.difficulty = difficulty
|
||||
toReturn.gameParameters = gameParameters
|
||||
toReturn.gameId = gameId
|
||||
toReturn.diplomaticVictoryVotesCast.putAll(diplomaticVictoryVotesCast)
|
||||
toReturn.oneMoreTurnMode = oneMoreTurnMode
|
||||
toReturn.customSaveLocation = customSaveLocation
|
||||
return toReturn
|
||||
@ -454,4 +458,4 @@ class GameInfoPreview {
|
||||
var gameId = ""
|
||||
var currentPlayer = ""
|
||||
fun getCivilization(civName: String) = civilizations.first { it.civName == civName }
|
||||
}
|
||||
}
|
@ -50,6 +50,7 @@ object NextTurnAutomation {
|
||||
automateUnits(civInfo)
|
||||
reassignWorkedTiles(civInfo)
|
||||
trainSettler(civInfo)
|
||||
tryVoteForDiplomaticVictory(civInfo)
|
||||
|
||||
}
|
||||
|
||||
@ -208,6 +209,7 @@ object NextTurnAutomation {
|
||||
VictoryType.Cultural -> listOf("Piety", "Freedom", "Tradition", "Commerce", "Patronage")
|
||||
VictoryType.Scientific -> listOf("Rationalism", "Commerce", "Liberty", "Order", "Patronage")
|
||||
VictoryType.Domination -> listOf("Autocracy", "Honor", "Liberty", "Rationalism", "Commerce")
|
||||
VictoryType.Diplomatic -> listOf("Patronage", "Commerce", "Rationalism", "Freedom", "Tradition")
|
||||
VictoryType.Neutral -> listOf()
|
||||
}
|
||||
val policiesByPreference = adoptablePolicies
|
||||
@ -464,7 +466,7 @@ object NextTurnAutomation {
|
||||
.filterNot { it == civInfo || it.isBarbarian() || it.cities.isEmpty() }
|
||||
.filter { !civInfo.getDiplomacyManager(it).hasFlag(DiplomacyFlags.DeclinedPeace) }
|
||||
// Don't allow AIs to offer peace to city states allied with their enemies
|
||||
.filterNot { it.isCityState() && it.getAllyCiv() != "" && civInfo.isAtWarWith(civInfo.gameInfo.getCivilization(it.getAllyCiv())) }
|
||||
.filterNot { it.isCityState() && it.getAllyCiv() != null && civInfo.isAtWarWith(civInfo.gameInfo.getCivilization(it.getAllyCiv()!!)) }
|
||||
|
||||
for (enemy in enemiesCiv) {
|
||||
val motivationToAttack = motivationToAttack(civInfo, enemy)
|
||||
@ -559,6 +561,27 @@ object NextTurnAutomation {
|
||||
}
|
||||
}
|
||||
|
||||
// Technically, this function should also check for civs that have liberated one or more cities
|
||||
// Hoewever, that can be added in another update, this PR is large enough as it is.
|
||||
private fun tryVoteForDiplomaticVictory(civInfo: CivilizationInfo) {
|
||||
if (!civInfo.mayVoteForDiplomaticVictory()) return
|
||||
val chosenCiv: String? = if (civInfo.isMajorCiv()) {
|
||||
|
||||
val knownMajorCivs = civInfo.getKnownCivs().filter { it.isMajorCiv() }
|
||||
val highestOpinion = knownMajorCivs
|
||||
.maxOfOrNull {
|
||||
civInfo.getDiplomacyManager(it).opinionOfOtherCiv()
|
||||
}
|
||||
|
||||
if (highestOpinion == null) null
|
||||
else knownMajorCivs.filter { civInfo.getDiplomacyManager(it).opinionOfOtherCiv() == highestOpinion}.random().civName
|
||||
|
||||
} else {
|
||||
civInfo.getAllyCiv()
|
||||
}
|
||||
|
||||
civInfo.diplomaticVoteForCiv(chosenCiv)
|
||||
}
|
||||
|
||||
private fun issueRequests(civInfo: CivilizationInfo) {
|
||||
for (otherCiv in civInfo.getKnownCivs().filter { it.isMajorCiv() && !civInfo.isAtWarWith(it) }) {
|
||||
|
@ -89,13 +89,13 @@ class CivilizationInfo {
|
||||
var diplomacy = HashMap<String, DiplomacyManager>()
|
||||
var notifications = ArrayList<Notification>()
|
||||
val popupAlerts = ArrayList<PopupAlert>()
|
||||
private var allyCivName = ""
|
||||
private var allyCivName: String? = null
|
||||
var naturalWonders = ArrayList<String>()
|
||||
|
||||
/** for trades here, ourOffers is the current civ's offers, and theirOffers is what the requesting civ offers */
|
||||
val tradeRequests = ArrayList<TradeRequest>()
|
||||
|
||||
/** See DiplomacyManager.flagsCountdown to why not eEnum */
|
||||
/** See DiplomacyManager.flagsCountdown for why this does not map Enums to ints */
|
||||
private var flagsCountdown = HashMap<String, Int>()
|
||||
/** Arraylist instead of HashMap as there might be doubles
|
||||
* Pairs of Uniques and the amount of turns they are still active
|
||||
@ -540,7 +540,7 @@ class CivilizationInfo {
|
||||
|
||||
updateViewableTiles() // adds explored tiles so that the units will be able to perform automated actions better
|
||||
transients().updateCitiesConnectedToCapital()
|
||||
turnStartFlags()
|
||||
startTurnFlags()
|
||||
for (city in cities) city.startTurn()
|
||||
|
||||
for (unit in getCivUnits()) unit.startTurn()
|
||||
@ -606,14 +606,11 @@ class CivilizationInfo {
|
||||
updateHasActiveGreatWall()
|
||||
}
|
||||
|
||||
private fun turnStartFlags() {
|
||||
// This function may be too abstracted for what it currently does (only managing a single flag)
|
||||
// But eh, it works.
|
||||
private fun startTurnFlags() {
|
||||
for (flag in flagsCountdown.keys.toList()) {
|
||||
|
||||
if (flag == CivFlags.cityStateGreatPersonGift.name) {
|
||||
val cityStateAllies =
|
||||
getKnownCivs().filter { it.isCityState() && it.getAllyCiv() == civName }
|
||||
// the "ignoreCase = true" is to catch 'cityStateGreatPersonGift' instead of 'CityStateGreatPersonGift' being in old save files
|
||||
if (flag == CivFlags.CityStateGreatPersonGift.name || flag.equals(CivFlags.CityStateGreatPersonGift.name, ignoreCase = true)) {
|
||||
val cityStateAllies = getKnownCivs().filter { it.isCityState() && it.getAllyCiv() == civName }
|
||||
|
||||
if (cityStateAllies.any()) flagsCountdown[flag] = flagsCountdown[flag]!! - 1
|
||||
|
||||
@ -629,12 +626,52 @@ class CivilizationInfo {
|
||||
|
||||
if (flagsCountdown[flag]!! > 0)
|
||||
flagsCountdown[flag] = flagsCountdown[flag]!! - 1
|
||||
|
||||
|
||||
if (flagsCountdown[flag]!! != 0) continue
|
||||
|
||||
when (flag) {
|
||||
CivFlags.TurnsTillNextDiplomaticVote.name -> addFlag(CivFlags.ShowDiplomaticVotingResults.name, 1)
|
||||
CivFlags.ShouldResetDiplomaticVotes.name -> {
|
||||
gameInfo.diplomaticVictoryVotesCast.clear()
|
||||
removeFlag(CivFlags.ShouldResetDiplomaticVotes.name)
|
||||
removeFlag(CivFlags.ShowDiplomaticVotingResults.name)
|
||||
}
|
||||
CivFlags.ShowDiplomaticVotingResults.name -> {
|
||||
|
||||
if (gameInfo.civilizations.any { it.victoryManager.hasWon() } )
|
||||
// We have either already done this calculation, or it doesn't matter anymore,
|
||||
// so don't waste resources doing it
|
||||
continue
|
||||
|
||||
addFlag(CivFlags.ShouldResetDiplomaticVotes.name, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addFlag(flag: String, count: Int) { flagsCountdown[flag] = count }
|
||||
fun removeFlag(flag: String) { flagsCountdown.remove(flag) }
|
||||
|
||||
fun getTurnsBetweenDiplomaticVotings() = (15 * gameInfo.gameParameters.gameSpeed.modifier).toInt() // Dunno the exact calculation, hidden in Lua files
|
||||
|
||||
fun getTurnsTillNextDiplomaticVote() = flagsCountdown[CivFlags.TurnsTillNextDiplomaticVote.name]
|
||||
|
||||
fun mayVoteForDiplomaticVictory() =
|
||||
getTurnsTillNextDiplomaticVote() == 0
|
||||
&& civName !in gameInfo.diplomaticVictoryVotesCast.keys
|
||||
|
||||
fun diplomaticVoteForCiv(chosenCivName: String?) {
|
||||
if (chosenCivName != null) gameInfo.diplomaticVictoryVotesCast[civName] = chosenCivName
|
||||
addFlag(CivFlags.TurnsTillNextDiplomaticVote.name, getTurnsBetweenDiplomaticVotings())
|
||||
}
|
||||
|
||||
fun shouldShowDiplomaticVotingResults() =
|
||||
flagsCountdown[CivFlags.ShowDiplomaticVotingResults.name] == 0
|
||||
|
||||
// Yes, this is the same function as above, but with a different use case so it has a different name.
|
||||
fun shouldCheckForDiplomaticVictory() =
|
||||
flagsCountdown[CivFlags.ShowDiplomaticVotingResults.name] == 0
|
||||
|
||||
/** Modify gold by a given amount making sure it does neither overflow nor underflow.
|
||||
* @param delta the amount to add (can be negative)
|
||||
*/
|
||||
@ -717,7 +754,6 @@ class CivilizationInfo {
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun destroy() {
|
||||
val destructionText = if (isMajorCiv()) "The civilization of [$civName] has been destroyed!"
|
||||
else "The City-State of [$civName] has been destroyed!"
|
||||
@ -831,7 +867,7 @@ class CivilizationInfo {
|
||||
}
|
||||
|
||||
fun updateAllyCivForCityState() {
|
||||
var newAllyName = ""
|
||||
var newAllyName: String? = null
|
||||
if (!isCityState()) return
|
||||
val maxInfluence = diplomacy
|
||||
.filter { !it.value.otherCiv().isCityState() && !it.value.otherCiv().isDefeated() }
|
||||
@ -848,7 +884,7 @@ class CivilizationInfo {
|
||||
// This means that it will NOT HAVE a capital at that time, so if we run getCapital we'll get a crash!
|
||||
val capitalLocation = if (cities.isNotEmpty()) getCapital().location else null
|
||||
|
||||
if (newAllyName != "") {
|
||||
if (newAllyName != null) {
|
||||
val newAllyCiv = gameInfo.getCivilization(newAllyName)
|
||||
val text = "We have allied with [${civName}]."
|
||||
if (capitalLocation != null) newAllyCiv.addNotification(text, capitalLocation, civName, NotificationIcon.Diplomacy)
|
||||
@ -856,7 +892,7 @@ class CivilizationInfo {
|
||||
newAllyCiv.updateViewableTiles()
|
||||
newAllyCiv.updateDetailedCivResources()
|
||||
}
|
||||
if (oldAllyName != "") {
|
||||
if (oldAllyName != null) {
|
||||
val oldAllyCiv = gameInfo.getCivilization(oldAllyName)
|
||||
val text = "We have lost alliance with [${civName}]."
|
||||
if (capitalLocation != null) oldAllyCiv.addNotification(text, capitalLocation, civName, NotificationIcon.Diplomacy)
|
||||
@ -879,5 +915,8 @@ class CivilizationInfoPreview {
|
||||
}
|
||||
|
||||
enum class CivFlags {
|
||||
cityStateGreatPersonGift
|
||||
CityStateGreatPersonGift,
|
||||
TurnsTillNextDiplomaticVote,
|
||||
ShowDiplomaticVotingResults,
|
||||
ShouldResetDiplomaticVotes,
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ class VictoryManager {
|
||||
|
||||
var requiredSpaceshipParts = Counter<String>()
|
||||
var currentsSpaceshipParts = Counter<String>()
|
||||
var hasWonDiplomaticVictory = false
|
||||
|
||||
init {
|
||||
requiredSpaceshipParts.add("SS Booster", 3)
|
||||
@ -31,6 +32,36 @@ class VictoryManager {
|
||||
|
||||
fun spaceshipPartsRemaining() = requiredSpaceshipParts.values.sum() - currentsSpaceshipParts.values.sum()
|
||||
|
||||
fun calculateDiplomaticVotingResults(votesCast: HashMap<String, String>): Counter<String> {
|
||||
val results = Counter<String>()
|
||||
for (castVote in votesCast) {
|
||||
results.add(castVote.value, 1)
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
fun votesNeededForDiplomaticVictory(): Int {
|
||||
val civCount = civInfo.gameInfo.civilizations.count { !it.isDefeated() }
|
||||
|
||||
// CvGame.cpp::DoUpdateDiploVictory() in the source code of the original
|
||||
return (
|
||||
if (civCount > 28) 0.35 * civCount
|
||||
else (67 - 1.1 * civCount) / 100 * civCount
|
||||
).toInt()
|
||||
}
|
||||
|
||||
fun hasEnoughVotesForDiplomaticVictory(): Boolean {
|
||||
val results = calculateDiplomaticVotingResults(civInfo.gameInfo.diplomaticVictoryVotesCast)
|
||||
val bestCiv = results.maxByOrNull { it.value }
|
||||
if (bestCiv == null) return false
|
||||
|
||||
// If we don't have the highest score, we have not won anyway
|
||||
if (bestCiv.key != civInfo.civName) return false
|
||||
|
||||
// If there's a tie, we haven't won either
|
||||
return (results.none { it != bestCiv && it.value == bestCiv.value })
|
||||
}
|
||||
|
||||
private fun hasVictoryType(victoryType: VictoryType) = civInfo.gameInfo.gameParameters.victoryTypes.contains(victoryType)
|
||||
|
||||
fun hasWonScientificVictory() = hasVictoryType(VictoryType.Scientific) && spaceshipPartsRemaining() == 0
|
||||
@ -42,12 +73,17 @@ class VictoryManager {
|
||||
return hasVictoryType(VictoryType.Domination)
|
||||
&& civInfo.gameInfo.civilizations.all { it == civInfo || it.isDefeated() || !it.isMajorCiv() }
|
||||
}
|
||||
|
||||
fun hasWonDiplomaticVictory() = hasVictoryType(VictoryType.Diplomatic)
|
||||
&& civInfo.shouldCheckForDiplomaticVictory()
|
||||
&& hasEnoughVotesForDiplomaticVictory()
|
||||
|
||||
fun hasWonVictoryType(): VictoryType? {
|
||||
if (!civInfo.isMajorCiv()) return null
|
||||
if (hasWonDominationVictory()) return VictoryType.Domination
|
||||
if (hasWonScientificVictory()) return VictoryType.Scientific
|
||||
if (hasWonCulturalVictory()) return VictoryType.Cultural
|
||||
if (hasWonDiplomaticVictory()) return VictoryType.Diplomatic
|
||||
if (civInfo.hasUnique("Triggers victory")) return VictoryType.Neutral
|
||||
return null
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ class GameParameters { // Default values are the default new game
|
||||
var nuclearWeaponsEnabled = true
|
||||
var religionEnabled = false
|
||||
|
||||
var victoryTypes: ArrayList<VictoryType> = arrayListOf(VictoryType.Cultural, VictoryType.Domination, VictoryType.Scientific) // By default, all victory types
|
||||
// By default, all victory types except Diplomacy as it is quite new
|
||||
var victoryTypes: ArrayList<VictoryType> = arrayListOf(VictoryType.Cultural, VictoryType.Domination, VictoryType.Scientific)
|
||||
var startingEra = "Ancient Era"
|
||||
|
||||
var isOnlineMultiplayer = false
|
||||
|
@ -494,11 +494,18 @@ class Building : NamedStats(), IConstruction, ICivilopediaText {
|
||||
return "Should not be displayed"
|
||||
}
|
||||
}
|
||||
"Hidden when cultural victory is disabled" -> {
|
||||
if ( !civInfo.gameInfo.gameParameters.victoryTypes.contains(VictoryType.Cultural)) {
|
||||
return "Hidden when cultural victory is disabled"
|
||||
"Hidden when [] Victory is disabled" -> {
|
||||
if (!civInfo.gameInfo.gameParameters.victoryTypes.contains(VictoryType.valueOf(unique.params[0]))) {
|
||||
return unique.text
|
||||
}
|
||||
}
|
||||
// Deprecated since 3.15.14
|
||||
"Hidden when cultural victory is disabled" -> {
|
||||
if (!civInfo.gameInfo.gameParameters.victoryTypes.contains(VictoryType.Cultural)) {
|
||||
return unique.text
|
||||
}
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
if (requiredBuilding != null && !construction.containsBuildingOrEquivalent(requiredBuilding!!)) {
|
||||
|
@ -17,8 +17,9 @@ import com.unciv.ui.utils.colorFromRGB
|
||||
enum class VictoryType {
|
||||
Neutral,
|
||||
Cultural,
|
||||
Diplomatic,
|
||||
Domination,
|
||||
Scientific
|
||||
Scientific,
|
||||
}
|
||||
|
||||
class Nation : INamed, ICivilopediaText {
|
||||
|
@ -110,7 +110,7 @@ object UniqueTriggerActivation {
|
||||
}
|
||||
}
|
||||
"Allied City-States will occasionally gift Great People" ->
|
||||
civInfo.addFlag(CivFlags.cityStateGreatPersonGift.name, civInfo.turnsForGreatPersonFromCityState() / 2)
|
||||
civInfo.addFlag(CivFlags.CityStateGreatPersonGift.name, civInfo.turnsForGreatPersonFromCityState() / 2)
|
||||
// The mechanics for granting great people are wonky, but basically the following happens:
|
||||
// Based on the game speed, a timer with some amount of turns is set, 40 on regular speed
|
||||
// Every turn, 1 is subtracted from this timer, as long as you have at least 1 city state ally
|
||||
@ -126,6 +126,10 @@ object UniqueTriggerActivation {
|
||||
|
||||
// Note that the way this is implemented now, this unique does NOT stack
|
||||
// I could parametrize the [Allied], but eh.
|
||||
"Triggers voting for the Diplomatic Victory" ->
|
||||
for (civ in civInfo.gameInfo.civilizations)
|
||||
if (!civ.isBarbarian() && !civ.isSpectator())
|
||||
civ.addFlag(CivFlags.TurnsTillNextDiplomaticVote.name, civInfo.getTurnsBetweenDiplomaticVotings())
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.*
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.Unique
|
||||
import com.unciv.models.ruleset.VictoryType
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.models.translations.tr
|
||||
@ -172,12 +173,9 @@ class CivilopediaScreen(
|
||||
onBackButtonClicked { UncivGame.Current.setWorldScreen() }
|
||||
|
||||
val hideReligionItems = !game.gameInfo.hasReligionEnabled()
|
||||
val noCulturalVictory = VictoryType.Cultural !in game.gameInfo.gameParameters.victoryTypes
|
||||
|
||||
categoryToEntries[CivilopediaCategories.Building] = ruleset.buildings.values
|
||||
.filter { "Will not be displayed in Civilopedia" !in it.uniques
|
||||
&& !(hideReligionItems && "Hidden when religion is disabled" in it.uniques)
|
||||
&& !(noCulturalVictory && "Hidden when cultural victory is disabled" in it.uniques)
|
||||
.filter { shouldBeDisplayed(it.uniqueObjects)
|
||||
&& !it.isAnyWonder() }
|
||||
.map {
|
||||
CivilopediaEntry(
|
||||
@ -188,9 +186,7 @@ class CivilopediaScreen(
|
||||
)
|
||||
}
|
||||
categoryToEntries[CivilopediaCategories.Wonder] = ruleset.buildings.values
|
||||
.filter { "Will not be displayed in Civilopedia" !in it.uniques
|
||||
&& !(hideReligionItems && "Hidden when religion is disabled" in it.uniques)
|
||||
&& !(noCulturalVictory && "Hidden when cultural victory is disabled" in it.uniques)
|
||||
.filter { shouldBeDisplayed(it.uniqueObjects)
|
||||
&& it.isAnyWonder() }
|
||||
.map {
|
||||
CivilopediaEntry(
|
||||
@ -210,6 +206,7 @@ class CivilopediaScreen(
|
||||
)
|
||||
}
|
||||
categoryToEntries[CivilopediaCategories.Terrain] = ruleset.terrains.values
|
||||
.filter { shouldBeDisplayed(it.uniqueObjects) }
|
||||
.map {
|
||||
CivilopediaEntry(
|
||||
it.name,
|
||||
@ -219,6 +216,7 @@ class CivilopediaScreen(
|
||||
)
|
||||
}
|
||||
categoryToEntries[CivilopediaCategories.Improvement] = ruleset.tileImprovements.values
|
||||
.filter { shouldBeDisplayed(it.uniqueObjects) }
|
||||
.map {
|
||||
CivilopediaEntry(
|
||||
it.name,
|
||||
@ -228,9 +226,7 @@ class CivilopediaScreen(
|
||||
)
|
||||
}
|
||||
categoryToEntries[CivilopediaCategories.Unit] = ruleset.units.values
|
||||
.filter { "Will not be displayed in Civilopedia" !in it.uniques
|
||||
&& !(hideReligionItems && "Hidden when religion is disabled" in it.uniques)
|
||||
}
|
||||
.filter { shouldBeDisplayed(it.uniqueObjects) }
|
||||
.map {
|
||||
CivilopediaEntry(
|
||||
it.name,
|
||||
@ -240,7 +236,7 @@ class CivilopediaScreen(
|
||||
)
|
||||
}
|
||||
categoryToEntries[CivilopediaCategories.Nation] = ruleset.nations.values
|
||||
.filter { it.isMajorCiv() }
|
||||
.filter { shouldBeDisplayed(it.uniqueObjects) && it.isMajorCiv() }
|
||||
.map {
|
||||
CivilopediaEntry(
|
||||
it.name,
|
||||
@ -250,6 +246,7 @@ class CivilopediaScreen(
|
||||
)
|
||||
}
|
||||
categoryToEntries[CivilopediaCategories.Technology] = ruleset.technologies.values
|
||||
.filter { shouldBeDisplayed(it.uniqueObjects) }
|
||||
.map {
|
||||
CivilopediaEntry(
|
||||
it.name,
|
||||
@ -259,6 +256,7 @@ class CivilopediaScreen(
|
||||
)
|
||||
}
|
||||
categoryToEntries[CivilopediaCategories.Promotion] = ruleset.unitPromotions.values
|
||||
.filter { shouldBeDisplayed(it.uniqueObjects) }
|
||||
.map {
|
||||
CivilopediaEntry(
|
||||
it.name,
|
||||
@ -376,6 +374,21 @@ class CivilopediaScreen(
|
||||
}
|
||||
return SimpleCivilopediaText(lines, true)
|
||||
}
|
||||
|
||||
private fun shouldBeDisplayed(uniqueObjects: List<Unique>): Boolean {
|
||||
val uniques = uniqueObjects.map { it.placeholderText }
|
||||
val hideReligionItems = !game.gameInfo.hasReligionEnabled()
|
||||
val noCulturalVictory = VictoryType.Cultural !in game.gameInfo.gameParameters.victoryTypes
|
||||
|
||||
return "Will not be displayed in Civilopedia" !in uniques
|
||||
&& !(hideReligionItems && "Hidden when religion is disabled" in uniques)
|
||||
&& !(uniqueObjects.filter { unique -> unique.placeholderText == "Hidden when [] Victory is disabled"}.any {
|
||||
unique -> !game.gameInfo.gameParameters.victoryTypes.contains(VictoryType.valueOf(unique.params[0] ))
|
||||
})
|
||||
// Deprecated since 3.15.14
|
||||
&& !(noCulturalVictory && "Hidden when cultural victory is disabled" in uniques)
|
||||
//
|
||||
}
|
||||
|
||||
override fun resize(width: Int, height: Int) {
|
||||
if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) {
|
||||
|
@ -72,6 +72,9 @@ class DiplomacyOverviewTable (
|
||||
civTable.background = ImageGetter.getBackground(Color.BLACK)
|
||||
civTable.add("[${relevantCivs.size}] Civilizations in the game".toLabel()).pad(5f).colspan(2).row()
|
||||
civTable.add(titleTable).colspan(2).row()
|
||||
val turnsTillNextDiplomaticVote = viewingPlayer.getTurnsTillNextDiplomaticVote()
|
||||
if (turnsTillNextDiplomaticVote != null)
|
||||
civTable.add("Turns until the next\ndiplomacy victory vote: [$turnsTillNextDiplomaticVote]".toLabel()).center().pad(5f).colspan(2).row()
|
||||
civTable.addSeparator()
|
||||
civTable.add("Known and alive ([${playerKnowsAndUndefeatedCivs.size - 1}])".toLabel())
|
||||
.pad(5f).colspan(2).row()
|
||||
|
@ -0,0 +1,42 @@
|
||||
package com.unciv.ui.pickerscreens
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Button
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.ImageGetter
|
||||
import com.unciv.ui.utils.onClick
|
||||
import com.unciv.ui.utils.toLabel
|
||||
|
||||
class DiplomaticVotePickerScreen(private val votingCiv: CivilizationInfo) : PickerScreen() {
|
||||
private var chosenCiv: String? = null
|
||||
|
||||
init {
|
||||
setDefaultCloseAction()
|
||||
rightSideButton.setText("Choose a civ to vote for".tr())
|
||||
|
||||
descriptionLabel.setText("Choose who should become the world leader and win a diplomatic victory!".tr())
|
||||
|
||||
val choosableCivs = votingCiv.gameInfo.civilizations.filter { it.isMajorCiv() && it != votingCiv && !it.isDefeated() }
|
||||
for (civ in choosableCivs)
|
||||
{
|
||||
val button = Button(skin)
|
||||
|
||||
button.add(ImageGetter.getNationIndicator(civ.nation, 30f)).pad(10f)
|
||||
button.add(civ.civName.toLabel()).pad(10f)
|
||||
button.pack()
|
||||
button.onClick {
|
||||
chosenCiv = civ.civName
|
||||
pick("Vote for [${civ.civName}]".tr())
|
||||
}
|
||||
topTable.add(button).pad(10f).row()
|
||||
}
|
||||
|
||||
rightSideButton.onClick(UncivSound.Chimes) {
|
||||
votingCiv.diplomaticVoteForCiv(chosenCiv!!)
|
||||
UncivGame.Current.setWorldScreen()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.unciv.ui.pickerscreens
|
||||
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.civilization.CivFlags
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.ImageGetter
|
||||
import com.unciv.ui.utils.enable
|
||||
import com.unciv.ui.utils.onClick
|
||||
import com.unciv.ui.utils.toLabel
|
||||
|
||||
class DiplomaticVoteResultScreen(val votesCast: HashMap<String, String>, val viewingCiv: CivilizationInfo) : PickerScreen() {
|
||||
val gameInfo = viewingCiv.gameInfo
|
||||
|
||||
init {
|
||||
closeButton.remove()
|
||||
|
||||
addVote(viewingCiv.civName)
|
||||
|
||||
for (civ in gameInfo.civilizations.filter { it.isMajorCiv() && it != viewingCiv })
|
||||
addVote(civ.civName)
|
||||
for (civ in gameInfo.civilizations.filter { it.isCityState() })
|
||||
addVote(civ.civName)
|
||||
|
||||
rightSideButton.onClick(UncivSound.Click) {
|
||||
viewingCiv.addFlag(CivFlags.ShowDiplomaticVotingResults.name, -1)
|
||||
UncivGame.Current.setWorldScreen()
|
||||
}
|
||||
rightSideButton.enable()
|
||||
rightSideButton.setText("Continue".tr())
|
||||
}
|
||||
|
||||
private fun addVote(civName: String) {
|
||||
val civ = gameInfo.civilizations.firstOrNull { it.civName == civName }
|
||||
if (civ == null || civ.isDefeated()) return
|
||||
|
||||
topTable.add(ImageGetter.getNationIndicator(civ.nation, 30f)).pad(10f)
|
||||
topTable.add(civName.toLabel()).pad(20f)
|
||||
if (civName !in votesCast.keys) {
|
||||
topTable.add("Abstained".toLabel()).row()
|
||||
return
|
||||
}
|
||||
|
||||
val votedCiv = gameInfo.civilizations.firstOrNull { it.civName == votesCast[civName] }!!
|
||||
if (votedCiv.isDefeated()) {
|
||||
topTable.add("Abstained".toLabel()).row()
|
||||
return
|
||||
}
|
||||
|
||||
topTable.add("Voted for".toLabel()).pad(20f)
|
||||
topTable.add(ImageGetter.getNationIndicator(votedCiv.nation, 30f)).pad(10f)
|
||||
topTable.add(votedCiv.civName.toLabel()).row()
|
||||
}
|
||||
}
|
@ -115,7 +115,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
|
||||
|
||||
otherCiv.updateAllyCivForCityState()
|
||||
val ally = otherCiv.getAllyCiv()
|
||||
if (ally != "") {
|
||||
if (ally != null) {
|
||||
val allyString = "{Ally}: {$ally} {Influence}: ".tr() +
|
||||
otherCiv.getDiplomacyManager(ally).influence.toString()
|
||||
diplomacyTable.add(allyString.toLabel()).row()
|
||||
|
@ -6,6 +6,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.ruleset.VictoryType
|
||||
import com.unciv.models.translations.getPlaceholderParameters
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.newgamescreen.GameSetupInfo
|
||||
import com.unciv.ui.newgamescreen.NewGameScreen
|
||||
@ -54,24 +55,14 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
|
||||
val playerVictoryType = playerCivInfo.victoryManager.hasWonVictoryType()
|
||||
if (playerVictoryType != null) {
|
||||
someoneHasWon = true
|
||||
when (playerVictoryType) {
|
||||
VictoryType.Cultural -> wonOrLost("You have won a cultural victory!")
|
||||
VictoryType.Domination -> wonOrLost("You have won a domination victory!")
|
||||
VictoryType.Scientific -> wonOrLost("You have won a scientific victory!")
|
||||
VictoryType.Neutral -> wonOrLost("You have won!")
|
||||
}
|
||||
wonOrLost("You have won a [${playerVictoryType.name}] Victory!")
|
||||
}
|
||||
for (civ in gameInfo.civilizations.filter { it.isMajorCiv() && it != playerCivInfo }) {
|
||||
val civVictoryType = civ.victoryManager.hasWonVictoryType()
|
||||
if (civVictoryType != null) {
|
||||
someoneHasWon = true
|
||||
val winningCivName = civ.civName
|
||||
when (civVictoryType) {
|
||||
VictoryType.Cultural -> wonOrLost("[$winningCivName] has won a cultural victory!")
|
||||
VictoryType.Domination -> wonOrLost("[$winningCivName] has won a domination victory!")
|
||||
VictoryType.Scientific -> wonOrLost("[$winningCivName] has won a scientific victory!")
|
||||
VictoryType.Neutral -> wonOrLost("[$winningCivName] has won!")
|
||||
}
|
||||
wonOrLost("[$winningCivName] has won a [${civVictoryType.name}] Victory!")
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,12 +76,15 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
|
||||
|
||||
|
||||
private fun wonOrLost(description: String) {
|
||||
|
||||
val endGameMessage = when (description) {
|
||||
"You have won a cultural victory!" -> "You have achieved victory through the awesome power of your Culture. Your civilization's greatness - the magnificence of its monuments and the power of its artists - have astounded the world! Poets will honor you as long as beauty brings gladness to a weary heart."
|
||||
"You have won a domination victory!" -> "The world has been convulsed by war. Many great and powerful civilizations have fallen, but you have survived - and emerged victorious! The world will long remember your glorious triumph!"
|
||||
"You have won a scientific victory!" -> "You have achieved victory through mastery of Science! You have conquered the mysteries of nature and led your people on a voyage to a brave new world! Your triumph will be remembered as long as the stars burn in the night sky!"
|
||||
"You have won!" -> "Your civilization stands above all others! The exploits of your people shall be remembered until the end of civilizaton itself!"
|
||||
|
||||
val endGameMessage = when (description.getPlaceholderParameters()[0]) {
|
||||
// Taking the 0th element is a dirty hack to differentiate between the cases
|
||||
// "you have won" and "someone else has won", but it works, so I don't question it
|
||||
VictoryType.Cultural.name -> "You have achieved victory through the awesome power of your Culture. Your civilization's greatness - the magnificence of its monuments and the power of its artists - have astounded the world! Poets will honor you as long as beauty brings gladness to a weary heart."
|
||||
VictoryType.Domination.name -> "The world has been convulsed by war. Many great and powerful civilizations have fallen, but you have survived - and emerged victorious! The world will long remember your glorious triumph!"
|
||||
VictoryType.Scientific.name -> "You have achieved victory through mastery of Science! You have conquered the mysteries of nature and led your people on a voyage to a brave new world! Your triumph will be remembered as long as the stars burn in the night sky!"
|
||||
VictoryType.Diplomatic.name -> "You have triumphed over your foes through the art of diplomacy! Your cunning and wisdom have earned you great friends - and divided and sown confusion among your enemies! Forever will you be remembered as the leader who brought peace to this weary world!"
|
||||
VictoryType.Neutral.name -> "Your civilization stands above all others! The exploits of your people shall be remembered until the end of civilizaton itself!"
|
||||
else -> "You have been defeated. Your civilization has been overwhelmed by its many foes. But your people do not despair, for they know that one day you shall return - and lead them forward to victory!"
|
||||
}
|
||||
|
||||
|
@ -400,6 +400,8 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Cam
|
||||
when {
|
||||
!gameInfo.oneMoreTurnMode && (viewingCiv.isDefeated() || gameInfo.civilizations.any { it.victoryManager.hasWon() }) ->
|
||||
game.setScreen(VictoryScreen(this))
|
||||
viewingCiv.shouldShowDiplomaticVotingResults() ->
|
||||
UncivGame.Current.setScreen(DiplomaticVoteResultScreen(gameInfo.diplomaticVictoryVotesCast, viewingCiv))
|
||||
viewingCiv.greatPeople.freeGreatPeople > 0 -> game.setScreen(GreatPersonPickerScreen(viewingCiv))
|
||||
viewingCiv.popupAlerts.any() -> AlertPopup(this, viewingCiv.popupAlerts.first()).open()
|
||||
viewingCiv.tradeRequests.isNotEmpty() -> TradePopup(this).open()
|
||||
@ -701,6 +703,10 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Cam
|
||||
NextTurnAction("Found Religion", Color.WHITE) {
|
||||
game.setScreen(FoundReligionPickerScreen(viewingCiv, gameInfo))
|
||||
}
|
||||
viewingCiv.mayVoteForDiplomaticVictory() ->
|
||||
NextTurnAction("Vote for World Leader", Color.RED) {
|
||||
game.setScreen(DiplomaticVotePickerScreen(viewingCiv))
|
||||
}
|
||||
|
||||
else ->
|
||||
NextTurnAction("${Fonts.turn}{Next turn}", Color.WHITE) {
|
||||
|
@ -265,6 +265,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
|
||||
* [Harbor](https://thenounproject.com/term/harbor/225583/) By Rflor for Seaport
|
||||
* [Mansion](https://www.flaticon.com/free-icon/mansion_509903#term=persian&page=1&position=19) by Freepik for Satrap's Court
|
||||
* [Bullets](https://thenounproject.com/term/bullets/810156/) By Aldric Rodriguez for Arsenal
|
||||
* [St. Petersburg](https://thenounproject.com/search/?q=kremlin&i=1569704) By Carpe Diem for Kremlin
|
||||
|
||||
### Industrial Era
|
||||
|
||||
@ -281,30 +282,30 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
|
||||
* [Hangar](https://thenounproject.com/search/?q=hangar&i=1705288) By Rflor for Military Base
|
||||
* [Eiffel Tower](https://thenounproject.com/term/eiffel-tower/1907757/) By Felipe Alvarado
|
||||
* [Statue of Liberty](https://thenounproject.com/search/?q=statue%20of%20liberty&i=1801199) By 1516
|
||||
* [Microscope](https://thenounproject.com/term/microscope/1452362/) By Arafat Uddin for Research Lab
|
||||
* [Christ the redeemer](https://thenounproject.com/term/christ-the-redeemer/56112/) By Stefan Spieler for Cristo Redentor
|
||||
* [St. Petersburg](https://thenounproject.com/search/?q=kremlin&i=1569704) By Carpe Diem for Kremlin
|
||||
* [Neuschwanstein](https://thenounproject.com/search/?q=Neuschwanstein&i=2107683) By Vectors Market
|
||||
* [Big Ben](https://thenounproject.com/search/?q=Big%20Ben&i=443690) By Ben Davis, RO
|
||||
|
||||
### Information Era
|
||||
|
||||
### Atomic Era
|
||||
* [Chemistry](https://thenounproject.com/term/chemistry/175847/) By Creative Stall for Medical Lab
|
||||
* [Microscope](https://thenounproject.com/term/microscope/1452362/) By Arafat Uddin for Research Lab
|
||||
* [Water dam](https://thenounproject.com/term/water-dam/1002726/) By Symbolon for Hydro Plant
|
||||
* [Pentagon](https://thenounproject.com/search/?q=the%20pentagon&i=1788323) By Maxim Kulikov
|
||||
* [Solar panel](https://thenounproject.com/term/solar-panel/1131/) By Modik for Solar Plant
|
||||
* [Opera House Sydney](https://thenounproject.com/term/opera-house-sydney/1626283/) By Pham Duy Phuong Hung for Sydney Opera House
|
||||
* [Water dam](https://thenounproject.com/term/water-dam/1002726/) By Symbolon for Hydro Plant
|
||||
* [Manhattan Project](https://thenounproject.com/search/?q=Nuclear%20Bomb&i=2041074) By corpus delicti, GR
|
||||
* [Spaceship](https://thenounproject.com/term/spaceship/1444621/) By Dinosoft Labs for Apollo Program
|
||||
* [Build](https://thenounproject.com/term/build/1156478/) By Michael G Brown for Spaceship Factory
|
||||
* [Nuclear Plant](https://thenounproject.com/term/nuclear-plant/1132340/) By Andrejs Kirma
|
||||
* [Pentagon](https://thenounproject.com/search/?q=the%20pentagon&i=1788323) By Maxim Kulikov
|
||||
* [Spaceship](https://thenounproject.com/term/spaceship/1444621/) By Dinosoft Labs for Apollo Program
|
||||
|
||||
### Future Era
|
||||
* [Hubble Telescope](https://thenounproject.com/search/?q=hubble%20space&i=445502) By Scott Lewis for Hubble Space Telescope
|
||||
### Information Era
|
||||
* [CN Tower Toronto](https://thenounproject.com/search/?q=cn%20tower&i=807678) By mikicon for CN tower
|
||||
* [War Shelter](https://www.flaticon.com/free-icon/war-shelter_978661) by [Frepik](www.freepik.com) for Bomb Shelter
|
||||
* [Missile](https://thenounproject.com/term/missile/799922/) By ProSymbols for SS Booster
|
||||
* [Rocket](https://thenounproject.com/term/rocket/937173/) By BomSymbols for SS Cockpit
|
||||
* [Hubble Telescope](https://thenounproject.com/search/?q=hubble%20space&i=445502) By Scott Lewis for Hubble Space Telescope
|
||||
* [Build](https://thenounproject.com/term/build/1156478/) By Michael G Brown for Spaceship Factory
|
||||
* [United Nations](https://thenounproject.com/search/?q=united+nations&i=3104698) by Imam for United Nations
|
||||
* [Engine](https://thenounproject.com/term/engine/1877958/) By Andre for SS Engine
|
||||
* [Chamber](https://thenounproject.com/term/chamber/1242689/) By IYIKON for SS Stasis Chamber
|
||||
|
||||
@ -461,29 +462,32 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
|
||||
* [Plastic](https://thenounproject.com/term/plastic/478826/) By Yu luck
|
||||
* [Microphone](https://thenounproject.com/term/microphone/470266/) By Viktor Vorobyev for Mass Media
|
||||
* [Flight](https://thenounproject.com/term/flight/1014306/) By Genius Icons
|
||||
* [Train](https://thenounproject.com/term/train/651644/) By Federico Panzano for Railroad
|
||||
* [Refridgerator](https://thenounproject.com/search/?q=refridgerator&i=1188873) By b farias, CL
|
||||
* [Train](https://thenounproject.com/term/train/651644/) By Federico Panzano for Railroad
|
||||
* [Fridge](https://thenounproject.com/search/?q=refridgerator&i=1188873) By b farias for Refrigeration
|
||||
|
||||
### Atomic
|
||||
* [Pill](https://thenounproject.com/term/pill/780458/) By Alex Arseneau for Pharmaceuticals
|
||||
* [Satellite Dish](https://thenounproject.com/search/?q=satellite%20dish&i=2054441) By Vectors Market for Radar
|
||||
* [Ecology](https://thenounproject.com/term/ecology/1970666/) By ProSymbols
|
||||
* [Nuclear Reactor](https://thenounproject.com/term/nuclear-reactor/426463/) By Jeremie Sommet for Nuclear Fission
|
||||
* [Rocket](https://thenounproject.com/term/rocket/1743642/) By kareemov for Rocketry
|
||||
* [Computer](https://thenounproject.com/term/computer/1967529/) By Shastry for Computers
|
||||
|
||||
### Information
|
||||
* [Pill](https://thenounproject.com/term/pill/780458/) By Alex Arseneau for Pharmaceuticals
|
||||
* [Computer](https://thenounproject.com/term/computer/1967529/) By Shastry for Computers
|
||||
* [telecommunications](https://thenounproject.com/search/?q=telecommunications&i=3191260) by Wichai Wi for Telcommunications
|
||||
* [Tactics](https://thenounproject.com/search/?q=tactics&i=2290123) By Grafix Point for Mobile Tactics
|
||||
* [Laser](https://thenounproject.com/search/?q=laser&i=232249) by Andrew Doane for Lasers
|
||||
* [Satellite Dish](https://thenounproject.com/search/?q=satellite%20dish&i=2054441) By Vectors Market for Radar
|
||||
* [Nuclear Reactor](https://thenounproject.com/term/nuclear-reactor/426463/) By Jeremie Sommet for Nuclear Fission
|
||||
* [Ecology](https://thenounproject.com/term/ecology/1970666/) By ProSymbols
|
||||
* [Robotic Arm](https://thenounproject.com/term/robotic-arm/1970874/) By Karl Gilbert for Robotics
|
||||
* [Rocket](https://thenounproject.com/term/rocket/1743642/) By kareemov for Rocketry
|
||||
* [Rocket](https://thenounproject.com/term/rocket/3999811) Kusdarti for Advanced Ballistics
|
||||
* [Satellite](https://thenounproject.com/term/satellite/1466641/) By Ben Davis for Satellites
|
||||
* [Robotic Arm](https://thenounproject.com/term/robotic-arm/1970874/) By Karl Gilbert for Robotics
|
||||
* [Laser](https://thenounproject.com/search/?q=laser&i=232249) by Andrew Doane for Lasers
|
||||
* [global](https://thenounproject.com/search/?q=globalization&i=4073147) by Rank Sol for Globilization
|
||||
* [Atom](https://thenounproject.com/term/atom/1586852/) By Kelsey Armstrong for Particle Physics
|
||||
* [Nanoparticles](https://thenounproject.com/term/nanoparticles/822286/) By Gyan Lakhwani for Nanotechnology
|
||||
* [Thermonuclear fusion](https://thenounproject.com/search/?q=fusion&i=3292735) by Olena Panasovska, UA for Nuclear Fusion
|
||||
* [Electronics](https://thenounproject.com/search/?q=Electronics&i=1565843) By Cuby Design
|
||||
* [Radar](https://thenounproject.com/term/radar/1546196/) By CINDYFLA, ID for Stealth
|
||||
|
||||
### Future
|
||||
* [Nanoparticles](https://thenounproject.com/term/nanoparticles/822286/) By Gyan Lakhwani for Nanotechnology
|
||||
* [Satellite](https://thenounproject.com/term/satellite/1466641/) By Ben Davis for Satellites
|
||||
* [Electronics](https://thenounproject.com/search/?q=Electronics&i=1565843) By Cuby Design
|
||||
* [Atom](https://thenounproject.com/term/atom/1586852/) By Kelsey Armstrong for Particle Physics
|
||||
* [Thermonuclear fusion](https://thenounproject.com/search/?q=fusion&i=3292735) by Olena Panasovska, UA for Nuclear Fusion
|
||||
* [telecommunications](https://thenounproject.com/search/?q=telecommunications&i=3191260) by Wichai Wi for Telcommunications
|
||||
* [Radar](https://thenounproject.com/term/radar/1546196/) By CINDYFLA, ID for Stealth
|
||||
* [Information Technology](https://thenounproject.com/term/information-technology/1927668/) By Vectors Markeet for Future Tech
|
||||
|
||||
## Terrain
|
||||
|
Loading…
Reference in New Issue
Block a user