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 |
@ -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"],
|
||||
"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"
|
||||
"requiredTech": "Globalization", // todo doesn't exist yet!
|
||||
},
|
||||
*/
|
||||
{
|
||||
"name": "SS Engine",
|
||||
"requiredResource": "Aluminum",
|
||||
@ -1123,6 +1121,6 @@
|
||||
"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"]
|
||||
"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
|
||||
|
@ -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
|
||||
|
||||
@ -630,10 +627,50 @@ 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
|
||||
@ -43,11 +74,16 @@ class VictoryManager {
|
||||
&& 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 [] 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 "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,
|
||||
@ -377,6 +375,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) {
|
||||
game.setScreen(CivilopediaScreen(game.worldScreen.gameInfo.ruleSet, currentCategory, currentEntry))
|
||||
|
@ -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!")
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,11 +77,14 @@ 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
|
||||
|
||||
@ -462,28 +463,31 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
|
||||
* [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
|
||||
* [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