From bc3f1341e125540bf902bcf626596f52855ff1db Mon Sep 17 00:00:00 2001 From: SeventhM <127357473+SeventhM@users.noreply.github.com> Date: Sat, 24 Jun 2023 23:34:23 -0700 Subject: [PATCH] Tech column validation and removing crashes from undefined building costs (#9664) * Add in tech column validation * Negative Columns * Forgot to add techColumns to the add and clear functiond * Remove restrictive cokumn check * bugfixing --- .../assets/jsons/Civ V - Gods & Kings/Techs.json | 1 + android/assets/jsons/Civ V - Vanilla/Techs.json | 1 + core/src/com/unciv/models/ruleset/Ruleset.kt | 9 +++++++-- .../com/unciv/models/ruleset/RulesetValidator.kt | 16 +++++++++++++--- .../com/unciv/models/ruleset/tech/TechColumn.kt | 4 ++-- .../com/unciv/models/ruleset/unit/BaseUnit.kt | 2 +- 6 files changed, 25 insertions(+), 8 deletions(-) diff --git a/android/assets/jsons/Civ V - Gods & Kings/Techs.json b/android/assets/jsons/Civ V - Gods & Kings/Techs.json index a4b96f76d1..07fee47ebf 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/Techs.json +++ b/android/assets/jsons/Civ V - Gods & Kings/Techs.json @@ -4,6 +4,7 @@ "era": "Ancient era", "techCost": 20, "buildingCost": 40, + "wonderCost": 185, "techs": [ { "name": "Agriculture", diff --git a/android/assets/jsons/Civ V - Vanilla/Techs.json b/android/assets/jsons/Civ V - Vanilla/Techs.json index fed4aa3e42..a9a0d285ec 100644 --- a/android/assets/jsons/Civ V - Vanilla/Techs.json +++ b/android/assets/jsons/Civ V - Vanilla/Techs.json @@ -4,6 +4,7 @@ "era": "Ancient era", "techCost": 20, "buildingCost": 40, + "wonderCost": 185, "techs": [ { "name": "Agriculture", diff --git a/core/src/com/unciv/models/ruleset/Ruleset.kt b/core/src/com/unciv/models/ruleset/Ruleset.kt index 655f122ec0..58bc756233 100644 --- a/core/src/com/unciv/models/ruleset/Ruleset.kt +++ b/core/src/com/unciv/models/ruleset/Ruleset.kt @@ -91,6 +91,7 @@ class Ruleset { val quests = LinkedHashMap() val specialists = LinkedHashMap() val technologies = LinkedHashMap() + val techColumns = ArrayList() val terrains = LinkedHashMap() val tileImprovements = LinkedHashMap() val tileResources = LinkedHashMap() @@ -152,6 +153,7 @@ class Ruleset { technologies.remove(it) } technologies.putAll(ruleset.technologies) + techColumns.addAll(ruleset.techColumns) terrains.putAll(ruleset.terrains) tileImprovements.putAll(ruleset.tileImprovements) tileResources.putAll(ruleset.tileResources) @@ -212,6 +214,7 @@ class Ruleset { ruinRewards.clear() specialists.clear() technologies.clear() + techColumns.clear() terrains.clear() tileImprovements.clear() tileResources.clear() @@ -264,6 +267,7 @@ class Ruleset { if (techFile.exists()) { val techColumns = json().fromJsonFile(Array::class.java, techFile) for (techColumn in techColumns) { + this.techColumns.add(techColumn) for (tech in techColumn.techs) { if (tech.cost == 0) tech.cost = techColumn.techCost tech.column = techColumn @@ -458,8 +462,9 @@ class Ruleset { for (building in buildings.values) { if (building.cost == -1 && building.getMatchingUniques(UniqueType.Unbuildable).none { it.conditionals.isEmpty() }) { val column = technologies[building.requiredTech]?.column - ?: throw UncivShowableException("Building '[${building.name}]' is buildable and therefore must either have an explicit cost or reference an existing tech.") - building.cost = if (building.isAnyWonder()) column.wonderCost else column.buildingCost + if (column != null) { + building.cost = if (building.isAnyWonder()) column.wonderCost else column.buildingCost + } } } } diff --git a/core/src/com/unciv/models/ruleset/RulesetValidator.kt b/core/src/com/unciv/models/ruleset/RulesetValidator.kt index 54f82c3c0e..3fe007e69b 100644 --- a/core/src/com/unciv/models/ruleset/RulesetValidator.kt +++ b/core/src/com/unciv/models/ruleset/RulesetValidator.kt @@ -51,17 +51,27 @@ class RulesetValidator(val ruleset: Ruleset) { for (tech in ruleset.technologies.values) { for (otherTech in ruleset.technologies.values) { - if (tech != otherTech && otherTech.column == tech.column && otherTech.row == tech.row) - lines += "${tech.name} is in the same row as ${otherTech.name}!" + if (tech != otherTech && otherTech.column?.columnNumber == tech.column?.columnNumber && otherTech.row == tech.row) + lines += "${tech.name} is in the same row and column as ${otherTech.name}!" } checkUniques(tech, lines, rulesetInvariant, tryFixUnknownUniques) } + for (techColumn in ruleset.techColumns){ + if (techColumn.columnNumber < 0) + lines+= "Tech Column number ${techColumn.columnNumber} is negative" + if (techColumn.buildingCost == -1) + lines.add("Tech Column number ${techColumn.columnNumber} has no explicit building cost", RulesetErrorSeverity.Warning) + if (techColumn.wonderCost == -1) + lines.add("Tech Column number ${techColumn.columnNumber} has no explicit wonder cost", RulesetErrorSeverity.Warning) + } + for (building in ruleset.buildings.values) { if (building.requiredTech == null && building.cost == -1 && !building.hasUnique( UniqueType.Unbuildable)) - lines += "${building.name} is buildable and therefore must either have an explicit cost or reference an existing tech!" + lines.add("${building.name} is buildable and therefore should either have an explicit cost or reference an existing tech!", + RulesetErrorSeverity.Warning) checkUniques(building, lines, rulesetInvariant, tryFixUnknownUniques) diff --git a/core/src/com/unciv/models/ruleset/tech/TechColumn.kt b/core/src/com/unciv/models/ruleset/tech/TechColumn.kt index 3aebef7c1f..d96d912c89 100644 --- a/core/src/com/unciv/models/ruleset/tech/TechColumn.kt +++ b/core/src/com/unciv/models/ruleset/tech/TechColumn.kt @@ -5,6 +5,6 @@ class TechColumn { lateinit var era: String var techs = ArrayList() var techCost: Int = 0 - var buildingCost: Int = 0 - var wonderCost: Int = 0 + var buildingCost: Int = -1 + var wonderCost: Int = -1 } diff --git a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt index 3417eedeb5..f38e85d3d5 100644 --- a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt @@ -27,7 +27,7 @@ import kotlin.math.pow in contrast to MapUnit, which is a specific unit of a certain type that appears on the map */ class BaseUnit : RulesetObject(), INonPerpetualConstruction { - override var cost: Int = 0 + override var cost: Int = -1 override var hurryCostModifier: Int = 0 var movement: Int = 0 var strength: Int = 0