mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-05 21:11:35 +07:00
Fix a few now flagged but working Unique targets (#9845)
* Allow a few working UniqueType-UniqueTarget combos in RulesetValidator * RulesetValidator checks GlobalUniques * Alternate Settlers and Workers recognized via Unique - same rules in RulesetValidator and GameStarter, wiki clarification
This commit is contained in:
parent
ae7ac6a063
commit
b992144ecd
@ -435,7 +435,7 @@ object GameStarter {
|
||||
}
|
||||
|
||||
private fun getStartingUnitsForEraAndDifficulty(civ: Civilization, gameInfo: GameInfo, ruleset: Ruleset, startingEra: String): MutableList<String> {
|
||||
val startingUnits = ruleset.eras[startingEra]!!.getStartingUnits().toMutableList()
|
||||
val startingUnits = ruleset.eras[startingEra]!!.getStartingUnits(ruleset)
|
||||
|
||||
// Add extra units granted by difficulty
|
||||
startingUnits.addAll(when {
|
||||
|
@ -40,6 +40,8 @@ class RulesetValidator(val ruleset: Ruleset) {
|
||||
val rulesetInvariant = UniqueType.UniqueComplianceErrorSeverity.RulesetInvariant
|
||||
val rulesetSpecific = UniqueType.UniqueComplianceErrorSeverity.RulesetSpecific
|
||||
|
||||
checkUniques(ruleset.globalUniques, lines, rulesetInvariant, tryFixUnknownUniques)
|
||||
|
||||
for (unit in ruleset.units.values) {
|
||||
if (unit.upgradesTo == unit.name || (unit.upgradesTo != null && unit.upgradesTo == unit.replaces))
|
||||
lines += "${unit.name} upgrades to itself!"
|
||||
@ -145,6 +147,7 @@ class RulesetValidator(val ruleset: Ruleset) {
|
||||
|
||||
val vanillaRuleset = RulesetCache.getVanillaRuleset() // for UnitTypes fallback
|
||||
|
||||
checkUniques(ruleset.globalUniques, lines, rulesetSpecific, tryFixUnknownUniques)
|
||||
|
||||
if (ruleset.units.values.none { it.hasUnique(UniqueType.FoundCity, StateForConditionals.IgnoreConditionals) })
|
||||
lines += "No city-founding units in ruleset!"
|
||||
@ -313,13 +316,14 @@ class RulesetValidator(val ruleset: Ruleset) {
|
||||
if (building !in ruleset.buildings)
|
||||
lines += "Nonexistent building $building built by settlers when starting in ${era.name}"
|
||||
// todo the whole 'starting unit' thing needs to be redone, there's no reason we can't have a single list containing all the starting units.
|
||||
if (era.startingSettlerUnit !in ruleset.units && (era.startingSettlerUnit!= Constants.settler || ruleset.units.values.none { it.hasUnique(
|
||||
UniqueType.FoundCity) }))
|
||||
if (era.startingSettlerUnit !in ruleset.units
|
||||
&& ruleset.units.values.none { it.hasUnique(UniqueType.FoundCity) })
|
||||
lines += "Nonexistent unit ${era.startingSettlerUnit} marked as starting unit when starting in ${era.name}"
|
||||
if (era.startingWorkerCount!=0 && era.startingWorkerUnit !in ruleset.units)
|
||||
if (era.startingWorkerCount != 0 && era.startingWorkerUnit !in ruleset.units
|
||||
&& ruleset.units.values.none { it.hasUnique(UniqueType.BuildImprovements) })
|
||||
lines += "Nonexistent unit ${era.startingWorkerUnit} marked as starting unit when starting in ${era.name}"
|
||||
|
||||
if ((era.startingMilitaryUnitCount !=0 || allDifficultiesStartingUnits.contains(
|
||||
if ((era.startingMilitaryUnitCount != 0 || allDifficultiesStartingUnits.contains(
|
||||
Constants.eraSpecificUnit)) && era.startingMilitaryUnit !in ruleset.units)
|
||||
lines += "Nonexistent unit ${era.startingMilitaryUnit} marked as starting unit when starting in ${era.name}"
|
||||
if (era.researchAgreementCost < 0 || era.startingSettlerCount < 0 || era.startingWorkerCount < 0 || era.startingMilitaryUnitCount < 0 || era.startingGold < 0 || era.startingCulture < 0)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.unciv.models.ruleset.tech
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.logic.UncivShowableException
|
||||
import com.unciv.models.ruleset.IRulesetObject
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetObject
|
||||
@ -82,10 +83,22 @@ class Era : RulesetObject() {
|
||||
}.map { it.first }.distinct()
|
||||
}
|
||||
|
||||
fun getStartingUnits(): List<String> {
|
||||
fun getStartingUnits(ruleset: Ruleset): MutableList<String> {
|
||||
val startingUnits = mutableListOf<String>()
|
||||
repeat(startingSettlerCount) { startingUnits.add(startingSettlerUnit) }
|
||||
repeat(startingWorkerCount) { startingUnits.add(startingWorkerUnit) }
|
||||
val startingSettlerName: String =
|
||||
if (startingSettlerUnit in ruleset.units) startingSettlerUnit
|
||||
else ruleset.units.values
|
||||
.firstOrNull { it.hasUnique(UniqueType.FoundCity) }
|
||||
?.name
|
||||
?: throw UncivShowableException("No Settler unit found for era $name")
|
||||
val startingWorkerName: String =
|
||||
if (startingWorkerCount == 0 || startingWorkerUnit in ruleset.units) startingWorkerUnit
|
||||
else ruleset.units.values
|
||||
.firstOrNull { it.hasUnique(UniqueType.BuildImprovements) }
|
||||
?.name
|
||||
?: throw UncivShowableException("No Worker unit found for era $name")
|
||||
repeat(startingSettlerCount) { startingUnits.add(startingSettlerName) }
|
||||
repeat(startingWorkerCount) { startingUnits.add(startingWorkerName) }
|
||||
repeat(startingMilitaryUnitCount) { startingUnits.add(startingMilitaryUnit) }
|
||||
return startingUnits
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ enum class UniqueTarget(
|
||||
Tech(inheritsFrom = Global),
|
||||
Policy(inheritsFrom = Global),
|
||||
FounderBelief("Uniques for Founder and Enhancer type Beliefs, that will apply to the founder of this religion", inheritsFrom = Global),
|
||||
FollowerBelief("Uniques for Pantheon and Follower type beliefs, that will apply to each city where the religion is the majority religion"),
|
||||
FollowerBelief("Uniques for Pantheon and Follower type beliefs, that will apply to each city where the religion is the majority religion", inheritsFrom = Triggerable),
|
||||
|
||||
// City-specific
|
||||
Building(inheritsFrom = Global),
|
||||
|
@ -184,7 +184,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
|
||||
/// Resource production & consumption
|
||||
ConsumesResources("Consumes [amount] [resource]", UniqueTarget.Improvement, UniqueTarget.Building, UniqueTarget.Unit),
|
||||
ProvidesResources("Provides [amount] [resource]", UniqueTarget.Improvement, UniqueTarget.Global),
|
||||
ProvidesResources("Provides [amount] [resource]", UniqueTarget.Global, UniqueTarget.Improvement, UniqueTarget.FollowerBelief),
|
||||
CostsResources("Costs [amount] [stockpiledResource]", UniqueTarget.Improvement, UniqueTarget.Building, UniqueTarget.Unit),
|
||||
// Todo: Get rid of forced sign (+[relativeAmount]) and unify these two, e.g.: "[relativeAmount]% [resource/resourceType] production"
|
||||
// Note that the parameter type 'resourceType' (strategic, luxury, bonus) currently doesn't exist and should then be added as well
|
||||
@ -497,7 +497,7 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
TerrainGrantsPromotion("Grants [promotion] ([comment]) to adjacent [mapUnitFilter] units for the rest of the game", UniqueTarget.Terrain),
|
||||
GrantsCityStrength("[amount] Strength for cities built on this terrain", UniqueTarget.Terrain),
|
||||
ProductionBonusWhenRemoved("Provides a one-time Production bonus to the closest city when cut down", UniqueTarget.Terrain),
|
||||
Vegetation("Vegetation", UniqueTarget.Terrain, flags = UniqueFlag.setOfHiddenToUsers),
|
||||
Vegetation("Vegetation", UniqueTarget.Terrain, UniqueTarget.Improvement, flags = UniqueFlag.setOfHiddenToUsers), // Improvement included because use as tileFilter works
|
||||
|
||||
|
||||
TileProvidesYieldWithoutPopulation("Tile provides yield without assigned population", UniqueTarget.Terrain, UniqueTarget.Improvement),
|
||||
|
@ -8,9 +8,9 @@ This file defines the difficulty levels a player can choose when starting a new
|
||||
|
||||
Each difficulty level can have the following attributes:
|
||||
|
||||
| Attribute | Type | Optional | Notes |
|
||||
| --------- | ---- | -------- | ----- |
|
||||
| name | String | Required | Name of the difficulty level |
|
||||
| Attribute | Type | Optional | Notes |
|
||||
| --------- | ---- | -------- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| name | String | Required | Name of the difficulty level |
|
||||
| baseHappiness | Integer | Default 0 |
|
||||
| extraHappinessPerLuxury | Float | Default 0 |
|
||||
| researchCostModifier | Float | Default 1 |
|
||||
@ -19,7 +19,7 @@ Each difficulty level can have the following attributes:
|
||||
| policyCostModifier | Float | Default 1 |
|
||||
| unhappinessModifier | Float | Default 1 |
|
||||
| barbarianBonus | Float | Default 0 |
|
||||
| playerBonusStartingUnits | List of Units | Default empty | Can also be 'Era Starting Unit', maps to `startingMilitaryUnit` of the Eras file. All other units must be in [Units.json](4-Unit-related-JSON-files.md#Units.json)] |
|
||||
| playerBonusStartingUnits | List of Units | Default empty | Can also be 'Era Starting Unit', maps to `startingMilitaryUnit` of the Eras file. All other units must be in [Units.json](4-Unit-related-JSON-files.md#Units.json)]. Applies only to human player civs |
|
||||
| aiCityGrowthModifier | Float | Default 1 |
|
||||
| aiUnitCostModifier | Float | Default 1 |
|
||||
| aiBuildingCostModifier | Float | Default 1 |
|
||||
@ -27,10 +27,10 @@ Each difficulty level can have the following attributes:
|
||||
| aiBuildingMaintenanceModifier | Float | Default 1 |
|
||||
| aiUnitMaintenanceModifier | Float | Default 1 |
|
||||
| aiFreeTechs | List of Techs | Default empty |
|
||||
| aiMajorCivBonusStartingUnits | List of Units | Default empty | See above |
|
||||
| aiCityStateBonusStartingUnits | List of Units | Default empty | See above |
|
||||
| aiMajorCivBonusStartingUnits | List of Units | Default empty | Same rules as playerBonusStartingUnits, See above. Applies only to AI major civs |
|
||||
| aiCityStateBonusStartingUnits | List of Units | Default empty | Same rules as playerBonusStartingUnits, See above. Applies only to city-state civs |
|
||||
| aiUnhappinessModifier | Float | Default 1 |
|
||||
| aisExchangeTechs | Boolean | | Unimplemented |
|
||||
| aisExchangeTechs | Boolean | | Unimplemented |
|
||||
| turnBarbariansCanEnterPlayerTiles | Integer | Default 0 |
|
||||
| clearBarbarianCampReward | Integer | Default 25 |
|
||||
|
||||
@ -42,23 +42,25 @@ This file should contain all the era's you want to use in your mod.
|
||||
|
||||
Each era can have the following attributes:
|
||||
|
||||
| Attribute | Type | Optional | Notes |
|
||||
| --------- | ---- | -------- | ----- |
|
||||
| name | String | required | Name of the era |
|
||||
| researchAgreementCost | Integer (≥0) | defaults to 300 | Cost of research agreements were the most technologically advanced civ is in this era |
|
||||
| iconRGB | List of 3 Integers | defaults to [255, 255, 255] | RGB color that icons for technologies of this era should have in the Tech screen |
|
||||
| unitBaseBuyCost | Integer (≥0) | defaults to 200 | Base cost of buying units with Faith, Food, Science or Culture when no other cost is provided |
|
||||
| startingSettlerCount | Integer (≥0) | defaults to 1 | Amount of settler units that should be spawned when starting a game in this era |
|
||||
| startingSettlerUnit | String | defaults to "Settler" | Name of the unit that should be used for the previous field. Must be in [Units.json](4-Unit-related-JSON-files.md#unitsjson) |
|
||||
| startingWorkerCount | Integer (≥0) | defaults to 0 | Amount of worker units that should be spawned when starting a game in this era |
|
||||
| startingWorkerUnit | String | defaults to "Worker" | Name of the unit that should be used for the previous field. Must be in [Units.json](4-Unit-related-JSON-files.md#unitsjson) |
|
||||
| startingMilitaryUnitCount | Integer (≥0) | defaults to 1 | Amount of military units that should be spawned when starting a game in this era |
|
||||
| startingMilitaryUnit | String | defaults to "Warrior" | Name of the unit that should be used for the previous field. Must be in [Units.json](4-Unit-related-JSON-files.md#unitsjson)|
|
||||
| startingGold | Integer (≥0) | defaults to 0 | Amount of gold each civ should receive when starting a game in this era |
|
||||
| startingCulture | Integer (≥0) | defaults to 0 | Amount of culture each civ should receive when starting a game in this era |
|
||||
| settlerPopulation | Integer (>0) | defaults to 1 | Default amount of population each city should have when settled when starting a game in this era |
|
||||
| settlerBuildings | List of Strings | defaults to none | Buildings that should automatically be built whenever a city is settled when starting a game in this era |
|
||||
| startingObsoleteWonders | List of Strings | defaults to none | Wonders (and technically buildings) that should be impossible to built when starting a game in this era. Used in the base game to remove all wonders older than 2 era's |
|
||||
| Attribute | Type | Optional | Notes |
|
||||
| --------- | ---- | -------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| name | String | required | Name of the era |
|
||||
| researchAgreementCost | Integer (≥0) | defaults to 300 | Cost of research agreements were the most technologically advanced civ is in this era |
|
||||
| iconRGB | List of 3 Integers | defaults to [255, 255, 255] | RGB color that icons for technologies of this era should have in the Tech screen |
|
||||
| unitBaseBuyCost | Integer (≥0) | defaults to 200 | Base cost of buying units with Faith, Food, Science or Culture when no other cost is provided |
|
||||
| startingSettlerCount | Integer (≥0) | defaults to 1 | Amount of settler units that should be spawned when starting a game in this era (setting this to zero is discouraged [^1]) |
|
||||
| startingSettlerUnit | String | defaults to "Settler" | Name of the unit that should be used for the previous field. Must be in [Units.json](4-Unit-related-JSON-files.md#unitsjson), or a unit with the "Founds a new city" unique must exist |
|
||||
| startingWorkerCount | Integer (≥0) | defaults to 0 | Amount of worker units that should be spawned when starting a game in this era |
|
||||
| startingWorkerUnit | String | defaults to "Worker" | Name of the unit that should be used for the previous field. If startingWorkerCount>0, then it must exist in [Units.json](4-Unit-related-JSON-files.md#unitsjson), or a unit with the "Can build [filter] improvements on tiles" unique must exist |
|
||||
| startingMilitaryUnitCount | Integer (≥0) | defaults to 1 | Amount of military units that should be spawned when starting a game in this era |
|
||||
| startingMilitaryUnit | String | defaults to "Warrior" | Name of the unit that should be used for the previous field. Must be in [Units.json](4-Unit-related-JSON-files.md#unitsjson) |
|
||||
| startingGold | Integer (≥0) | defaults to 0 | Amount of gold each civ should receive when starting a game in this era |
|
||||
| startingCulture | Integer (≥0) | defaults to 0 | Amount of culture each civ should receive when starting a game in this era |
|
||||
| settlerPopulation | Integer (>0) | defaults to 1 | Default amount of population each city should have when settled when starting a game in this era |
|
||||
| settlerBuildings | List of Strings | defaults to none | Buildings that should automatically be built whenever a city is settled when starting a game in this era |
|
||||
| startingObsoleteWonders | List of Strings | defaults to none | Wonders (and technically buildings) that should be impossible to built when starting a game in this era. Used in the base game to remove all wonders older than 2 era's |
|
||||
|
||||
[^1]: Successfully setting startingSettlerCount to zero in a mod (idea: conquer or die) is not easy. Some player-controlled settings require at least one Settler, through any source (see difficulties for other possible settler sources), or you won't be able to start a game: Once City Challenge requires one for all players, and allowing any city-states requires one for those. Would also affect defeat rules.
|
||||
|
||||
## Speeds.json
|
||||
|
||||
|
@ -606,7 +606,7 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
|
||||
??? example "Provides [amount] [resource]"
|
||||
Example: "Provides [3] [Iron]"
|
||||
|
||||
Applicable to: Global, Improvement
|
||||
Applicable to: Global, FollowerBelief, Improvement
|
||||
|
||||
??? example "Quantity of strategic resources produced by the empire +[relativeAmount]%"
|
||||
Example: "Quantity of strategic resources produced by the empire +[+20]%"
|
||||
@ -1450,7 +1450,7 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
|
||||
Applicable to: Terrain
|
||||
|
||||
??? example "Vegetation"
|
||||
Applicable to: Terrain
|
||||
Applicable to: Terrain, Improvement
|
||||
|
||||
??? example "Tile provides yield without assigned population"
|
||||
Applicable to: Terrain, Improvement
|
||||
|
Loading…
Reference in New Issue
Block a user