mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 07:17:50 +07: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:
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
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Walls
|
||||
Utopia Project
|
||||
rotate: false
|
||||
xy: 1430, 920
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Walls of Babylon
|
||||
Walls
|
||||
rotate: false
|
||||
xy: 614, 2
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Wat
|
||||
Walls of Babylon
|
||||
rotate: false
|
||||
xy: 716, 104
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Water Mill
|
||||
Wat
|
||||
rotate: false
|
||||
xy: 818, 206
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Windmill
|
||||
Water Mill
|
||||
rotate: false
|
||||
xy: 920, 308
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Workshop
|
||||
Windmill
|
||||
rotate: false
|
||||
xy: 1022, 410
|
||||
size: 100, 100
|
||||
orig: 100, 100
|
||||
offset: 0, 0
|
||||
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",
|
||||
"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 =
|
||||
[civName] 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] =
|
||||
[cityName] cannot continue work on [construction] =
|
||||
[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.stats.Stat
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
@ -155,8 +156,8 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
.filter { it.isStatRelated(Stat.Culture) }.minByOrNull { it.cost }
|
||||
if (cultureBuilding != null) {
|
||||
var modifier = 0.5f
|
||||
if(cityInfo.cityStats.currentCityStats.culture==0f) // It won't grow if we don't help it
|
||||
modifier=0.8f
|
||||
if (cityInfo.cityStats.currentCityStats.culture == 0f) // It won't grow if we don't help it
|
||||
modifier = 0.8f
|
||||
if (preferredVictoryType == VictoryType.Cultural) modifier = 1.6f
|
||||
addChoice(relativeCostEffectiveness, cultureBuilding.name, modifier)
|
||||
}
|
||||
@ -166,8 +167,6 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
val spaceshipPart = buildableNotWonders.firstOrNull { it.uniques.contains("Spaceship part") }
|
||||
if (spaceshipPart != null) {
|
||||
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
|
||||
addChoice(relativeCostEffectiveness, spaceshipPart.name, modifier)
|
||||
}
|
||||
@ -187,6 +186,11 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
if (preferredVictoryType == VictoryType.Cultural
|
||||
&& wonder.name in listOf("Sistine Chapel", "Eiffel Tower", "Cristo Redentor", "Neuschwanstein", "Sydney Opera House"))
|
||||
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 (allTechsAreResearched) return .5f
|
||||
if (preferredVictoryType == VictoryType.Scientific) return 1.5f
|
||||
|
@ -231,7 +231,10 @@ class CityConstructions {
|
||||
|
||||
fun turnsToConstruction(constructionName: String, useStoredProduction: Boolean = true): Int {
|
||||
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
|
||||
|
||||
val cityStatsForConstruction: Stats
|
||||
@ -304,6 +307,9 @@ class CityConstructions {
|
||||
validateInProgressConstructions()
|
||||
|
||||
if (getConstruction(currentConstructionFromQueue) !is PerpetualConstruction) {
|
||||
if (getWorkDone(currentConstructionFromQueue) == 0) {
|
||||
constructionBegun(getConstruction(currentConstructionFromQueue))
|
||||
}
|
||||
addProductionPoints(cityStats.production.roundToInt() + productionOverflow)
|
||||
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) {
|
||||
construction.postBuildEvent(this)
|
||||
if (construction.name in inProgressConstructions)
|
||||
@ -386,7 +411,7 @@ class CityConstructions {
|
||||
cityInfo.civInfo.addNotification("[${construction.name}] has been built in [" + cityInfo.name + "]",
|
||||
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) {
|
||||
// No need to notify ourself, since we already got the building notification anyway
|
||||
if (otherCiv == cityInfo.civInfo) continue
|
||||
|
@ -168,6 +168,7 @@ class CivilizationInfo {
|
||||
fun isAlive(): Boolean = !isDefeated()
|
||||
fun hasEverBeenFriendWith(otherCiv: CivilizationInfo): Boolean = getDiplomacyManager(otherCiv).everBeenFriends()
|
||||
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() }
|
||||
|
||||
fun victoryType(): VictoryType {
|
||||
|
@ -36,7 +36,7 @@ class VictoryManager {
|
||||
fun hasWonScientificVictory() = hasVictoryType(VictoryType.Scientific) && spaceshipPartsRemaining() == 0
|
||||
|
||||
fun hasWonCulturalVictory() = hasVictoryType(VictoryType.Cultural)
|
||||
&& civInfo.policies.adoptedPolicies.count { it.endsWith("Complete") } > 4
|
||||
&& civInfo.hasUnique("Triggers a Cultural Victory upon completion")
|
||||
|
||||
fun hasWonDominationVictory(): Boolean {
|
||||
return hasVictoryType(VictoryType.Domination)
|
||||
|
@ -352,6 +352,16 @@ class Building : NamedStats(), IConstruction {
|
||||
&& 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
|
||||
}
|
||||
"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!!)) {
|
||||
@ -383,7 +393,7 @@ class Building : NamedStats(), IConstruction {
|
||||
if (!civInfo.gameInfo.gameParameters.victoryTypes.contains(VictoryType.Scientific)
|
||||
&& "Enables construction of Spaceship parts" in uniques)
|
||||
return "Can't construct spaceship parts if scientific victory is not enabled!"
|
||||
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@ -410,7 +420,6 @@ class Building : NamedStats(), IConstruction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (providesFreeBuilding != null && !cityConstructions.containsBuildingOrEquivalent(providesFreeBuilding!!)) {
|
||||
var buildingToAdd = providesFreeBuilding!!
|
||||
|
||||
@ -469,4 +478,4 @@ class Building : NamedStats(), IConstruction {
|
||||
resourceRequirements[unique.params[1]] = unique.params[0].toInt()
|
||||
return resourceRequirements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ class BaseUnit : INamed, IConstruction {
|
||||
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")
|
||||
+ civInfo.getMatchingUniques("New [] units start with [] Experience")) {
|
||||
if (unit.matchesFilter(unique.params[0]))
|
||||
@ -206,7 +206,7 @@ class BaseUnit : INamed, IConstruction {
|
||||
}
|
||||
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")) {
|
||||
val filter = unique.params[0]
|
||||
val promotion = unique.params[1]
|
||||
|
@ -123,7 +123,7 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
|
||||
if (dominationVictoryEnabled) myVictoryStatusTable.add(conquestVictoryColumn())
|
||||
myVictoryStatusTable.row()
|
||||
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())
|
||||
|
||||
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
|
||||
* [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
|
||||
* [Illuminati](https://thenounproject.com/term/illuminati/1617812) by emilegraphics for the Utopia Project
|
||||
|
||||
## Social Policies
|
||||
|
||||
|
Reference in New Issue
Block a user