mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-28 22:37:02 -04:00
Updated the culture victory so it now requires the Utopia Project to be built (#4060)
* Added the Utopia Project for the culture victory; AI will now build it * Forgot to credit the icon * Fixed a few minor issues * Improved code quality; added translatable notifications * Fixed mistakes; improved quality * Changed a label * Revert a small change which is no longer necessary * Reverted the revert of a small change which is no longer necessary * Made requsted changes
This commit is contained in:
parent
07a43f3f1a
commit
1c21573a42
BIN
android/ImagesToPackSeparately/BuildingIcons/Utopia Project.png
Normal file
BIN
android/ImagesToPackSeparately/BuildingIcons/Utopia Project.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
@ -732,45 +732,52 @@ University
|
|||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
Walls
|
Utopia Project
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1430, 920
|
xy: 1430, 920
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
Walls of Babylon
|
Walls
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 614, 2
|
xy: 614, 2
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
Wat
|
Walls of Babylon
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 716, 104
|
xy: 716, 104
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
Water Mill
|
Wat
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 818, 206
|
xy: 818, 206
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
Windmill
|
Water Mill
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 920, 308
|
xy: 920, 308
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
Workshop
|
Windmill
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1022, 410
|
xy: 1022, 410
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
|
Workshop
|
||||||
|
rotate: false
|
||||||
|
xy: 1124, 512
|
||||||
|
size: 100, 100
|
||||||
|
orig: 100, 100
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 248 KiB |
@ -1046,4 +1046,14 @@
|
|||||||
"requiredTech": "Nanotechnology",
|
"requiredTech": "Nanotechnology",
|
||||||
"uniques": ["Spaceship part", "Triggers a global alert upon completion", "Cannot be purchased"]
|
"uniques": ["Spaceship part", "Triggers a global alert upon completion", "Cannot be purchased"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All Era's
|
||||||
|
|
||||||
|
{
|
||||||
|
"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"]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
@ -404,6 +404,9 @@ Cannot provide unit upkeep for [unitName] - unit has been disbanded! =
|
|||||||
[wonder] has been built in a faraway land =
|
[wonder] has been built in a faraway land =
|
||||||
[civName] has completed [construction]! =
|
[civName] has completed [construction]! =
|
||||||
An unknown civilization has completed [construction]! =
|
An unknown civilization has completed [construction]! =
|
||||||
|
The city of [cityname] has started constructing [construction]! =
|
||||||
|
[civilization] has started constructing [construction]! =
|
||||||
|
An unknown civilization has started constructing [construction]! =
|
||||||
Work has started on [construction] =
|
Work has started on [construction] =
|
||||||
[cityName] cannot continue work on [construction] =
|
[cityName] cannot continue work on [construction] =
|
||||||
[cityName] has expanded its borders! =
|
[cityName] has expanded its borders! =
|
||||||
|
@ -12,6 +12,7 @@ import com.unciv.models.ruleset.Building
|
|||||||
import com.unciv.models.ruleset.VictoryType
|
import com.unciv.models.ruleset.VictoryType
|
||||||
import com.unciv.models.stats.Stat
|
import com.unciv.models.stats.Stat
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
import kotlin.math.roundToInt
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
class ConstructionAutomation(val cityConstructions: CityConstructions){
|
class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||||
@ -166,8 +167,6 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
|||||||
val spaceshipPart = buildableNotWonders.firstOrNull { it.uniques.contains("Spaceship part") }
|
val spaceshipPart = buildableNotWonders.firstOrNull { it.uniques.contains("Spaceship part") }
|
||||||
if (spaceshipPart != null) {
|
if (spaceshipPart != null) {
|
||||||
var modifier = 1.5f
|
var modifier = 1.5f
|
||||||
if (cityInfo.cityStats.currentCityStats.culture == 0f) // It won't grow if we don't help it
|
|
||||||
modifier = 0.8f
|
|
||||||
if (preferredVictoryType == VictoryType.Scientific) modifier = 2f
|
if (preferredVictoryType == VictoryType.Scientific) modifier = 2f
|
||||||
addChoice(relativeCostEffectiveness, spaceshipPart.name, modifier)
|
addChoice(relativeCostEffectiveness, spaceshipPart.name, modifier)
|
||||||
}
|
}
|
||||||
@ -187,6 +186,11 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
|||||||
if (preferredVictoryType == VictoryType.Cultural
|
if (preferredVictoryType == VictoryType.Cultural
|
||||||
&& wonder.name in listOf("Sistine Chapel", "Eiffel Tower", "Cristo Redentor", "Neuschwanstein", "Sydney Opera House"))
|
&& wonder.name in listOf("Sistine Chapel", "Eiffel Tower", "Cristo Redentor", "Neuschwanstein", "Sydney Opera House"))
|
||||||
return 3f
|
return 3f
|
||||||
|
// Only start building if we are the city that would complete it the soonest
|
||||||
|
if (wonder.uniques.contains("Triggers a Cultural Victory upon completion") && cityInfo == civInfo.cities.minByOrNull {
|
||||||
|
it.cityConstructions.turnsToConstruction(wonder.name)
|
||||||
|
}!!)
|
||||||
|
return 10f
|
||||||
if (wonder.isStatRelated(Stat.Science)) {
|
if (wonder.isStatRelated(Stat.Science)) {
|
||||||
if (allTechsAreResearched) return .5f
|
if (allTechsAreResearched) return .5f
|
||||||
if (preferredVictoryType == VictoryType.Scientific) return 1.5f
|
if (preferredVictoryType == VictoryType.Scientific) return 1.5f
|
||||||
|
@ -231,7 +231,10 @@ class CityConstructions {
|
|||||||
|
|
||||||
fun turnsToConstruction(constructionName: String, useStoredProduction: Boolean = true): Int {
|
fun turnsToConstruction(constructionName: String, useStoredProduction: Boolean = true): Int {
|
||||||
val workLeft = getRemainingWork(constructionName, useStoredProduction)
|
val workLeft = getRemainingWork(constructionName, useStoredProduction)
|
||||||
if (workLeft <= productionOverflow) // we might have done more work than actually necessary (if <0) - possible if circumstances cause buildings to be cheaper later
|
if (workLeft < 0) // This most often happens when a production is more than finished in a multiplayer game while its not your turn
|
||||||
|
return 0 // So we finish it at the start of the next turn. This could technically also happen when we lower production costs during our turn,
|
||||||
|
// but distinguishing those two cases is difficult, and the second one is much rarer than the first
|
||||||
|
if (workLeft <= productionOverflow) // if we already have stored up enough production to finish it directly
|
||||||
return 1 // we'll finish this next turn
|
return 1 // we'll finish this next turn
|
||||||
|
|
||||||
val cityStatsForConstruction: Stats
|
val cityStatsForConstruction: Stats
|
||||||
@ -304,6 +307,9 @@ class CityConstructions {
|
|||||||
validateInProgressConstructions()
|
validateInProgressConstructions()
|
||||||
|
|
||||||
if (getConstruction(currentConstructionFromQueue) !is PerpetualConstruction) {
|
if (getConstruction(currentConstructionFromQueue) !is PerpetualConstruction) {
|
||||||
|
if (getWorkDone(currentConstructionFromQueue) == 0) {
|
||||||
|
constructionBegun(getConstruction(currentConstructionFromQueue))
|
||||||
|
}
|
||||||
addProductionPoints(cityStats.production.roundToInt() + productionOverflow)
|
addProductionPoints(cityStats.production.roundToInt() + productionOverflow)
|
||||||
productionOverflow = 0
|
productionOverflow = 0
|
||||||
}
|
}
|
||||||
@ -362,6 +368,25 @@ class CityConstructions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun constructionBegun(construction: IConstruction) {
|
||||||
|
if (construction !is Building) return;
|
||||||
|
if (construction.uniqueObjects.none { it.placeholderText == "Triggers a global alert upon build start" }) return
|
||||||
|
val buildingIcon = "BuildingIcons/${construction.name}"
|
||||||
|
for (otherCiv in cityInfo.civInfo.gameInfo.civilizations) {
|
||||||
|
if (otherCiv == cityInfo.civInfo) continue
|
||||||
|
when {
|
||||||
|
(otherCiv.exploredTiles.contains(cityInfo.location) && otherCiv != cityInfo.civInfo) ->
|
||||||
|
otherCiv.addNotification("The city of [${cityInfo.name}] has started constructing [${construction.name}]!",
|
||||||
|
cityInfo.location, NotificationIcon.Construction, buildingIcon)
|
||||||
|
(otherCiv.knows(cityInfo.civInfo)) ->
|
||||||
|
otherCiv.addNotification("[${cityInfo.civInfo.civName}] has started constructing [${construction.name}]!",
|
||||||
|
NotificationIcon.Construction, buildingIcon)
|
||||||
|
else -> otherCiv.addNotification("An unknown civilization has started constructing [${construction.name}]!",
|
||||||
|
NotificationIcon.Construction, buildingIcon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun constructionComplete(construction: IConstruction) {
|
private fun constructionComplete(construction: IConstruction) {
|
||||||
construction.postBuildEvent(this)
|
construction.postBuildEvent(this)
|
||||||
if (construction.name in inProgressConstructions)
|
if (construction.name in inProgressConstructions)
|
||||||
@ -386,7 +411,7 @@ class CityConstructions {
|
|||||||
cityInfo.civInfo.addNotification("[${construction.name}] has been built in [" + cityInfo.name + "]",
|
cityInfo.civInfo.addNotification("[${construction.name}] has been built in [" + cityInfo.name + "]",
|
||||||
cityInfo.location, NotificationIcon.Construction, icon)
|
cityInfo.location, NotificationIcon.Construction, icon)
|
||||||
}
|
}
|
||||||
if (construction is Building && "Triggers a global alert upon completion" in construction.uniques) {
|
if (construction is Building && construction.uniqueObjects.any { it.placeholderText == "Triggers a global alert upon completion" } ) {
|
||||||
for (otherCiv in cityInfo.civInfo.gameInfo.civilizations) {
|
for (otherCiv in cityInfo.civInfo.gameInfo.civilizations) {
|
||||||
// No need to notify ourself, since we already got the building notification anyway
|
// No need to notify ourself, since we already got the building notification anyway
|
||||||
if (otherCiv == cityInfo.civInfo) continue
|
if (otherCiv == cityInfo.civInfo) continue
|
||||||
|
@ -168,6 +168,7 @@ class CivilizationInfo {
|
|||||||
fun isAlive(): Boolean = !isDefeated()
|
fun isAlive(): Boolean = !isDefeated()
|
||||||
fun hasEverBeenFriendWith(otherCiv: CivilizationInfo): Boolean = getDiplomacyManager(otherCiv).everBeenFriends()
|
fun hasEverBeenFriendWith(otherCiv: CivilizationInfo): Boolean = getDiplomacyManager(otherCiv).everBeenFriends()
|
||||||
fun hasMetCivTerritory(otherCiv: CivilizationInfo): Boolean = otherCiv.getCivTerritory().any { it in exploredTiles }
|
fun hasMetCivTerritory(otherCiv: CivilizationInfo): Boolean = otherCiv.getCivTerritory().any { it in exploredTiles }
|
||||||
|
fun getCompletedPolicyBranchesCount(): Int = policies.adoptedPolicies.count { it.endsWith("Complete") }
|
||||||
private fun getCivTerritory() = cities.asSequence().flatMap { it.tiles.asSequence() }
|
private fun getCivTerritory() = cities.asSequence().flatMap { it.tiles.asSequence() }
|
||||||
|
|
||||||
fun victoryType(): VictoryType {
|
fun victoryType(): VictoryType {
|
||||||
|
@ -36,7 +36,7 @@ class VictoryManager {
|
|||||||
fun hasWonScientificVictory() = hasVictoryType(VictoryType.Scientific) && spaceshipPartsRemaining() == 0
|
fun hasWonScientificVictory() = hasVictoryType(VictoryType.Scientific) && spaceshipPartsRemaining() == 0
|
||||||
|
|
||||||
fun hasWonCulturalVictory() = hasVictoryType(VictoryType.Cultural)
|
fun hasWonCulturalVictory() = hasVictoryType(VictoryType.Cultural)
|
||||||
&& civInfo.policies.adoptedPolicies.count { it.endsWith("Complete") } > 4
|
&& civInfo.hasUnique("Triggers a Cultural Victory upon completion")
|
||||||
|
|
||||||
fun hasWonDominationVictory(): Boolean {
|
fun hasWonDominationVictory(): Boolean {
|
||||||
return hasVictoryType(VictoryType.Domination)
|
return hasVictoryType(VictoryType.Domination)
|
||||||
|
@ -352,6 +352,16 @@ class Building : NamedStats(), IConstruction {
|
|||||||
&& civInfo.cities.any { !it.isPuppet && !it.cityConstructions.containsBuildingOrEquivalent(unique.params[0]) })
|
&& civInfo.cities.any { !it.isPuppet && !it.cityConstructions.containsBuildingOrEquivalent(unique.params[0]) })
|
||||||
return "Requires a [${civInfo.getEquivalentBuilding(unique.params[0])}] in all cities" // replace with civ-specific building for user
|
return "Requires a [${civInfo.getEquivalentBuilding(unique.params[0])}] in all cities" // replace with civ-specific building for user
|
||||||
}
|
}
|
||||||
|
"Hidden until [] social policy branches have been completed" -> {
|
||||||
|
if (construction.cityInfo.civInfo.getCompletedPolicyBranchesCount() < unique.params[0].toInt()) {
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requiredBuilding != null && !construction.containsBuildingOrEquivalent(requiredBuilding!!)) {
|
if (requiredBuilding != null && !construction.containsBuildingOrEquivalent(requiredBuilding!!)) {
|
||||||
@ -410,7 +420,6 @@ class Building : NamedStats(), IConstruction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (providesFreeBuilding != null && !cityConstructions.containsBuildingOrEquivalent(providesFreeBuilding!!)) {
|
if (providesFreeBuilding != null && !cityConstructions.containsBuildingOrEquivalent(providesFreeBuilding!!)) {
|
||||||
var buildingToAdd = providesFreeBuilding!!
|
var buildingToAdd = providesFreeBuilding!!
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ class BaseUnit : INamed, IConstruction {
|
|||||||
var XP = cityConstructions.getBuiltBuildings().sumBy { it.xpForNewUnits }
|
var XP = cityConstructions.getBuiltBuildings().sumBy { it.xpForNewUnits }
|
||||||
|
|
||||||
|
|
||||||
for (unique in cityConstructions.cityInfo.cityConstructions.builtBuildingUniqueMap
|
for (unique in cityConstructions.builtBuildingUniqueMap
|
||||||
.getUniques("New [] units start with [] Experience in this city")
|
.getUniques("New [] units start with [] Experience in this city")
|
||||||
+ civInfo.getMatchingUniques("New [] units start with [] Experience")) {
|
+ civInfo.getMatchingUniques("New [] units start with [] Experience")) {
|
||||||
if (unit.matchesFilter(unique.params[0]))
|
if (unit.matchesFilter(unique.params[0]))
|
||||||
@ -206,7 +206,7 @@ class BaseUnit : INamed, IConstruction {
|
|||||||
}
|
}
|
||||||
unit.promotions.XP = XP
|
unit.promotions.XP = XP
|
||||||
|
|
||||||
for (unique in cityConstructions.cityInfo.cityConstructions.builtBuildingUniqueMap
|
for (unique in cityConstructions.builtBuildingUniqueMap
|
||||||
.getUniques("All newly-trained [] units in this city receive the [] promotion")) {
|
.getUniques("All newly-trained [] units in this city receive the [] promotion")) {
|
||||||
val filter = unique.params[0]
|
val filter = unique.params[0]
|
||||||
val promotion = unique.params[1]
|
val promotion = unique.params[1]
|
||||||
|
@ -123,7 +123,7 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
|
|||||||
if (dominationVictoryEnabled) myVictoryStatusTable.add(conquestVictoryColumn())
|
if (dominationVictoryEnabled) myVictoryStatusTable.add(conquestVictoryColumn())
|
||||||
myVictoryStatusTable.row()
|
myVictoryStatusTable.row()
|
||||||
if (scientificVictoryEnabled) myVictoryStatusTable.add("Complete all the spaceship parts\n to win!".toLabel())
|
if (scientificVictoryEnabled) myVictoryStatusTable.add("Complete all the spaceship parts\n to win!".toLabel())
|
||||||
if (culturalVictoryEnabled) myVictoryStatusTable.add("Complete 5 policy branches\n to win!".toLabel())
|
if (culturalVictoryEnabled) myVictoryStatusTable.add("Complete 5 policy branches and build\n the Utopia Project to win!".toLabel())
|
||||||
if (dominationVictoryEnabled) myVictoryStatusTable.add("Destroy all enemies\n to win!".toLabel())
|
if (dominationVictoryEnabled) myVictoryStatusTable.add("Destroy all enemies\n to win!".toLabel())
|
||||||
|
|
||||||
contentsTable.clear()
|
contentsTable.clear()
|
||||||
|
@ -284,6 +284,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
|
|||||||
* [Rocket](https://thenounproject.com/term/rocket/937173/) By BomSymbols for SS Cockpit
|
* [Rocket](https://thenounproject.com/term/rocket/937173/) By BomSymbols for SS Cockpit
|
||||||
* [Engine](https://thenounproject.com/term/engine/1877958/) By Andre for SS Engine
|
* [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
|
* [Chamber](https://thenounproject.com/term/chamber/1242689/) By IYIKON for SS Stasis Chamber
|
||||||
|
* [Illuminati](https://thenounproject.com/term/illuminati/1617812) by emilegraphics for the Utopia Project
|
||||||
|
|
||||||
## Social Policies
|
## Social Policies
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user