mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-28 06:16:37 -04:00
Made unhappiness effects moddable by adding a global uniques json; added revolts when < -20 happiness (#5932)
* Added a json file for unhappiness effects * Change existing code to handle these effects * Made a weird and unexpendable way to add unhappiness effects to the civilopedia * Add the default unhappinesseffects to mods without the json * Added revolts when at very low happiness * Renamed a few often-used functions * Added a file for uniques that are always active * Fixed tests * Nullifies [Food] -> Nullifies Growth
This commit is contained in:
parent
40cd2ba24b
commit
f6cb2bd0d7
25
android/assets/jsons/Civ V - Gods & Kings/GlobalUniques.json
Normal file
25
android/assets/jsons/Civ V - Gods & Kings/GlobalUniques.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "Global uniques",
|
||||||
|
"uniques": [
|
||||||
|
"[-75]% growth [in all cities] <when between [-10] and [0] Happiness>",
|
||||||
|
"Nullifies Growth [in all cities] <when below [-10] Happiness>",
|
||||||
|
"[-50]% [Production] [in all cities] <when below [-10] Happiness>",
|
||||||
|
"[-33]% Strength <for [All] units> <when below [-10] Happiness>",
|
||||||
|
"Cannot build [Settler] units <when below [-10] Happiness>",
|
||||||
|
"Rebel units may spawn <when below [-20] Happiness>"
|
||||||
|
|
||||||
|
// TODO: Implement the uniques below
|
||||||
|
// "[+20]% [Culture] [in all cities] <during a golden age>",
|
||||||
|
// "[+20]% [Production] [in all cities] <during a golden age>",
|
||||||
|
|
||||||
|
// "[+10]% growth [in all cities] <during We Love The King Day>",
|
||||||
|
|
||||||
|
// "Nullifies All Yield <while is in resistance>",
|
||||||
|
|
||||||
|
// "[-25]% [Science] [in pupetted cities]" -- Imo cityFilters should ideally become conditionals anyway
|
||||||
|
// "[-25]% [Culture] [in pupetted cities]"
|
||||||
|
|
||||||
|
// "[+20]% [Production] [in cities connected via railroad]"
|
||||||
|
// something something unit supply
|
||||||
|
]
|
||||||
|
}
|
25
android/assets/jsons/Civ V - Vanilla/GlobalUniques.json
Normal file
25
android/assets/jsons/Civ V - Vanilla/GlobalUniques.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "Global uniques",
|
||||||
|
"uniques": [
|
||||||
|
"[-75]% growth [in all cities] <when between [-10] and [0] Happiness>",
|
||||||
|
"Nullifies Growth [in all cities] <when below [-10] Happiness>",
|
||||||
|
"[-50]% [Production] [in all cities] <when below [-10] Happiness>",
|
||||||
|
"[-33]% Strength <for [All] units> <when below [-10] Happiness>",
|
||||||
|
"Cannot build [Settler] units <when below [-10] Happiness>",
|
||||||
|
"Rebel units may spawn <when below [-20] Happiness>"
|
||||||
|
|
||||||
|
// TODO: Implement the uniques below
|
||||||
|
// "[+20]% [Culture] [in all cities] <during a golden age>",
|
||||||
|
// "[+20]% [Production] [in all cities] <during a golden age>",
|
||||||
|
|
||||||
|
// "[+10]% growth [in all cities] <during We Love The King Day>",
|
||||||
|
|
||||||
|
// "Nullifies All Yield <while is in resistance>",
|
||||||
|
|
||||||
|
// "[-25]% [Science] [in pupetted cities]" -- Imo cityFilters should ideally become conditionals anyway
|
||||||
|
// "[-25]% [Culture] [in pupetted cities]"
|
||||||
|
|
||||||
|
// "[+20]% [Production] [in cities connected via railroad]"
|
||||||
|
// something something unit supply
|
||||||
|
]
|
||||||
|
}
|
@ -33,7 +33,7 @@
|
|||||||
"This means that it is very difficult to expand quickly in Unciv.\nIt isn’t impossible, but as a new player you probably shouldn't do it.\nSo what should you do? Chill out, scout, and improve the land that you do have by building Workers.\nOnly build new cities once you have found a spot that you believe is appropriate."
|
"This means that it is very difficult to expand quickly in Unciv.\nIt isn’t impossible, but as a new player you probably shouldn't do it.\nSo what should you do? Chill out, scout, and improve the land that you do have by building Workers.\nOnly build new cities once you have found a spot that you believe is appropriate."
|
||||||
],
|
],
|
||||||
Unhappiness: [
|
Unhappiness: [
|
||||||
"It seems that your citizens are unhappy!\nWhile unhappy, cities will grow at 1/4 the speed, and your units will suffer a 2% penalty for each unhappiness",
|
"It seems that your citizens are unhappy!\nWhile unhappy, your civilization will suffer many detrimental effects, increasing in severity as unhappiness gets higher.",
|
||||||
"Unhappiness has two main causes: Population and cities.\n Each city causes 3 unhappiness, and each population, 1",
|
"Unhappiness has two main causes: Population and cities.\n Each city causes 3 unhappiness, and each population, 1",
|
||||||
"There are 2 main ways to combat unhappiness:\n by building happiness buildings for your population\n or by having improved luxury resources within your borders."
|
"There are 2 main ways to combat unhappiness:\n by building happiness buildings for your population\n or by having improved luxury resources within your borders."
|
||||||
],
|
],
|
||||||
|
@ -754,6 +754,7 @@ Force =
|
|||||||
GOLDEN AGE =
|
GOLDEN AGE =
|
||||||
Golden Age =
|
Golden Age =
|
||||||
We Love The King Day =
|
We Love The King Day =
|
||||||
|
Global Effect =
|
||||||
[year] BC =
|
[year] BC =
|
||||||
[year] AD =
|
[year] AD =
|
||||||
Civilopedia =
|
Civilopedia =
|
||||||
@ -811,7 +812,6 @@ Specialist Allocation =
|
|||||||
Specialists =
|
Specialists =
|
||||||
[specialist] slots =
|
[specialist] slots =
|
||||||
Food eaten =
|
Food eaten =
|
||||||
Growth bonus =
|
|
||||||
Unassigned population =
|
Unassigned population =
|
||||||
[turnsToExpansion] turns to expansion =
|
[turnsToExpansion] turns to expansion =
|
||||||
Stopped expansion =
|
Stopped expansion =
|
||||||
|
@ -66,13 +66,13 @@ class MainMenuScreen: BaseScreen() {
|
|||||||
|
|
||||||
// If we were in a mod, some of the resource images for the background map we're creating
|
// If we were in a mod, some of the resource images for the background map we're creating
|
||||||
// will not exist unless we reset the ruleset and images
|
// will not exist unless we reset the ruleset and images
|
||||||
ImageGetter.ruleset = RulesetCache.getBaseRuleset()
|
ImageGetter.ruleset = RulesetCache.getVanillaRuleset()
|
||||||
|
|
||||||
crashHandlingThread(name = "ShowMapBackground") {
|
crashHandlingThread(name = "ShowMapBackground") {
|
||||||
val newMap = MapGenerator(RulesetCache.getBaseRuleset())
|
val newMap = MapGenerator(RulesetCache.getVanillaRuleset())
|
||||||
.generateMap(MapParameters().apply { mapSize = MapSizeNew(MapSize.Small); type = MapType.default })
|
.generateMap(MapParameters().apply { mapSize = MapSizeNew(MapSize.Small); type = MapType.default })
|
||||||
postCrashHandlingRunnable { // for GL context
|
postCrashHandlingRunnable { // for GL context
|
||||||
ImageGetter.setNewRuleset(RulesetCache.getBaseRuleset())
|
ImageGetter.setNewRuleset(RulesetCache.getVanillaRuleset())
|
||||||
val mapHolder = EditorMapHolder(MapEditorScreen(), newMap)
|
val mapHolder = EditorMapHolder(MapEditorScreen(), newMap)
|
||||||
backgroundTable.addAction(Actions.sequence(
|
backgroundTable.addAction(Actions.sequence(
|
||||||
Actions.fadeOut(0f),
|
Actions.fadeOut(0f),
|
||||||
|
@ -117,7 +117,7 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
|||||||
postCrashHandlingRunnable {
|
postCrashHandlingRunnable {
|
||||||
musicController.chooseTrack(suffix = MusicMood.Menu)
|
musicController.chooseTrack(suffix = MusicMood.Menu)
|
||||||
|
|
||||||
ImageGetter.ruleset = RulesetCache.getBaseRuleset() // so that we can enter the map editor without having to load a game first
|
ImageGetter.ruleset = RulesetCache.getVanillaRuleset() // so that we can enter the map editor without having to load a game first
|
||||||
|
|
||||||
if (settings.isFreshlyCreated) {
|
if (settings.isFreshlyCreated) {
|
||||||
setScreen(LanguagePickerScreen())
|
setScreen(LanguagePickerScreen())
|
||||||
|
@ -40,7 +40,7 @@ object GameStarter {
|
|||||||
gameSetupInfo.gameParameters.baseRuleset = baseRulesetInMods
|
gameSetupInfo.gameParameters.baseRuleset = baseRulesetInMods
|
||||||
|
|
||||||
if (!RulesetCache.containsKey(gameSetupInfo.gameParameters.baseRuleset))
|
if (!RulesetCache.containsKey(gameSetupInfo.gameParameters.baseRuleset))
|
||||||
gameSetupInfo.gameParameters.baseRuleset = RulesetCache.getBaseRuleset().name
|
gameSetupInfo.gameParameters.baseRuleset = RulesetCache.getVanillaRuleset().name
|
||||||
|
|
||||||
gameInfo.gameParameters = gameSetupInfo.gameParameters
|
gameInfo.gameParameters = gameSetupInfo.gameParameters
|
||||||
val ruleset = RulesetCache.getComplexRuleset(gameInfo.gameParameters.mods, gameInfo.gameParameters.baseRuleset)
|
val ruleset = RulesetCache.getComplexRuleset(gameInfo.gameParameters.mods, gameInfo.gameParameters.baseRuleset)
|
||||||
|
@ -2,6 +2,7 @@ package com.unciv.logic.battle
|
|||||||
|
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.models.Counter
|
import com.unciv.models.Counter
|
||||||
|
import com.unciv.models.ruleset.GlobalUniques
|
||||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||||
import com.unciv.models.ruleset.unique.Unique
|
import com.unciv.models.ruleset.unique.Unique
|
||||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||||
@ -20,6 +21,7 @@ object BattleDamage {
|
|||||||
val source = when (unique.sourceObjectType) {
|
val source = when (unique.sourceObjectType) {
|
||||||
UniqueTarget.Unit -> "Unit ability"
|
UniqueTarget.Unit -> "Unit ability"
|
||||||
UniqueTarget.Nation -> "National ability"
|
UniqueTarget.Nation -> "National ability"
|
||||||
|
UniqueTarget.Global -> GlobalUniques.getUniqueSourceDescription(unique)
|
||||||
else -> "[${unique.sourceObjectName}] ([${unique.sourceObjectType?.name}])"
|
else -> "[${unique.sourceObjectName}] ([${unique.sourceObjectType?.name}])"
|
||||||
}
|
}
|
||||||
if (unique.conditionals.isEmpty()) return source
|
if (unique.conditionals.isEmpty()) return source
|
||||||
@ -58,19 +60,6 @@ object BattleDamage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php
|
//https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php
|
||||||
val civHappiness = if (civInfo.isCityState() && civInfo.getAllyCiv() != null)
|
|
||||||
// If we are a city state with an ally we are vulnerable to their unhappiness.
|
|
||||||
min(
|
|
||||||
civInfo.gameInfo.getCivilization(civInfo.getAllyCiv()!!).getHappiness(),
|
|
||||||
civInfo.getHappiness()
|
|
||||||
)
|
|
||||||
else civInfo.getHappiness()
|
|
||||||
if (civHappiness < 0)
|
|
||||||
modifiers["Unhappiness"] = max(
|
|
||||||
2 * civHappiness,
|
|
||||||
-90
|
|
||||||
) // otherwise it could exceed -100% and start healing enemy units...
|
|
||||||
|
|
||||||
val adjacentUnits = combatant.getTile().neighbors.flatMap { it.getUnits() }
|
val adjacentUnits = combatant.getTile().neighbors.flatMap { it.getUnits() }
|
||||||
|
|
||||||
// Deprecated since 3.18.17
|
// Deprecated since 3.18.17
|
||||||
|
@ -282,7 +282,7 @@ class CityInfo {
|
|||||||
fun hasFlag(flag: CityFlags) = flagsCountdown.containsKey(flag.name)
|
fun hasFlag(flag: CityFlags) = flagsCountdown.containsKey(flag.name)
|
||||||
fun getFlag(flag: CityFlags) = flagsCountdown[flag.name]!!
|
fun getFlag(flag: CityFlags) = flagsCountdown[flag.name]!!
|
||||||
|
|
||||||
fun isWeLoveTheKingDay() = hasFlag(CityFlags.WeLoveTheKing)
|
fun isWeLoveTheKingDayActive() = hasFlag(CityFlags.WeLoveTheKing)
|
||||||
fun isInResistance() = hasFlag(CityFlags.Resistance)
|
fun isInResistance() = hasFlag(CityFlags.Resistance)
|
||||||
|
|
||||||
/** @return the number of tiles 4 out from this city that could hold a city, ie how lonely this city is */
|
/** @return the number of tiles 4 out from this city that could hold a city, ie how lonely this city is */
|
||||||
|
@ -6,9 +6,9 @@ import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
|||||||
import com.unciv.logic.map.RoadStatus
|
import com.unciv.logic.map.RoadStatus
|
||||||
import com.unciv.models.Counter
|
import com.unciv.models.Counter
|
||||||
import com.unciv.models.ruleset.Building
|
import com.unciv.models.ruleset.Building
|
||||||
|
import com.unciv.models.ruleset.GlobalUniques
|
||||||
import com.unciv.models.ruleset.ModOptionsConstants
|
import com.unciv.models.ruleset.ModOptionsConstants
|
||||||
import com.unciv.models.ruleset.unique.Unique
|
import com.unciv.models.ruleset.unique.*
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
|
||||||
import com.unciv.models.ruleset.unit.BaseUnit
|
import com.unciv.models.ruleset.unit.BaseUnit
|
||||||
import com.unciv.models.stats.Stat
|
import com.unciv.models.stats.Stat
|
||||||
import com.unciv.models.stats.StatMap
|
import com.unciv.models.stats.StatMap
|
||||||
@ -167,15 +167,21 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getGrowthBonusFromPoliciesAndWonders(): Float {
|
private fun getGrowthBonus(totalFood: Float): StatMap {
|
||||||
var bonus = 0f
|
val growthSources = StatMap()
|
||||||
|
val stateForConditionals = StateForConditionals(cityInfo.civInfo, cityInfo)
|
||||||
// "[amount]% growth [cityFilter]"
|
// "[amount]% growth [cityFilter]"
|
||||||
for (unique in cityInfo.getMatchingUniques(UniqueType.GrowthPercentBonus)) {
|
for (unique in cityInfo.getMatchingUniques(UniqueType.GrowthPercentBonus, stateForConditionals = stateForConditionals)) {
|
||||||
if (!unique.conditionalsApply(cityInfo.civInfo, cityInfo)) continue
|
if (!cityInfo.matchesFilter(unique.params[1])) continue
|
||||||
if (cityInfo.matchesFilter(unique.params[1]))
|
|
||||||
bonus += unique.params[0].toFloat()
|
val uniqueSource =
|
||||||
|
if (unique.sourceObjectType == UniqueTarget.Global && unique.conditionals.any())
|
||||||
|
GlobalUniques.getUniqueSourceDescription(unique)
|
||||||
|
else unique.sourceObjectType?.name ?: ""
|
||||||
|
|
||||||
|
growthSources.add(uniqueSource, Stats(food = unique.params[0].toFloat()/100f * totalFood))
|
||||||
}
|
}
|
||||||
return bonus / 100
|
return growthSources
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasExtraAnnexUnhappiness(): Boolean {
|
fun hasExtraAnnexUnhappiness(): Boolean {
|
||||||
@ -206,8 +212,13 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
|
|
||||||
private fun getStatsFromUniquesBySource(): StatTreeNode {
|
private fun getStatsFromUniquesBySource(): StatTreeNode {
|
||||||
val sourceToStats = StatTreeNode()
|
val sourceToStats = StatTreeNode()
|
||||||
fun addUniqueStats(unique:Unique) =
|
fun addUniqueStats(unique:Unique) {
|
||||||
sourceToStats.addStats(unique.stats, unique.sourceObjectType?.name ?: "", unique.sourceObjectName ?: "")
|
val uniqueSource =
|
||||||
|
if (unique.sourceObjectType == UniqueTarget.Global && unique.conditionals.any())
|
||||||
|
GlobalUniques.getUniqueSourceDescription(unique)
|
||||||
|
else unique.sourceObjectType?.name ?: ""
|
||||||
|
sourceToStats.addStats(unique.stats, uniqueSource, unique.sourceObjectName ?: "")
|
||||||
|
}
|
||||||
|
|
||||||
for (unique in cityInfo.getMatchingUniques(UniqueType.Stats))
|
for (unique in cityInfo.getMatchingUniques(UniqueType.Stats))
|
||||||
addUniqueStats(unique)
|
addUniqueStats(unique)
|
||||||
@ -278,9 +289,14 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
|
|
||||||
private fun getStatsPercentBonusesFromUniquesBySource(currentConstruction: IConstruction):StatMap {
|
private fun getStatsPercentBonusesFromUniquesBySource(currentConstruction: IConstruction):StatMap {
|
||||||
val sourceToStats = StatMap()
|
val sourceToStats = StatMap()
|
||||||
fun addUniqueStats(unique: Unique, stat:Stat, amount:Float) =
|
fun addUniqueStats(unique: Unique, stat:Stat, amount:Float) {
|
||||||
sourceToStats.add(unique.sourceObjectType?.name ?: "",
|
val uniqueSource =
|
||||||
Stats().add(stat, amount))
|
if (unique.sourceObjectType == UniqueTarget.Global && unique.conditionals.any())
|
||||||
|
GlobalUniques.getUniqueSourceDescription(unique)
|
||||||
|
else unique.sourceObjectType?.name ?: ""
|
||||||
|
|
||||||
|
sourceToStats.add(uniqueSource, Stats().add(stat, amount))
|
||||||
|
}
|
||||||
|
|
||||||
for (unique in cityInfo.getMatchingUniques(UniqueType.StatPercentBonus)) {
|
for (unique in cityInfo.getMatchingUniques(UniqueType.StatPercentBonus)) {
|
||||||
addUniqueStats(unique, Stat.valueOf(unique.params[1]), unique.params[0].toFloat())
|
addUniqueStats(unique, Stat.valueOf(unique.params[1]), unique.params[0].toFloat())
|
||||||
@ -294,14 +310,14 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
|
|
||||||
|
|
||||||
val uniquesToCheck =
|
val uniquesToCheck =
|
||||||
if (currentConstruction is Building && currentConstruction.isAnyWonder()) {
|
when {
|
||||||
cityInfo.getMatchingUniques(UniqueType.PercentProductionWonders)
|
currentConstruction is BaseUnit ->
|
||||||
} else if (currentConstruction is Building && !currentConstruction.isAnyWonder()) {
|
|
||||||
cityInfo.getMatchingUniques(UniqueType.PercentProductionBuildings)
|
|
||||||
} else if (currentConstruction is BaseUnit) {
|
|
||||||
cityInfo.getMatchingUniques(UniqueType.PercentProductionUnits)
|
cityInfo.getMatchingUniques(UniqueType.PercentProductionUnits)
|
||||||
} else { // Science/Gold production
|
currentConstruction is Building && currentConstruction.isAnyWonder() ->
|
||||||
sequenceOf()
|
cityInfo.getMatchingUniques(UniqueType.PercentProductionWonders)
|
||||||
|
currentConstruction is Building && !currentConstruction.isAnyWonder() ->
|
||||||
|
cityInfo.getMatchingUniques(UniqueType.PercentProductionBuildings)
|
||||||
|
else -> sequenceOf() // Science/Gold production
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unique in uniquesToCheck) {
|
for (unique in uniquesToCheck) {
|
||||||
@ -321,9 +337,11 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
|
|
||||||
if (currentConstruction is Building
|
if (currentConstruction is Building
|
||||||
&& cityInfo.civInfo.cities.isNotEmpty()
|
&& cityInfo.civInfo.cities.isNotEmpty()
|
||||||
&& cityInfo.civInfo.getCapital().cityConstructions.builtBuildings.contains(currentConstruction.name))
|
&& cityInfo.civInfo.getCapital().cityConstructions.builtBuildings.contains(currentConstruction.name)
|
||||||
for(unique in cityInfo.getMatchingUniques("+25% Production towards any buildings that already exist in the Capital"))
|
) {
|
||||||
|
for (unique in cityInfo.getMatchingUniques("+25% Production towards any buildings that already exist in the Capital"))
|
||||||
addUniqueStats(unique, Stat.Production, 25f)
|
addUniqueStats(unique, Stat.Production, 25f)
|
||||||
|
}
|
||||||
|
|
||||||
renameStatmapKeys(sourceToStats)
|
renameStatmapKeys(sourceToStats)
|
||||||
|
|
||||||
@ -462,8 +480,8 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
private fun updateBaseStatList(statsFromBuildings: StatTreeNode) {
|
private fun updateBaseStatList(statsFromBuildings: StatTreeNode) {
|
||||||
val newBaseStatTree = StatTreeNode()
|
val newBaseStatTree = StatTreeNode()
|
||||||
|
|
||||||
val newBaseStatList =
|
// We don't edit the existing baseStatList directly, in order to avoid concurrency exceptions
|
||||||
StatMap() // we don't edit the existing baseStatList directly, in order to avoid concurrency exceptions
|
val newBaseStatList = StatMap()
|
||||||
|
|
||||||
newBaseStatTree.addStats(Stats(
|
newBaseStatTree.addStats(Stats(
|
||||||
science = cityInfo.population.population.toFloat(),
|
science = cityInfo.population.population.toFloat(),
|
||||||
@ -576,6 +594,20 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
entry.science *= statPercentBonusesSum.science.toPercent()
|
entry.science *= statPercentBonusesSum.science.toPercent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ((unique, statToBeRemoved) in cityInfo.getMatchingUniques(UniqueType.NullifiesStat)
|
||||||
|
.map { it to Stat.valueOf(it.params[0]) }
|
||||||
|
.distinct()
|
||||||
|
) {
|
||||||
|
val removedAmount = newFinalStatList.values.sumOf { it[statToBeRemoved].toDouble() }
|
||||||
|
|
||||||
|
val uniqueSource =
|
||||||
|
if (unique.sourceObjectType == UniqueTarget.Global && unique.conditionals.any())
|
||||||
|
GlobalUniques.getUniqueSourceDescription(unique)
|
||||||
|
else unique.sourceObjectType?.name ?: ""
|
||||||
|
|
||||||
|
newFinalStatList.add(uniqueSource, Stats().apply { this[statToBeRemoved] = -removedAmount.toFloat() })
|
||||||
|
}
|
||||||
|
|
||||||
/* Okay, food calculation is complicated.
|
/* Okay, food calculation is complicated.
|
||||||
First we see how much food we generate. Then we apply production bonuses to it.
|
First we see how much food we generate. Then we apply production bonuses to it.
|
||||||
Up till here, business as usual.
|
Up till here, business as usual.
|
||||||
@ -592,15 +624,12 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
if (totalFood > 0) {
|
if (totalFood > 0) {
|
||||||
// Since growth bonuses are special, (applied afterwards) they will be displayed separately in the user interface as well.
|
// Since growth bonuses are special, (applied afterwards) they will be displayed separately in the user interface as well.
|
||||||
// All bonuses except We Love The King do apply even when unhappy
|
// All bonuses except We Love The King do apply even when unhappy
|
||||||
val foodFromGrowthBonuses = Stats(food = getGrowthBonusFromPoliciesAndWonders() * totalFood)
|
val growthBonuses = getGrowthBonus(totalFood)
|
||||||
newFinalStatList.add("Growth bonus", foodFromGrowthBonuses)
|
renameStatmapKeys(growthBonuses)
|
||||||
val happiness = cityInfo.civInfo.getHappiness()
|
for (growthBonus in growthBonuses) {
|
||||||
if (happiness < 0) {
|
newFinalStatList.add("${growthBonus.key} (Growth)", growthBonus.value)
|
||||||
// Unhappiness -75% to -100%
|
}
|
||||||
val foodReducedByUnhappiness = if (happiness <= -10) Stats(food = totalFood * -1)
|
if (cityInfo.isWeLoveTheKingDayActive() && cityInfo.civInfo.getHappiness() >= 0) {
|
||||||
else Stats(food = (totalFood * -3) / 4)
|
|
||||||
newFinalStatList.add("Unhappiness", foodReducedByUnhappiness)
|
|
||||||
} else if (cityInfo.isWeLoveTheKingDay()) {
|
|
||||||
// We Love The King Day +25%, only if not unhappy
|
// We Love The King Day +25%, only if not unhappy
|
||||||
val weLoveTheKingFood = Stats(food = totalFood / 4)
|
val weLoveTheKingFood = Stats(food = totalFood / 4)
|
||||||
newFinalStatList.add("We Love The King Day", weLoveTheKingFood)
|
newFinalStatList.add("We Love The King Day", weLoveTheKingFood)
|
||||||
@ -620,6 +649,16 @@ class CityStats(val cityInfo: CityInfo) {
|
|||||||
newFinalStatList["Excess food to production"] = Stats(production = totalFood, food = -totalFood)
|
newFinalStatList["Excess food to production"] = Stats(production = totalFood, food = -totalFood)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val growthNullifyingUnique = cityInfo.getMatchingUniques(UniqueType.NullifiesGrwoth).firstOrNull()
|
||||||
|
if (growthNullifyingUnique != null) {
|
||||||
|
val uniqueSource =
|
||||||
|
if (growthNullifyingUnique.sourceObjectType == UniqueTarget.Global && growthNullifyingUnique.conditionals.any())
|
||||||
|
GlobalUniques.getUniqueSourceDescription(growthNullifyingUnique)
|
||||||
|
else growthNullifyingUnique.sourceObjectType?.name ?: ""
|
||||||
|
val amountToRemove = -newFinalStatList.values.sumOf { it[Stat.Food].toDouble() }
|
||||||
|
newFinalStatList[uniqueSource] = Stats().apply { this[Stat.Food] = amountToRemove.toFloat() }
|
||||||
|
}
|
||||||
|
|
||||||
if (cityInfo.isInResistance())
|
if (cityInfo.isInResistance())
|
||||||
newFinalStatList.clear() // NOPE
|
newFinalStatList.clear() // NOPE
|
||||||
|
|
||||||
|
@ -382,7 +382,8 @@ class CivilizationInfo {
|
|||||||
else city.getAllUniquesWithNonLocalEffects()
|
else city.getAllUniquesWithNonLocalEffects()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasUnique(uniqueType: UniqueType, stateForConditionals: StateForConditionals? = null) = getMatchingUniques(uniqueType, stateForConditionals).any()
|
fun hasUnique(uniqueType: UniqueType, stateForConditionals: StateForConditionals? =
|
||||||
|
StateForConditionals(this)) = getMatchingUniques(uniqueType, stateForConditionals).any()
|
||||||
fun hasUnique(unique: String) = getMatchingUniques(unique).any()
|
fun hasUnique(unique: String) = getMatchingUniques(unique).any()
|
||||||
|
|
||||||
// Does not return local uniques, only global ones.
|
// Does not return local uniques, only global ones.
|
||||||
@ -402,6 +403,9 @@ class CivilizationInfo {
|
|||||||
yieldAll(getEra().getMatchingUniques(uniqueType, stateForConditionals))
|
yieldAll(getEra().getMatchingUniques(uniqueType, stateForConditionals))
|
||||||
if (religionManager.religion != null)
|
if (religionManager.religion != null)
|
||||||
yieldAll(religionManager.religion!!.getFounderUniques().filter { it.isOfType(uniqueType) })
|
yieldAll(religionManager.religion!!.getFounderUniques().filter { it.isOfType(uniqueType) })
|
||||||
|
|
||||||
|
yieldAll(gameInfo.ruleSet.globalUniques.getMatchingUniques(uniqueType, stateForConditionals))
|
||||||
|
|
||||||
}.filter {
|
}.filter {
|
||||||
it.conditionalsApply(stateForConditionals)
|
it.conditionalsApply(stateForConditionals)
|
||||||
}
|
}
|
||||||
@ -424,6 +428,8 @@ class CivilizationInfo {
|
|||||||
.asSequence()
|
.asSequence()
|
||||||
.filter { it.placeholderText == uniqueTemplate }
|
.filter { it.placeholderText == uniqueTemplate }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
yieldAll(gameInfo.ruleSet.globalUniques.getMatchingUniques(uniqueTemplate))
|
||||||
}
|
}
|
||||||
|
|
||||||
//region Units
|
//region Units
|
||||||
@ -827,6 +833,7 @@ class CivilizationInfo {
|
|||||||
updateViewableTiles() // adds explored tiles so that the units will be able to perform automated actions better
|
updateViewableTiles() // adds explored tiles so that the units will be able to perform automated actions better
|
||||||
transients().updateCitiesConnectedToCapital()
|
transients().updateCitiesConnectedToCapital()
|
||||||
startTurnFlags()
|
startTurnFlags()
|
||||||
|
updateRevolts()
|
||||||
for (city in cities) city.startTurn() // Most expensive part of startTurn
|
for (city in cities) city.startTurn() // Most expensive part of startTurn
|
||||||
|
|
||||||
for (unit in getCivUnits()) unit.startTurn()
|
for (unit in getCivUnits()) unit.startTurn()
|
||||||
@ -921,6 +928,11 @@ class CivilizationInfo {
|
|||||||
if (flagsCountdown[flag]!! > 0)
|
if (flagsCountdown[flag]!! > 0)
|
||||||
flagsCountdown[flag] = flagsCountdown[flag]!! - 1
|
flagsCountdown[flag] = flagsCountdown[flag]!! - 1
|
||||||
|
|
||||||
|
if (flagsCountdown[flag] != 0) continue
|
||||||
|
|
||||||
|
when (flag) {
|
||||||
|
CivFlags.RevoltSpawning.name -> doRevoltSpawn()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
handleDiplomaticVictoryFlags()
|
handleDiplomaticVictoryFlags()
|
||||||
}
|
}
|
||||||
@ -947,8 +959,8 @@ class CivilizationInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addFlag(flag: String, count: Int) = flagsCountdown.set(flag, count)
|
fun addFlag(flag: String, count: Int) = flagsCountdown.set(flag, count)
|
||||||
|
|
||||||
fun removeFlag(flag: String) = flagsCountdown.remove(flag)
|
fun removeFlag(flag: String) = flagsCountdown.remove(flag)
|
||||||
|
fun hasFlag(flag: String) = flagsCountdown.contains(flag)
|
||||||
|
|
||||||
fun getTurnsBetweenDiplomaticVotings() = (15 * gameInfo.gameParameters.gameSpeed.modifier).toInt() // Dunno the exact calculation, hidden in Lua files
|
fun getTurnsBetweenDiplomaticVotings() = (15 * gameInfo.gameParameters.gameSpeed.modifier).toInt() // Dunno the exact calculation, hidden in Lua files
|
||||||
|
|
||||||
@ -975,6 +987,65 @@ class CivilizationInfo {
|
|||||||
fun shouldCheckForDiplomaticVictory() =
|
fun shouldCheckForDiplomaticVictory() =
|
||||||
shouldShowDiplomaticVotingResults()
|
shouldShowDiplomaticVotingResults()
|
||||||
|
|
||||||
|
private fun updateRevolts() {
|
||||||
|
if (!hasUnique(UniqueType.SpawnRebels)) {
|
||||||
|
removeFlag(CivFlags.RevoltSpawning.name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasFlag(CivFlags.RevoltSpawning.name)) {
|
||||||
|
addFlag(CivFlags.RevoltSpawning.name, max(getTurnsBeforeRevolt(),1))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doRevoltSpawn() {
|
||||||
|
val random = Random()
|
||||||
|
val rebelCount = 1 + random.nextInt(100 + 20 * (cities.size - 1)) / 100
|
||||||
|
val spawnCity = cities.maxByOrNull { random.nextInt(it.population.population + 10) } ?: return
|
||||||
|
val spawnTile = spawnCity.getTiles().maxByOrNull { rateTileForRevoltSpawn(it) } ?: return
|
||||||
|
val unitToSpawn = gameInfo.ruleSet.units.values.asSequence().filter {
|
||||||
|
it.uniqueTo == null && it.isMelee() && it.isLandUnit()
|
||||||
|
&& !it.hasUnique(UniqueType.CannotAttack) && it.isBuildable(this)
|
||||||
|
}.maxByOrNull {
|
||||||
|
random.nextInt(1000)
|
||||||
|
} ?: return
|
||||||
|
|
||||||
|
repeat(rebelCount) {
|
||||||
|
gameInfo.tileMap.placeUnitNearTile(
|
||||||
|
spawnTile.position,
|
||||||
|
unitToSpawn.name,
|
||||||
|
gameInfo.getBarbarianCivilization()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will be automatically added again as long as unhappiness is still low enough
|
||||||
|
removeFlag(CivFlags.RevoltSpawning.name)
|
||||||
|
|
||||||
|
addNotification("Your citizens are revolting due to very high unhappiness!", spawnTile.position, unitToSpawn.name, "StatIcons/Malcontent")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Higher is better
|
||||||
|
private fun rateTileForRevoltSpawn(tile: TileInfo): Int {
|
||||||
|
if (tile.isWater || tile.militaryUnit != null || tile.civilianUnit != null || tile.isCityCenter() || tile.isImpassible())
|
||||||
|
return -1;
|
||||||
|
var score = 10
|
||||||
|
if (tile.improvement == null) {
|
||||||
|
score += 4
|
||||||
|
if (tile.resource != null) {
|
||||||
|
score += 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tile.getDefensiveBonus() > 0)
|
||||||
|
score += 4
|
||||||
|
return score
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTurnsBeforeRevolt(): Int {
|
||||||
|
val score = ((4 + Random().nextInt(3)) * max(gameInfo.gameParameters.gameSpeed.modifier, 1f)).toInt()
|
||||||
|
return score
|
||||||
|
}
|
||||||
|
|
||||||
/** Modify gold by a given amount making sure it does neither overflow nor underflow.
|
/** Modify gold by a given amount making sure it does neither overflow nor underflow.
|
||||||
* @param delta the amount to add (can be negative)
|
* @param delta the amount to add (can be negative)
|
||||||
*/
|
*/
|
||||||
@ -1252,4 +1323,5 @@ enum class CivFlags {
|
|||||||
ShouldResetDiplomaticVotes,
|
ShouldResetDiplomaticVotes,
|
||||||
RecentlyBullied,
|
RecentlyBullied,
|
||||||
TurnsTillCallForBarbHelp,
|
TurnsTillCallForBarbHelp,
|
||||||
|
RevoltSpawning,
|
||||||
}
|
}
|
||||||
|
25
core/src/com/unciv/models/ruleset/GlobalUniques.kt
Normal file
25
core/src/com/unciv/models/ruleset/GlobalUniques.kt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package com.unciv.models.ruleset
|
||||||
|
|
||||||
|
import com.unciv.models.ruleset.unique.Unique
|
||||||
|
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||||
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
|
|
||||||
|
class GlobalUniques: RulesetObject() {
|
||||||
|
override var name = ""
|
||||||
|
override fun getUniqueTarget() = UniqueTarget.Global
|
||||||
|
override fun makeLink() = "" // No own category on Civilopedia screen
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getUniqueSourceDescription(unique: Unique): String {
|
||||||
|
if (unique.conditionals.none())
|
||||||
|
return "Global Effect"
|
||||||
|
|
||||||
|
return when (unique.conditionals.first().type) {
|
||||||
|
UniqueType.ConditionalGoldenAge -> "Golden Age"
|
||||||
|
UniqueType.ConditionalHappy -> "Happiness"
|
||||||
|
UniqueType.ConditionalBetweenHappiness, UniqueType.ConditionalBelowHappiness -> "Unhappiness"
|
||||||
|
else -> "Global Effect"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -65,13 +65,12 @@ class Ruleset {
|
|||||||
|
|
||||||
private val jsonParser = JsonParser()
|
private val jsonParser = JsonParser()
|
||||||
|
|
||||||
var modWithReligionLoaded = false
|
|
||||||
|
|
||||||
var name = ""
|
var name = ""
|
||||||
val beliefs = LinkedHashMap<String, Belief>()
|
val beliefs = LinkedHashMap<String, Belief>()
|
||||||
val buildings = LinkedHashMap<String, Building>()
|
val buildings = LinkedHashMap<String, Building>()
|
||||||
val difficulties = LinkedHashMap<String, Difficulty>()
|
val difficulties = LinkedHashMap<String, Difficulty>()
|
||||||
val eras = LinkedHashMap<String, Era>()
|
val eras = LinkedHashMap<String, Era>()
|
||||||
|
var globalUniques = GlobalUniques()
|
||||||
val nations = LinkedHashMap<String, Nation>()
|
val nations = LinkedHashMap<String, Nation>()
|
||||||
val policies = LinkedHashMap<String, Policy>()
|
val policies = LinkedHashMap<String, Policy>()
|
||||||
val policyBranches = LinkedHashMap<String, PolicyBranch>()
|
val policyBranches = LinkedHashMap<String, PolicyBranch>()
|
||||||
@ -104,15 +103,16 @@ class Ruleset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun add(ruleset: Ruleset) {
|
fun add(ruleset: Ruleset) {
|
||||||
|
beliefs.putAll(ruleset.beliefs)
|
||||||
buildings.putAll(ruleset.buildings)
|
buildings.putAll(ruleset.buildings)
|
||||||
for (buildingToRemove in ruleset.modOptions.buildingsToRemove) buildings.remove(buildingToRemove)
|
for (buildingToRemove in ruleset.modOptions.buildingsToRemove) buildings.remove(buildingToRemove)
|
||||||
difficulties.putAll(ruleset.difficulties)
|
difficulties.putAll(ruleset.difficulties)
|
||||||
eras.putAll(ruleset.eras)
|
eras.putAll(ruleset.eras)
|
||||||
|
globalUniques = GlobalUniques().apply { uniques.addAll(globalUniques.uniques); uniques.addAll(ruleset.globalUniques.uniques) }
|
||||||
nations.putAll(ruleset.nations)
|
nations.putAll(ruleset.nations)
|
||||||
for (nationToRemove in ruleset.modOptions.nationsToRemove) nations.remove(nationToRemove)
|
for (nationToRemove in ruleset.modOptions.nationsToRemove) nations.remove(nationToRemove)
|
||||||
policyBranches.putAll(ruleset.policyBranches)
|
policyBranches.putAll(ruleset.policyBranches)
|
||||||
policies.putAll(ruleset.policies)
|
policies.putAll(ruleset.policies)
|
||||||
beliefs.putAll(ruleset.beliefs)
|
|
||||||
quests.putAll(ruleset.quests)
|
quests.putAll(ruleset.quests)
|
||||||
religions.addAll(ruleset.religions)
|
religions.addAll(ruleset.religions)
|
||||||
ruinRewards.putAll(ruleset.ruinRewards)
|
ruinRewards.putAll(ruleset.ruinRewards)
|
||||||
@ -127,7 +127,6 @@ class Ruleset {
|
|||||||
unitTypes.putAll(ruleset.unitTypes)
|
unitTypes.putAll(ruleset.unitTypes)
|
||||||
for (unitToRemove in ruleset.modOptions.unitsToRemove) units.remove(unitToRemove)
|
for (unitToRemove in ruleset.modOptions.unitsToRemove) units.remove(unitToRemove)
|
||||||
mods += ruleset.mods
|
mods += ruleset.mods
|
||||||
modWithReligionLoaded = modWithReligionLoaded || ruleset.modWithReligionLoaded
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
@ -135,14 +134,15 @@ class Ruleset {
|
|||||||
buildings.clear()
|
buildings.clear()
|
||||||
difficulties.clear()
|
difficulties.clear()
|
||||||
eras.clear()
|
eras.clear()
|
||||||
policyBranches.clear()
|
globalUniques = GlobalUniques()
|
||||||
specialists.clear()
|
|
||||||
mods.clear()
|
mods.clear()
|
||||||
nations.clear()
|
nations.clear()
|
||||||
policies.clear()
|
policies.clear()
|
||||||
|
policyBranches.clear()
|
||||||
|
quests.clear()
|
||||||
religions.clear()
|
religions.clear()
|
||||||
ruinRewards.clear()
|
ruinRewards.clear()
|
||||||
quests.clear()
|
specialists.clear()
|
||||||
technologies.clear()
|
technologies.clear()
|
||||||
terrains.clear()
|
terrains.clear()
|
||||||
tileImprovements.clear()
|
tileImprovements.clear()
|
||||||
@ -150,7 +150,6 @@ class Ruleset {
|
|||||||
unitPromotions.clear()
|
unitPromotions.clear()
|
||||||
units.clear()
|
units.clear()
|
||||||
unitTypes.clear()
|
unitTypes.clear()
|
||||||
modWithReligionLoaded = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -201,7 +200,7 @@ class Ruleset {
|
|||||||
if (erasFile.exists()) eras += createHashmap(jsonParser.getFromJson(Array<Era>::class.java, erasFile))
|
if (erasFile.exists()) eras += createHashmap(jsonParser.getFromJson(Array<Era>::class.java, erasFile))
|
||||||
// While `eras.values.toList()` might seem more logical, eras.values is a MutableCollection and
|
// While `eras.values.toList()` might seem more logical, eras.values is a MutableCollection and
|
||||||
// therefore does not guarantee keeping the order of elements like a LinkedHashMap does.
|
// therefore does not guarantee keeping the order of elements like a LinkedHashMap does.
|
||||||
// Using a map sidesteps this problem
|
// Using map{} sidesteps this problem
|
||||||
eras.map { it.value }.withIndex().forEach { it.value.eraNumber = it.index }
|
eras.map { it.value }.withIndex().forEach { it.value.eraNumber = it.index }
|
||||||
|
|
||||||
val unitTypesFile = folderHandle.child("UnitTypes.json")
|
val unitTypesFile = folderHandle.child("UnitTypes.json")
|
||||||
@ -254,7 +253,13 @@ class Ruleset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val difficultiesFile = folderHandle.child("Difficulties.json")
|
val difficultiesFile = folderHandle.child("Difficulties.json")
|
||||||
if (difficultiesFile.exists()) difficulties += createHashmap(jsonParser.getFromJson(Array<Difficulty>::class.java, difficultiesFile))
|
if (difficultiesFile.exists())
|
||||||
|
difficulties += createHashmap(jsonParser.getFromJson(Array<Difficulty>::class.java, difficultiesFile))
|
||||||
|
|
||||||
|
val globalUniquesFile = folderHandle.child("GlobalUniques.json")
|
||||||
|
if (globalUniquesFile.exists()) {
|
||||||
|
globalUniques = jsonParser.getFromJson(GlobalUniques::class.java, globalUniquesFile)
|
||||||
|
}
|
||||||
|
|
||||||
val gameBasicsLoadTime = System.currentTimeMillis() - gameBasicsStartTime
|
val gameBasicsLoadTime = System.currentTimeMillis() - gameBasicsStartTime
|
||||||
if (printOutput) println("Loading ruleset - " + gameBasicsLoadTime + "ms")
|
if (printOutput) println("Loading ruleset - " + gameBasicsLoadTime + "ms")
|
||||||
@ -275,8 +280,6 @@ class Ruleset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasReligion() = beliefs.any() && modWithReligionLoaded
|
|
||||||
|
|
||||||
/** Used for displaying a RuleSet's name */
|
/** Used for displaying a RuleSet's name */
|
||||||
override fun toString() = when {
|
override fun toString() = when {
|
||||||
name.isNotEmpty() -> name
|
name.isNotEmpty() -> name
|
||||||
@ -476,7 +479,7 @@ class Ruleset {
|
|||||||
// Quit here when no base ruleset is loaded - references cannot be checked
|
// Quit here when no base ruleset is loaded - references cannot be checked
|
||||||
if (!modOptions.isBaseRuleset) return lines
|
if (!modOptions.isBaseRuleset) return lines
|
||||||
|
|
||||||
val baseRuleset = RulesetCache.getBaseRuleset() // for UnitTypes fallback
|
val baseRuleset = RulesetCache.getVanillaRuleset() // for UnitTypes fallback
|
||||||
|
|
||||||
for (unit in units.values) {
|
for (unit in units.values) {
|
||||||
if (unit.requiredTech != null && !technologies.containsKey(unit.requiredTech!!))
|
if (unit.requiredTech != null && !technologies.containsKey(unit.requiredTech!!))
|
||||||
@ -697,7 +700,7 @@ object RulesetCache : HashMap<String,Ruleset>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun getBaseRuleset() = this[BaseRuleset.Civ_V_Vanilla.fullName]!!.clone() // safeguard, so no-one edits the base ruleset by mistake
|
fun getVanillaRuleset() = this[BaseRuleset.Civ_V_Vanilla.fullName]!!.clone() // safeguard, so no-one edits the base ruleset by mistake
|
||||||
|
|
||||||
fun getSortedBaseRulesets(): List<String> {
|
fun getSortedBaseRulesets(): List<String> {
|
||||||
val baseRulesets = values
|
val baseRulesets = values
|
||||||
@ -729,7 +732,7 @@ object RulesetCache : HashMap<String,Ruleset>() {
|
|||||||
|
|
||||||
val baseRuleset =
|
val baseRuleset =
|
||||||
if (containsKey(optionalBaseRuleset) && this[optionalBaseRuleset]!!.modOptions.isBaseRuleset) this[optionalBaseRuleset]!!
|
if (containsKey(optionalBaseRuleset) && this[optionalBaseRuleset]!!.modOptions.isBaseRuleset) this[optionalBaseRuleset]!!
|
||||||
else getBaseRuleset()
|
else getVanillaRuleset()
|
||||||
|
|
||||||
|
|
||||||
val loadedMods = mods
|
val loadedMods = mods
|
||||||
@ -744,20 +747,20 @@ object RulesetCache : HashMap<String,Ruleset>() {
|
|||||||
if (mod.modOptions.isBaseRuleset) {
|
if (mod.modOptions.isBaseRuleset) {
|
||||||
newRuleset.modOptions = mod.modOptions
|
newRuleset.modOptions = mod.modOptions
|
||||||
}
|
}
|
||||||
if (mod.beliefs.any()) {
|
|
||||||
newRuleset.modWithReligionLoaded = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
newRuleset.updateBuildingCosts() // only after we've added all the mods can we calculate the building costs
|
newRuleset.updateBuildingCosts() // only after we've added all the mods can we calculate the building costs
|
||||||
|
|
||||||
// This one should be temporary
|
// This one should be temporary
|
||||||
if (newRuleset.unitTypes.isEmpty()) {
|
if (newRuleset.unitTypes.isEmpty()) {
|
||||||
newRuleset.unitTypes.putAll(getBaseRuleset().unitTypes)
|
newRuleset.unitTypes.putAll(getVanillaRuleset().unitTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This one should be permanent
|
// These should be permanent
|
||||||
if (newRuleset.ruinRewards.isEmpty()) {
|
if (newRuleset.ruinRewards.isEmpty()) {
|
||||||
newRuleset.ruinRewards.putAll(getBaseRuleset().ruinRewards)
|
newRuleset.ruinRewards.putAll(getVanillaRuleset().ruinRewards)
|
||||||
|
}
|
||||||
|
if (newRuleset.globalUniques.uniques.isEmpty()) {
|
||||||
|
newRuleset.globalUniques = getVanillaRuleset().globalUniques
|
||||||
}
|
}
|
||||||
|
|
||||||
return newRuleset
|
return newRuleset
|
||||||
|
@ -58,6 +58,12 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
|
|||||||
UniqueType.ConditionalNotWar -> state.civInfo?.isAtWar() == false
|
UniqueType.ConditionalNotWar -> state.civInfo?.isAtWar() == false
|
||||||
UniqueType.ConditionalHappy ->
|
UniqueType.ConditionalHappy ->
|
||||||
state.civInfo != null && state.civInfo.statsForNextTurn.happiness >= 0
|
state.civInfo != null && state.civInfo.statsForNextTurn.happiness >= 0
|
||||||
|
UniqueType.ConditionalBetweenHappiness ->
|
||||||
|
state.civInfo != null
|
||||||
|
&& condition.params[0].toInt() <= state.civInfo.happinessForNextTurn
|
||||||
|
&& state.civInfo.happinessForNextTurn < condition.params[1].toInt()
|
||||||
|
UniqueType.ConditionalBelowHappiness ->
|
||||||
|
state.civInfo != null && state.civInfo.happinessForNextTurn < condition.params[0].toInt()
|
||||||
UniqueType.ConditionalGoldenAge ->
|
UniqueType.ConditionalGoldenAge ->
|
||||||
state.civInfo != null && state.civInfo.goldenAges.isGoldenAge()
|
state.civInfo != null && state.civInfo.goldenAges.isGoldenAge()
|
||||||
UniqueType.ConditionalBeforeEra ->
|
UniqueType.ConditionalBeforeEra ->
|
||||||
|
@ -87,6 +87,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
|||||||
|
|
||||||
// Stat percentage boosts
|
// Stat percentage boosts
|
||||||
StatPercentBonus("[amount]% [stat]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
StatPercentBonus("[amount]% [stat]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||||
|
StatPercentBonusCities("[amount]% [stat] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||||
StatPercentFromObject("[amount]% [stat] from every [tileFilter/specialist/buildingName]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
StatPercentFromObject("[amount]% [stat] from every [tileFilter/specialist/buildingName]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||||
@Deprecated("As of 3.18.17", ReplaceWith("[amount]% [stat] from every [tileFilter/specialist/buildingName]"))
|
@Deprecated("As of 3.18.17", ReplaceWith("[amount]% [stat] from every [tileFilter/specialist/buildingName]"))
|
||||||
StatPercentSignedFromObject("+[amount]% [stat] from every [tileFilter/specialist/buildingName]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
StatPercentSignedFromObject("+[amount]% [stat] from every [tileFilter/specialist/buildingName]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||||
@ -95,7 +96,8 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
|||||||
AllStatsSignedPercentFromObject("+[amount]% yield from every [tileFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
AllStatsSignedPercentFromObject("+[amount]% yield from every [tileFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||||
StatPercentFromReligionFollowers("[amount]% [stat] from every follower, up to [amount]%", UniqueTarget.FollowerBelief),
|
StatPercentFromReligionFollowers("[amount]% [stat] from every follower, up to [amount]%", UniqueTarget.FollowerBelief),
|
||||||
BonusStatsFromCityStates("[amount]% [stat] from City-States", UniqueTarget.Global),
|
BonusStatsFromCityStates("[amount]% [stat] from City-States", UniqueTarget.Global),
|
||||||
StatPercentBonusCities("[amount]% [stat] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
NullifiesStat("Nullifies [stat] [cityFilter]", UniqueTarget.Global),
|
||||||
|
NullifiesGrwoth("Nullifies Growth [cityFilter]", UniqueTarget.Global),
|
||||||
|
|
||||||
PercentProductionWonders("[amount]% Production when constructing [buildingFilter] wonders [cityFilter]", UniqueTarget.Global, UniqueTarget.Resource, UniqueTarget.FollowerBelief),
|
PercentProductionWonders("[amount]% Production when constructing [buildingFilter] wonders [cityFilter]", UniqueTarget.Global, UniqueTarget.Resource, UniqueTarget.FollowerBelief),
|
||||||
PercentProductionBuildings("[amount]% Production when constructing [buildingFilter] buildings [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
PercentProductionBuildings("[amount]% Production when constructing [buildingFilter] buildings [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
|
||||||
@ -266,6 +268,8 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
|||||||
StartsWithTech("Starts with [tech]", UniqueTarget.Nation),
|
StartsWithTech("Starts with [tech]", UniqueTarget.Nation),
|
||||||
ResearchableMultipleTimes("Can be continually researched", UniqueTarget.Global),
|
ResearchableMultipleTimes("Can be continually researched", UniqueTarget.Global),
|
||||||
|
|
||||||
|
SpawnRebels("Rebel units may spawn", UniqueTarget.Global),
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
//endregion Global uniques
|
//endregion Global uniques
|
||||||
@ -514,9 +518,12 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
|||||||
/////// civ conditionals
|
/////// civ conditionals
|
||||||
ConditionalWar("when at war", UniqueTarget.Conditional),
|
ConditionalWar("when at war", UniqueTarget.Conditional),
|
||||||
ConditionalNotWar("when not at war", UniqueTarget.Conditional),
|
ConditionalNotWar("when not at war", UniqueTarget.Conditional),
|
||||||
ConditionalHappy("while the empire is happy", UniqueTarget.Conditional),
|
|
||||||
ConditionalGoldenAge("during a Golden Age", UniqueTarget.Conditional),
|
ConditionalGoldenAge("during a Golden Age", UniqueTarget.Conditional),
|
||||||
|
|
||||||
|
ConditionalHappy("while the empire is happy", UniqueTarget.Conditional),
|
||||||
|
ConditionalBetweenHappiness("when between [amount] and [amount] Happiness", UniqueTarget.Conditional),
|
||||||
|
ConditionalBelowHappiness("when below [amount] Happiness", UniqueTarget.Conditional),
|
||||||
|
|
||||||
ConditionalDuringEra("during the [era]", UniqueTarget.Conditional),
|
ConditionalDuringEra("during the [era]", UniqueTarget.Conditional),
|
||||||
ConditionalBeforeEra("before the [era]", UniqueTarget.Conditional),
|
ConditionalBeforeEra("before the [era]", UniqueTarget.Conditional),
|
||||||
ConditionalStartingFromEra("starting from the [era]", UniqueTarget.Conditional),
|
ConditionalStartingFromEra("starting from the [era]", UniqueTarget.Conditional),
|
||||||
|
@ -238,7 +238,7 @@ object TranslationFileWriter {
|
|||||||
|
|
||||||
private fun generateStringsFromJSONs(jsonsFolder: FileHandle): LinkedHashMap<String, MutableSet<String>> {
|
private fun generateStringsFromJSONs(jsonsFolder: FileHandle): LinkedHashMap<String, MutableSet<String>> {
|
||||||
// build maps identifying parameters as certain types of filters - unitFilter etc
|
// build maps identifying parameters as certain types of filters - unitFilter etc
|
||||||
val ruleset = RulesetCache.getBaseRuleset()
|
val ruleset = RulesetCache.getVanillaRuleset()
|
||||||
val tileFilterMap = ruleset.terrains.keys.toMutableSet().apply { addAll(sequenceOf(
|
val tileFilterMap = ruleset.terrains.keys.toMutableSet().apply { addAll(sequenceOf(
|
||||||
"Friendly Land",
|
"Friendly Land",
|
||||||
"Foreign Land",
|
"Foreign Land",
|
||||||
@ -422,6 +422,7 @@ object TranslationFileWriter {
|
|||||||
"Buildings" -> emptyArray<Building>().javaClass
|
"Buildings" -> emptyArray<Building>().javaClass
|
||||||
"Difficulties" -> emptyArray<Difficulty>().javaClass
|
"Difficulties" -> emptyArray<Difficulty>().javaClass
|
||||||
"Eras" -> emptyArray<Era>().javaClass
|
"Eras" -> emptyArray<Era>().javaClass
|
||||||
|
"GlobalUniques" -> GlobalUniques().javaClass
|
||||||
"Nations" -> emptyArray<Nation>().javaClass
|
"Nations" -> emptyArray<Nation>().javaClass
|
||||||
"Policies" -> emptyArray<PolicyBranch>().javaClass
|
"Policies" -> emptyArray<PolicyBranch>().javaClass
|
||||||
"Quests" -> emptyArray<Quest>().javaClass
|
"Quests" -> emptyArray<Quest>().javaClass
|
||||||
|
@ -87,7 +87,7 @@ class CityStatsTable(val cityScreen: CityScreen): Table() {
|
|||||||
tableWithIcons.add(ImageGetter.getImage("StatIcons/Resistance")).size(20f)
|
tableWithIcons.add(ImageGetter.getImage("StatIcons/Resistance")).size(20f)
|
||||||
tableWithIcons.add("In resistance for another [${cityInfo.getFlag(CityFlags.Resistance)}] turns".toLabel()).row()
|
tableWithIcons.add("In resistance for another [${cityInfo.getFlag(CityFlags.Resistance)}] turns".toLabel()).row()
|
||||||
}
|
}
|
||||||
if (cityInfo.isWeLoveTheKingDay()) {
|
if (cityInfo.isWeLoveTheKingDayActive()) {
|
||||||
tableWithIcons.add(ImageGetter.getStatIcon("Food")).size(20f)
|
tableWithIcons.add(ImageGetter.getStatIcon("Food")).size(20f)
|
||||||
tableWithIcons.add("We Love The King Day for another [${cityInfo.getFlag(CityFlags.WeLoveTheKing)}] turns".toLabel()).row()
|
tableWithIcons.add("We Love The King Day for another [${cityInfo.getFlag(CityFlags.WeLoveTheKing)}] turns".toLabel()).row()
|
||||||
} else if (cityInfo.demandedResource != "") {
|
} else if (cityInfo.demandedResource != "") {
|
||||||
|
@ -196,7 +196,7 @@ class CivilopediaScreen(
|
|||||||
CivilopediaCategories.Technology -> ruleset.technologies.values
|
CivilopediaCategories.Technology -> ruleset.technologies.values
|
||||||
CivilopediaCategories.Promotion -> ruleset.unitPromotions.values
|
CivilopediaCategories.Promotion -> ruleset.unitPromotions.values
|
||||||
CivilopediaCategories.Policy -> ruleset.policies.values
|
CivilopediaCategories.Policy -> ruleset.policies.values
|
||||||
CivilopediaCategories.Tutorial -> tutorialController.getCivilopediaTutorials()
|
CivilopediaCategories.Tutorial -> tutorialController.getCivilopediaTutorials(ruleset)
|
||||||
CivilopediaCategories.Difficulty -> ruleset.difficulties.values
|
CivilopediaCategories.Difficulty -> ruleset.difficulties.values
|
||||||
CivilopediaCategories.Belief -> (ruleset.beliefs.values.asSequence() +
|
CivilopediaCategories.Belief -> (ruleset.beliefs.values.asSequence() +
|
||||||
Belief.getCivilopediaReligionEntry(ruleset)).toList()
|
Belief.getCivilopediaReligionEntry(ruleset)).toList()
|
||||||
|
@ -22,7 +22,7 @@ import com.unciv.ui.utils.*
|
|||||||
class MapEditorScreen(): BaseScreen() {
|
class MapEditorScreen(): BaseScreen() {
|
||||||
var mapName = ""
|
var mapName = ""
|
||||||
var tileMap = TileMap()
|
var tileMap = TileMap()
|
||||||
var ruleset = Ruleset().apply { add(RulesetCache.getBaseRuleset()) }
|
var ruleset = Ruleset().apply { add(RulesetCache.getVanillaRuleset()) }
|
||||||
|
|
||||||
var gameSetupInfo = GameSetupInfo()
|
var gameSetupInfo = GameSetupInfo()
|
||||||
lateinit var mapHolder: EditorMapHolder
|
lateinit var mapHolder: EditorMapHolder
|
||||||
|
@ -23,7 +23,7 @@ import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
|||||||
/** New map generation screen */
|
/** New map generation screen */
|
||||||
class NewMapScreen(val mapParameters: MapParameters = getDefaultParameters()) : PickerScreen() {
|
class NewMapScreen(val mapParameters: MapParameters = getDefaultParameters()) : PickerScreen() {
|
||||||
|
|
||||||
private val ruleset = RulesetCache.getBaseRuleset()
|
private val ruleset = RulesetCache.getVanillaRuleset()
|
||||||
private var generatedMap: TileMap? = null
|
private var generatedMap: TileMap? = null
|
||||||
private val mapParametersTable: MapParametersTable
|
private val mapParametersTable: MapParametersTable
|
||||||
private val modCheckBoxes: ModCheckboxTable
|
private val modCheckBoxes: ModCheckboxTable
|
||||||
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.utils.Array
|
|||||||
import com.unciv.JsonParser
|
import com.unciv.JsonParser
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.models.Tutorial
|
import com.unciv.models.Tutorial
|
||||||
|
import com.unciv.models.ruleset.Ruleset
|
||||||
import com.unciv.models.stats.INamed
|
import com.unciv.models.stats.INamed
|
||||||
import com.unciv.ui.civilopedia.FormattedLine
|
import com.unciv.ui.civilopedia.FormattedLine
|
||||||
import com.unciv.ui.civilopedia.SimpleCivilopediaText
|
import com.unciv.ui.civilopedia.SimpleCivilopediaText
|
||||||
@ -70,10 +71,13 @@ class TutorialController(screen: BaseScreen) {
|
|||||||
/** Get all Tutorials intended to be displayed in the Civilopedia
|
/** Get all Tutorials intended to be displayed in the Civilopedia
|
||||||
* as a List of wrappers supporting INamed and ICivilopediaText
|
* as a List of wrappers supporting INamed and ICivilopediaText
|
||||||
*/
|
*/
|
||||||
fun getCivilopediaTutorials() =
|
fun getCivilopediaTutorials(ruleset: Ruleset): List<CivilopediaTutorial> {
|
||||||
tutorials.filter {
|
val civilopediaTutorials = tutorials.filter {
|
||||||
Tutorial.findByName(it.key)!!.isCivilopedia
|
Tutorial.findByName(it.key)!!.isCivilopedia
|
||||||
}.map {
|
}.map { tutorial ->
|
||||||
CivilopediaTutorial(it.key, it.value)
|
val lines = tutorial.value
|
||||||
|
CivilopediaTutorial(tutorial.key, lines)
|
||||||
|
}
|
||||||
|
return civilopediaTutorials
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,11 @@ Example: "[20]% [Culture]"
|
|||||||
|
|
||||||
Applicable to: Global, FollowerBelief
|
Applicable to: Global, FollowerBelief
|
||||||
|
|
||||||
|
#### [amount]% [stat] [cityFilter]
|
||||||
|
Example: "[20]% [Culture] [in all cities]"
|
||||||
|
|
||||||
|
Applicable to: Global, FollowerBelief
|
||||||
|
|
||||||
#### [amount]% [stat] from every [tileFilter/specialist/buildingName]
|
#### [amount]% [stat] from every [tileFilter/specialist/buildingName]
|
||||||
Example: "[20]% [Culture] from every [tileFilter/specialist/buildingName]"
|
Example: "[20]% [Culture] from every [tileFilter/specialist/buildingName]"
|
||||||
|
|
||||||
@ -91,10 +96,15 @@ Example: "[20]% [Culture] from City-States"
|
|||||||
|
|
||||||
Applicable to: Global
|
Applicable to: Global
|
||||||
|
|
||||||
#### [amount]% [stat] [cityFilter]
|
#### Nullifies [stat] [cityFilter]
|
||||||
Example: "[20]% [Culture] [in all cities]"
|
Example: "Nullifies [Culture] [in all cities]"
|
||||||
|
|
||||||
Applicable to: Global, FollowerBelief
|
Applicable to: Global
|
||||||
|
|
||||||
|
#### Nullifies Growth [cityFilter]
|
||||||
|
Example: "Nullifies Growth [in all cities]"
|
||||||
|
|
||||||
|
Applicable to: Global
|
||||||
|
|
||||||
#### [amount]% Production when constructing [buildingFilter] wonders [cityFilter]
|
#### [amount]% Production when constructing [buildingFilter] wonders [cityFilter]
|
||||||
Example: "[20]% Production when constructing [Culture] wonders [in all cities]"
|
Example: "[20]% Production when constructing [Culture] wonders [in all cities]"
|
||||||
@ -388,6 +398,9 @@ Applicable to: Global
|
|||||||
#### Can be continually researched
|
#### Can be continually researched
|
||||||
Applicable to: Global
|
Applicable to: Global
|
||||||
|
|
||||||
|
#### Rebel units may spawn
|
||||||
|
Applicable to: Global
|
||||||
|
|
||||||
#### [amount]% Strength
|
#### [amount]% Strength
|
||||||
Example: "[20]% Strength"
|
Example: "[20]% Strength"
|
||||||
|
|
||||||
@ -1206,10 +1219,20 @@ Applicable to: Conditional
|
|||||||
#### <when not at war>
|
#### <when not at war>
|
||||||
Applicable to: Conditional
|
Applicable to: Conditional
|
||||||
|
|
||||||
|
#### <during a Golden Age>
|
||||||
|
Applicable to: Conditional
|
||||||
|
|
||||||
#### <while the empire is happy>
|
#### <while the empire is happy>
|
||||||
Applicable to: Conditional
|
Applicable to: Conditional
|
||||||
|
|
||||||
#### <during a Golden Age>
|
#### <when between [amount] and [amount] Happiness>
|
||||||
|
Example: "<when between [20] and [20] Happiness>"
|
||||||
|
|
||||||
|
Applicable to: Conditional
|
||||||
|
|
||||||
|
#### <when below [amount] Happiness>
|
||||||
|
Example: "<when below [20] Happiness>"
|
||||||
|
|
||||||
Applicable to: Conditional
|
Applicable to: Conditional
|
||||||
|
|
||||||
#### <during the [era]>
|
#### <during the [era]>
|
||||||
|
@ -31,7 +31,7 @@ class TileImprovementConstructionTests {
|
|||||||
@Before
|
@Before
|
||||||
fun initTheWorld() {
|
fun initTheWorld() {
|
||||||
RulesetCache.loadRulesets()
|
RulesetCache.loadRulesets()
|
||||||
ruleSet = RulesetCache.getBaseRuleset()
|
ruleSet = RulesetCache.getVanillaRuleset()
|
||||||
civInfo.tech.researchedTechnologies.addAll(ruleSet.technologies.values)
|
civInfo.tech.researchedTechnologies.addAll(ruleSet.technologies.values)
|
||||||
civInfo.tech.techsResearched.addAll(ruleSet.technologies.keys)
|
civInfo.tech.techsResearched.addAll(ruleSet.technologies.keys)
|
||||||
city.civInfo = civInfo
|
city.civInfo = civInfo
|
||||||
|
@ -22,7 +22,7 @@ class TileMapTests {
|
|||||||
@Before
|
@Before
|
||||||
fun initTheWorld() {
|
fun initTheWorld() {
|
||||||
RulesetCache.loadRulesets()
|
RulesetCache.loadRulesets()
|
||||||
ruleSet = RulesetCache.getBaseRuleset()
|
ruleSet = RulesetCache.getVanillaRuleset()
|
||||||
map = TileMap()
|
map = TileMap()
|
||||||
|
|
||||||
tile1.position = Vector2(0f, 0f)
|
tile1.position = Vector2(0f, 0f)
|
||||||
|
@ -28,7 +28,7 @@ class UnitMovementAlgorithmsTests {
|
|||||||
@Before
|
@Before
|
||||||
fun initTheWorld() {
|
fun initTheWorld() {
|
||||||
RulesetCache.loadRulesets()
|
RulesetCache.loadRulesets()
|
||||||
ruleSet = RulesetCache.getBaseRuleset()
|
ruleSet = RulesetCache.getVanillaRuleset()
|
||||||
tile.ruleset = ruleSet
|
tile.ruleset = ruleSet
|
||||||
tile.baseTerrain = Constants.grassland
|
tile.baseTerrain = Constants.grassland
|
||||||
civInfo.tech.techsResearched.addAll(ruleSet.technologies.keys)
|
civInfo.tech.techsResearched.addAll(ruleSet.technologies.keys)
|
||||||
|
@ -28,7 +28,7 @@ class BasicTests {
|
|||||||
@Before
|
@Before
|
||||||
fun loadTranslations() {
|
fun loadTranslations() {
|
||||||
RulesetCache.loadRulesets()
|
RulesetCache.loadRulesets()
|
||||||
ruleset = RulesetCache.getBaseRuleset()
|
ruleset = RulesetCache.getVanillaRuleset()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -31,7 +31,7 @@ class TranslationTests {
|
|||||||
}))
|
}))
|
||||||
translations.readAllLanguagesTranslation()
|
translations.readAllLanguagesTranslation()
|
||||||
RulesetCache.loadRulesets()
|
RulesetCache.loadRulesets()
|
||||||
ruleset = RulesetCache.getBaseRuleset()
|
ruleset = RulesetCache.getVanillaRuleset()
|
||||||
System.setOut(outputChannel)
|
System.setOut(outputChannel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class GlobalUniquesTests {
|
|||||||
|
|
||||||
// Create a new ruleset we can easily edit, and set the important variables of gameInfo
|
// Create a new ruleset we can easily edit, and set the important variables of gameInfo
|
||||||
RulesetCache.loadRulesets()
|
RulesetCache.loadRulesets()
|
||||||
ruleSet = RulesetCache.getBaseRuleset()
|
ruleSet = RulesetCache.getVanillaRuleset()
|
||||||
gameInfo.ruleSet = ruleSet
|
gameInfo.ruleSet = ruleSet
|
||||||
gameInfo.difficultyObject = ruleSet.difficulties["Prince"]!!
|
gameInfo.difficultyObject = ruleSet.difficulties["Prince"]!!
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user