From 6643613b545ce56975fc4aa5669c387c3b0142aa Mon Sep 17 00:00:00 2001 From: wraitii Date: Mon, 22 Jul 2019 18:37:18 +0000 Subject: [PATCH] Easier introduction of new damage types. 725aa8a686 introduced a DamageTypes.js global script similar to the resources one. However, we never actually need to refer to this script since we can always use the damage types provided by the template/context/object we are looping over/... There is one exception to this for AI weighting of damage types. However, since damage types are not stored in files, this is strictly equivalent to hardcoding them in the global script and was deemed acceptable. Patch By: freagarach Reviewed By: wraitii Refs #4801 (by invalidating it for now, though such helper files might be useful in the future if damage types require more metadata). Differential Revision: https://code.wildfiregames.com/D1938 This was SVN commit r22527. --- .../mods/public/globalscripts/DamageTypes.js | 22 ----------- .../mods/public/globalscripts/Templates.js | 11 +++--- .../data/mods/public/gui/common/tooltips.js | 9 ++--- .../public/gui/reference/common/helper.js | 6 +-- .../mods/public/gui/reference/common/load.js | 3 +- .../maps/random/rmgen-common/wall_builder.js | 2 +- .../mods/public/maps/random/rmgen/library.js | 2 - .../public/simulation/ai/common-api/entity.js | 27 +++++++------ .../mods/public/simulation/ai/petra/config.js | 8 ++++ .../public/simulation/ai/petra/defenseArmy.js | 2 +- .../simulation/ai/petra/defenseManager.js | 2 +- .../simulation/ai/petra/entityExtend.js | 39 +++++-------------- .../simulation/ai/petra/headquarters.js | 8 ++-- .../public/simulation/components/Armour.js | 17 ++++---- .../public/simulation/components/Attack.js | 10 ++--- .../simulation/components/DeathDamage.js | 4 +- .../simulation/components/GuiInterface.js | 4 +- .../tests/test_UpgradeModification.js | 8 ++-- .../public/simulation/helpers/DamageTypes.js | 26 ++++++++++--- 19 files changed, 95 insertions(+), 115 deletions(-) delete mode 100644 binaries/data/mods/public/globalscripts/DamageTypes.js diff --git a/binaries/data/mods/public/globalscripts/DamageTypes.js b/binaries/data/mods/public/globalscripts/DamageTypes.js deleted file mode 100644 index 4012a42be7..0000000000 --- a/binaries/data/mods/public/globalscripts/DamageTypes.js +++ /dev/null @@ -1,22 +0,0 @@ -function DamageTypes() -{ - // TODO: load these from files - - this.names = { - "Hack": markForTranslationWithContext("damage type", "Hack"), - "Pierce": markForTranslationWithContext("damage type", "Pierce"), - "Crush": markForTranslationWithContext("damage type", "Crush"), - }; - - deepfreeze(this.names); -} - -DamageTypes.prototype.GetNames = function() -{ - return this.names; -}; - -DamageTypes.prototype.GetTypes = function() -{ - return Object.keys(this.names); -}; diff --git a/binaries/data/mods/public/globalscripts/Templates.js b/binaries/data/mods/public/globalscripts/Templates.js index 083f3cca79..ea1dc89246 100644 --- a/binaries/data/mods/public/globalscripts/Templates.js +++ b/binaries/data/mods/public/globalscripts/Templates.js @@ -165,8 +165,9 @@ function GetTemplateDataHelper(template, player, auraTemplates, resources, damag if (template.Armour) { ret.armour = {}; - for (let damageType of damageTypes.GetTypes()) - ret.armour[damageType] = getEntityValue("Armour/" + damageType); + for (let damageType in template.Armour) + if (damageType != "Foundation") + ret.armour[damageType] = getEntityValue("Armour/" + damageType); } if (template.Attack) @@ -190,7 +191,7 @@ function GetTemplateDataHelper(template, player, auraTemplates, resources, damag "elevationBonus": getAttackStat("ElevationBonus"), "damage": {} }; - for (let damageType of damageTypes.GetTypes()) + for (let damageType in template.Attack[type].Damage) ret.attack[type].damage[damageType] = getAttackStat("Damage/" + damageType); ret.attack[type].elevationAdaptedRange = Math.sqrt(ret.attack[type].maxRange * @@ -206,7 +207,7 @@ function GetTemplateDataHelper(template, player, auraTemplates, resources, damag "shape": template.Attack[type].Splash.Shape, "damage": {} }; - for (let damageType of damageTypes.GetTypes()) + for (let damageType in template.Attack[type].Splash.Damage) ret.attack[type].splash.damage[damageType] = getAttackStat("Splash/Damage/" + damageType); } } @@ -218,7 +219,7 @@ function GetTemplateDataHelper(template, player, auraTemplates, resources, damag "friendlyFire": template.DeathDamage.FriendlyFire != "false", "damage": {} }; - for (let damageType of damageTypes.GetTypes()) + for (let damageType in template.DeathDamage.Damage) ret.deathDamage.damage[damageType] = getEntityValue("DeathDamage/Damage/" + damageType); } diff --git a/binaries/data/mods/public/gui/common/tooltips.js b/binaries/data/mods/public/gui/common/tooltips.js index 55a917c399..51b6a22e61 100644 --- a/binaries/data/mods/public/gui/common/tooltips.js +++ b/binaries/data/mods/public/gui/common/tooltips.js @@ -14,8 +14,6 @@ var g_AttackTypes = { "Capture": translate("Capture Attack:") }; -var g_DamageTypes = new DamageTypes(); - var g_SplashDamageTypes = { "Circular": translate("Circular Splash Damage"), "Linear": translate("Linear Splash Damage") @@ -222,7 +220,7 @@ function getArmorTooltip(template) Object.keys(template.armour).map( dmgType => sprintf(translate("%(damage)s %(damageType)s %(armorPercentage)s"), { "damage": template.armour[dmgType].toFixed(1), - "damageType": unitFont(translateWithContext("damage type", g_DamageTypes.GetNames()[dmgType])), + "damageType": unitFont(translateWithContext("damage type", dmgType)), "armorPercentage": '[font="sans-10"]' + sprintf(translate("(%(armorPercentage)s)"), { @@ -238,11 +236,10 @@ function damageTypesToText(dmg) if (!dmg) return '[font="sans-12"]' + translate("(None)") + '[/font]'; - return g_DamageTypes.GetTypes().filter( - dmgType => dmg[dmgType]).map( + return Object.keys(dmg).filter(dmgType => dmg[dmgType]).map( dmgType => sprintf(translate("%(damage)s %(damageType)s"), { "damage": dmg[dmgType].toFixed(1), - "damageType": unitFont(translateWithContext("damage type", g_DamageTypes.GetNames()[dmgType])) + "damageType": unitFont(translateWithContext("damage type", dmgType)) })).join(commaFont(translate(", "))); } diff --git a/binaries/data/mods/public/gui/reference/common/helper.js b/binaries/data/mods/public/gui/reference/common/helper.js index 5e84a1ef74..304780acdd 100644 --- a/binaries/data/mods/public/gui/reference/common/helper.js +++ b/binaries/data/mods/public/gui/reference/common/helper.js @@ -23,7 +23,7 @@ function getActualUpgradeData(upgradesInfo) { upgrade.entity = upgrade.entity.replace(/\{(civ|native)\}/g, g_SelectedCiv); - let data = GetTemplateDataHelper(loadTemplate(upgrade.entity), null, g_AuraData, g_ResourceData, g_DamageTypes); + let data = GetTemplateDataHelper(loadTemplate(upgrade.entity), null, g_AuraData, g_ResourceData); data.name.internal = upgrade.entity; data.cost = upgrade.cost; data.icon = upgrade.icon || data.icon; @@ -124,8 +124,8 @@ function getPhaseOfTemplate(template) */ function GetTemplateData(templateName) { - var template = loadTemplate(templateName); - return GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData, g_DamageTypes, g_CurrentModifiers); + let template = loadTemplate(templateName); + return GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData, g_CurrentModifiers); } function isPairTech(technologyCode) diff --git a/binaries/data/mods/public/gui/reference/common/load.js b/binaries/data/mods/public/gui/reference/common/load.js index 50fc741275..442dcdd063 100644 --- a/binaries/data/mods/public/gui/reference/common/load.js +++ b/binaries/data/mods/public/gui/reference/common/load.js @@ -17,7 +17,6 @@ var g_CivData = loadCivData(true, false); */ var g_ParsedData = {}; var g_ResourceData = new Resources(); -var g_DamageTypes = new DamageTypes(); // This must be defined after the g_TechnologyData cache object is declared. var g_AutoResearchTechList = findAllAutoResearchedTechs(); @@ -110,7 +109,7 @@ function loadEntityTemplate(templateName) return null; let template = loadTemplate(templateName); - let parsed = GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData, g_DamageTypes, g_CurrentModifiers); + let parsed = GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData, g_CurrentModifiers); parsed.name.internal = templateName; parsed.history = template.Identity.History; diff --git a/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js b/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js index 2c9684e0ae..d97cd08f22 100644 --- a/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js +++ b/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js @@ -262,7 +262,7 @@ function getWallElement(element, style) function readyWallElement(path, civCode) { path = path.replace(/\{civ\}/g, civCode); - let template = GetTemplateDataHelper(Engine.GetTemplate(path), null, null, {}, g_DamageTypes, {}); + let template = GetTemplateDataHelper(Engine.GetTemplate(path), null, null, {}, {}); let length = template.wallPiece ? template.wallPiece.length : template.obstruction.shape.width; return deepfreeze({ diff --git a/binaries/data/mods/public/maps/random/rmgen/library.js b/binaries/data/mods/public/maps/random/rmgen/library.js index 9d22cb9797..e958316e12 100644 --- a/binaries/data/mods/public/maps/random/rmgen/library.js +++ b/binaries/data/mods/public/maps/random/rmgen/library.js @@ -21,8 +21,6 @@ const TERRAIN_SEPARATOR = "|"; const SEA_LEVEL = 20.0; const HEIGHT_UNITS_PER_METRE = 92; -const g_DamageTypes = new DamageTypes(); - /** * Constants needed for heightmap_manipulation.js */ diff --git a/binaries/data/mods/public/simulation/ai/common-api/entity.js b/binaries/data/mods/public/simulation/ai/common-api/entity.js index 8b54a71f32..a5e0f0bd3f 100644 --- a/binaries/data/mods/public/simulation/ai/common-api/entity.js +++ b/binaries/data/mods/public/simulation/ai/common-api/entity.js @@ -198,14 +198,16 @@ m.Template = m.Class({ "getPopulationBonus": function() { return +this.get("Cost/PopulationBonus"); }, "armourStrengths": function() { - if (!this.get("Armour")) + let armourDamageTypes = this.get("Armour"); + if (!armourDamageTypes) return undefined; - return { - "Hack": +this.get("Armour/Hack"), - "Pierce": +this.get("Armour/Pierce"), - "Crush": +this.get("Armour/Crush") - }; + let armour = {}; + for (let damageType in armourDamageTypes) + if (damageType != "Foundation") + armour[damageType] = +armourDamageTypes[damageType]; + + return armour; }, "attackTypes": function() { @@ -229,14 +231,15 @@ m.Template = m.Class({ }, "attackStrengths": function(type) { - if (!this.get("Attack/" + type +"")) + let attackDamageTypes = this.get("Attack/" + type + "/Damage"); + if (!attackDamageTypes) return undefined; - return { - "Hack": +(this.get("Attack/" + type + "/Damage/Hack") || 0), - "Pierce": +(this.get("Attack/" + type + "/Damage/Pierce") || 0), - "Crush": +(this.get("Attack/" + type + "/Damage/Crush") || 0) - }; + let damage = {}; + for (let damageType in attackDamageTypes) + damage[damageType] = +attackDamageTypes[damageType]; + + return damage; }, "captureStrength": function() { diff --git a/binaries/data/mods/public/simulation/ai/petra/config.js b/binaries/data/mods/public/simulation/ai/petra/config.js index 77e4b56bfd..957d9979e6 100644 --- a/binaries/data/mods/public/simulation/ai/petra/config.js +++ b/binaries/data/mods/public/simulation/ai/petra/config.js @@ -24,6 +24,14 @@ m.Config = function(difficulty, behavior) "popForBlacksmith": 65, "numSentryTowers": 1 }; + + // Define damage type importance factors here. + this.DamageTypeImportance = { + "Hack": 0.085, + "Pierce": 0.075, + "Crush": 0.065 + }; + this.Economy = { "popPhase2": 38, // How many units we want before aging to phase2. "workPhase3": 65, // How many workers we want before aging to phase3. diff --git a/binaries/data/mods/public/simulation/ai/petra/defenseArmy.js b/binaries/data/mods/public/simulation/ai/petra/defenseArmy.js index a5be2f2d17..2c85851c33 100644 --- a/binaries/data/mods/public/simulation/ai/petra/defenseArmy.js +++ b/binaries/data/mods/public/simulation/ai/petra/defenseArmy.js @@ -488,7 +488,7 @@ m.DefenseArmy.prototype.evaluateStrength = function(ent, isOwn, remove) entStrength = 2; } else - entStrength = m.getMaxStrength(ent); + entStrength = m.getMaxStrength(ent, this.Config.debug, this.Config.DamageTypeImportance); // TODO adapt the getMaxStrength function for animals. // For the time being, just increase it for elephants as the returned value is too small. diff --git a/binaries/data/mods/public/simulation/ai/petra/defenseManager.js b/binaries/data/mods/public/simulation/ai/petra/defenseManager.js index b458d129b4..047aab5587 100644 --- a/binaries/data/mods/public/simulation/ai/petra/defenseManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/defenseManager.js @@ -486,7 +486,7 @@ m.DefenseManager.prototype.assignDefenders = function(gameState) else if (aMin === undefined) continue; - armiesNeeding[aMin].need -= m.getMaxStrength(ent); + armiesNeeding[aMin].need -= m.getMaxStrength(ent, this.Config.debug, this.Config.DamageTypeImportance); armiesNeeding[aMin].army.addOwn(gameState, potentialDefenders[i]); armiesNeeding[aMin].army.assignUnit(gameState, potentialDefenders[i]); potentialDefenders[i] = undefined; diff --git a/binaries/data/mods/public/simulation/ai/petra/entityExtend.js b/binaries/data/mods/public/simulation/ai/petra/entityExtend.js index 3edbdbfc30..ab4af81552 100644 --- a/binaries/data/mods/public/simulation/ai/petra/entityExtend.js +++ b/binaries/data/mods/public/simulation/ai/petra/entityExtend.js @@ -8,10 +8,11 @@ m.isSiegeUnit = function(ent) }; /** returns some sort of DPS * health factor. If you specify a class, it'll use the modifiers against that class too. */ -m.getMaxStrength = function(ent, againstClass) +m.getMaxStrength = function(ent, debugLevel, DamageTypeImportance, againstClass) { let strength = 0; let attackTypes = ent.attackTypes(); + let damageTypes = Object.keys(DamageTypeImportance); if (!attackTypes) return strength; @@ -26,20 +27,10 @@ m.getMaxStrength = function(ent, againstClass) let val = parseFloat(attackStrength[str]); if (againstClass) val *= ent.getMultiplierAgainst(type, againstClass); - switch (str) - { - case "Crush": - strength += val * 0.085 / 3; - break; - case "Hack": - strength += val * 0.075 / 3; - break; - case "Pierce": - strength += val * 0.065 / 3; - break; - default: - API3.warn("Petra: " + str + " unknown attackStrength in getMaxStrength"); - } + if (DamageTypeImportance[str]) + strength += DamageTypeImportance[str] * val / damageTypes.length; + else if (debugLevel > 0) + API3.warn("Petra: " + str + " unknown attackStrength in getMaxStrength (please add " + str + " to config.js)."); } let attackRange = ent.attackRange(type); @@ -68,20 +59,10 @@ m.getMaxStrength = function(ent, againstClass) for (let str in armourStrength) { let val = parseFloat(armourStrength[str]); - switch (str) - { - case "Crush": - strength += val * 0.085 / 3; - break; - case "Hack": - strength += val * 0.075 / 3; - break; - case "Pierce": - strength += val * 0.065 / 3; - break; - default: - API3.warn("Petra: " + str + " unknown armourStrength in getMaxStrength"); - } + if (DamageTypeImportance[str]) + strength += DamageTypeImportance[str] * val / damageTypes.length; + else if (debugLevel > 0) + API3.warn("Petra: " + str + " unknown armourStrength in getMaxStrength (please add " + str + " to config.js)."); } return strength * ent.maxHitpoints() / 100.0; diff --git a/binaries/data/mods/public/simulation/ai/petra/headquarters.js b/binaries/data/mods/public/simulation/ai/petra/headquarters.js index 1c08ee9bf4..66ecc89b2c 100644 --- a/binaries/data/mods/public/simulation/ai/petra/headquarters.js +++ b/binaries/data/mods/public/simulation/ai/petra/headquarters.js @@ -776,13 +776,13 @@ m.HQ.prototype.findBestTrainableUnit = function(gameState, classes, requirements { if (param[0] == "strength") { - aValue += m.getMaxStrength(a[1]) * param[1]; - bValue += m.getMaxStrength(b[1]) * param[1]; + aValue += m.getMaxStrength(a[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance) * param[1]; + bValue += m.getMaxStrength(b[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance) * param[1]; } else if (param[0] == "siegeStrength") { - aValue += m.getMaxStrength(a[1], "Structure") * param[1]; - bValue += m.getMaxStrength(b[1], "Structure") * param[1]; + aValue += m.getMaxStrength(a[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance, "Structure") * param[1]; + bValue += m.getMaxStrength(b[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance, "Structure") * param[1]; } else if (param[0] == "speed") { diff --git a/binaries/data/mods/public/simulation/components/Armour.js b/binaries/data/mods/public/simulation/components/Armour.js index bef3ea59f5..42fdc4b682 100644 --- a/binaries/data/mods/public/simulation/components/Armour.js +++ b/binaries/data/mods/public/simulation/components/Armour.js @@ -7,11 +7,11 @@ Armour.prototype.Schema = "0.0" + "5.0" + "" + - DamageTypes.BuildSchema("damage protection") + + BuildDamageTypesSchema("damage protection") + "" + "" + "" + - DamageTypes.BuildSchema("damage protection") + + BuildDamageTypesSchema("damage protection") + "" + "" + ""; @@ -59,9 +59,9 @@ Armour.prototype.TakeDamage = function(strengths, multiplier = 1) Armour.prototype.GetArmourStrengths = function() { - // Work out the armour values with technology effects - var applyMods = (type, foundation) => { - var strength; + // Work out the armour values with technology effects. + let applyMods = (type, foundation) => { + let strength; if (foundation) { strength = +this.template.Foundation[type]; @@ -73,11 +73,12 @@ Armour.prototype.GetArmourStrengths = function() return ApplyValueModificationsToEntity("Armour/" + type, strength, this.entity); }; - var foundation = Engine.QueryInterface(this.entity, IID_Foundation) && this.template.Foundation; + let foundation = Engine.QueryInterface(this.entity, IID_Foundation) && this.template.Foundation; let ret = {}; - for (let damageType of DamageTypes.GetTypes()) - ret[damageType] = applyMods(damageType, foundation); + for (let damageType in this.template) + if (damageType != "Foundation") + ret[damageType] = applyMods(damageType, foundation); return ret; }; diff --git a/binaries/data/mods/public/simulation/components/Attack.js b/binaries/data/mods/public/simulation/components/Attack.js index b259bbe4d8..4f8f74a29a 100644 --- a/binaries/data/mods/public/simulation/components/Attack.js +++ b/binaries/data/mods/public/simulation/components/Attack.js @@ -131,7 +131,7 @@ Attack.prototype.Schema = "" + "" + "" + - DamageTypes.BuildSchema("damage strength") + + BuildDamageTypesSchema("damage strength") + "" + "" + "" + @@ -150,7 +150,7 @@ Attack.prototype.Schema = "" + "" + "" + - DamageTypes.BuildSchema("damage strength") + + BuildDamageTypesSchema("damage strength") + "" + "" + "" + @@ -180,7 +180,7 @@ Attack.prototype.Schema = "" + "" + "" + - DamageTypes.BuildSchema("damage strength") + + BuildDamageTypesSchema("damage strength") + "" + Attack.prototype.bonusesSchema + "" + @@ -242,7 +242,7 @@ Attack.prototype.Schema = "" + "" + "" + - DamageTypes.BuildSchema("damage strength") + + BuildDamageTypesSchema("damage strength") + "" + "" + // TODO: how do these work? Attack.prototype.bonusesSchema + @@ -470,7 +470,7 @@ Attack.prototype.GetAttackStrengths = function(type) return { "value": ApplyValueModificationsToEntity("Attack/Capture/Value", +(template.Value || 0), this.entity) }; let ret = {}; - for (let damageType of DamageTypes.GetTypes()) + for (let damageType in template.Damage) ret[damageType] = applyMods(damageType); return ret; diff --git a/binaries/data/mods/public/simulation/components/DeathDamage.js b/binaries/data/mods/public/simulation/components/DeathDamage.js index d0f26864a7..1248679655 100644 --- a/binaries/data/mods/public/simulation/components/DeathDamage.js +++ b/binaries/data/mods/public/simulation/components/DeathDamage.js @@ -34,7 +34,7 @@ DeathDamage.prototype.Schema = "" + "" + "" + - DamageTypes.BuildSchema("damage strength") + + BuildDamageTypesSchema("damage strength") + "" + DeathDamage.prototype.bonusesSchema; @@ -51,7 +51,7 @@ DeathDamage.prototype.GetDeathDamageStrengths = function() ApplyValueModificationsToEntity("DeathDamage/Damage/" + damageType, +(this.template.Damage[damageType] || 0), this.entity); let ret = {}; - for (let damageType of DamageTypes.GetTypes()) + for (let damageType in this.template.Damage) ret[damageType] = applyMods(damageType); return ret; diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js index f58aa8a530..fd3421fedb 100644 --- a/binaries/data/mods/public/simulation/components/GuiInterface.js +++ b/binaries/data/mods/public/simulation/components/GuiInterface.js @@ -547,14 +547,14 @@ GuiInterface.prototype.GetTemplateData = function(player, templateName) let aurasTemplate = {}; if (!template.Auras) - return GetTemplateDataHelper(template, player, aurasTemplate, Resources, DamageTypes); + return GetTemplateDataHelper(template, player, aurasTemplate, Resources); let auraNames = template.Auras._string.split(/\s+/); for (let name of auraNames) aurasTemplate[name] = AuraTemplates.Get(name); - return GetTemplateDataHelper(template, player, aurasTemplate, Resources, DamageTypes); + return GetTemplateDataHelper(template, player, aurasTemplate, Resources); }; GuiInterface.prototype.IsTechnologyResearched = function(player, data) diff --git a/binaries/data/mods/public/simulation/components/tests/test_UpgradeModification.js b/binaries/data/mods/public/simulation/components/tests/test_UpgradeModification.js index 2eb3fd615c..3d7a6e1ce1 100644 --- a/binaries/data/mods/public/simulation/components/tests/test_UpgradeModification.js +++ b/binaries/data/mods/public/simulation/components/tests/test_UpgradeModification.js @@ -126,11 +126,11 @@ cmpUpgrade.owner = playerID; * To start with, no techs are researched... */ // T1: Check the cost of the upgrade without a player value being passed (as it would be in the structree). -let parsed_template = GetTemplateDataHelper(template, null, {}, Resources, DamageTypes); +let parsed_template = GetTemplateDataHelper(template, null, {}, Resources); TS_ASSERT_UNEVAL_EQUALS(parsed_template.upgrades[0].cost, { "stone": 100, "wood": 50, "time": 100 }); // T2: Check the value, with a player ID (as it would be in-session). -parsed_template = GetTemplateDataHelper(template, playerID, {}, Resources, DamageTypes); +parsed_template = GetTemplateDataHelper(template, playerID, {}, Resources); TS_ASSERT_UNEVAL_EQUALS(parsed_template.upgrades[0].cost, { "stone": 100, "wood": 50, "time": 100 }); // T3: Check that the value is correct within the Update Component. @@ -144,11 +144,11 @@ cmpUpgrade.Upgrade("structures/"+civCode+"_defense_tower"); isResearched = true; // T4: Check that the player-less value hasn't increased... -parsed_template = GetTemplateDataHelper(template, null, {}, Resources, DamageTypes); +parsed_template = GetTemplateDataHelper(template, null, {}, Resources); TS_ASSERT_UNEVAL_EQUALS(parsed_template.upgrades[0].cost, { "stone": 100, "wood": 50, "time": 100 }); // T5: ...but the player-backed value has. -parsed_template = GetTemplateDataHelper(template, playerID, {}, Resources, DamageTypes); +parsed_template = GetTemplateDataHelper(template, playerID, {}, Resources); TS_ASSERT_UNEVAL_EQUALS(parsed_template.upgrades[0].cost, { "stone": 160, "wood": 25, "time": 90 }); // T6: The upgrade component should still be using the old resource cost (but new time cost) for the upgrade in progress... diff --git a/binaries/data/mods/public/simulation/helpers/DamageTypes.js b/binaries/data/mods/public/simulation/helpers/DamageTypes.js index fabd6d8b45..891c94efaf 100644 --- a/binaries/data/mods/public/simulation/helpers/DamageTypes.js +++ b/binaries/data/mods/public/simulation/helpers/DamageTypes.js @@ -1,8 +1,22 @@ -DamageTypes.prototype.BuildSchema = function(helptext = "") +/** + * Builds a RelaxRNG schema based on currently valid elements. + * + * To prevent validation errors, disabled damage types are included in the schema. + * + * @param {string} helptext - Text displayed as help + * @return {string} - RelaxNG schema string + */ +function BuildDamageTypesSchema(helptext = "") { - return "" + this.GetTypes().reduce((schema, type) => - schema + "", - "") + ""; -}; + return "" + + "" + + "" + + // Armour requires Foundation to not be a damage type. + "Foundation" + + "" + + "" + + "" + + ""; +} -DamageTypes = new DamageTypes(); +Engine.RegisterGlobal("BuildDamageTypesSchema", BuildDamageTypesSchema);