Index: ps/trunk/binaries/data/mods/public/globalscripts/DamageTypes.js
===================================================================
--- ps/trunk/binaries/data/mods/public/globalscripts/DamageTypes.js
+++ ps/trunk/binaries/data/mods/public/globalscripts/DamageTypes.js
@@ -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);
-};
Index: ps/trunk/binaries/data/mods/public/globalscripts/Templates.js
===================================================================
--- ps/trunk/binaries/data/mods/public/globalscripts/Templates.js
+++ ps/trunk/binaries/data/mods/public/globalscripts/Templates.js
@@ -165,8 +165,9 @@
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 @@
"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 @@
"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 @@
"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);
}
Index: ps/trunk/binaries/data/mods/public/gui/common/tooltips.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/common/tooltips.js
+++ ps/trunk/binaries/data/mods/public/gui/common/tooltips.js
@@ -14,8 +14,6 @@
"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 @@
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 @@
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(", ")));
}
Index: ps/trunk/binaries/data/mods/public/gui/reference/common/helper.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/reference/common/helper.js
+++ ps/trunk/binaries/data/mods/public/gui/reference/common/helper.js
@@ -23,7 +23,7 @@
{
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 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)
Index: ps/trunk/binaries/data/mods/public/gui/reference/common/load.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/reference/common/load.js
+++ ps/trunk/binaries/data/mods/public/gui/reference/common/load.js
@@ -17,7 +17,6 @@
*/
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 @@
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;
Index: ps/trunk/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js
===================================================================
--- ps/trunk/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js
+++ ps/trunk/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js
@@ -262,7 +262,7 @@
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({
Index: ps/trunk/binaries/data/mods/public/maps/random/rmgen/library.js
===================================================================
--- ps/trunk/binaries/data/mods/public/maps/random/rmgen/library.js
+++ ps/trunk/binaries/data/mods/public/maps/random/rmgen/library.js
@@ -21,8 +21,6 @@
const SEA_LEVEL = 20.0;
const HEIGHT_UNITS_PER_METRE = 92;
-const g_DamageTypes = new DamageTypes();
-
/**
* Constants needed for heightmap_manipulation.js
*/
Index: ps/trunk/binaries/data/mods/public/simulation/ai/common-api/entity.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/ai/common-api/entity.js
+++ ps/trunk/binaries/data/mods/public/simulation/ai/common-api/entity.js
@@ -198,14 +198,16 @@
"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 @@
},
"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() {
Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/config.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/ai/petra/config.js
+++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/config.js
@@ -24,6 +24,14 @@
"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.
Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseArmy.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseArmy.js
+++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseArmy.js
@@ -488,7 +488,7 @@
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.
Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
+++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseManager.js
@@ -486,7 +486,7 @@
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;
Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js
+++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js
@@ -8,10 +8,11 @@
};
/** 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 @@
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 @@
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;
Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
+++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
@@ -776,13 +776,13 @@
{
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")
{
Index: ps/trunk/binaries/data/mods/public/simulation/components/Armour.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/Armour.js
+++ ps/trunk/binaries/data/mods/public/simulation/components/Armour.js
@@ -7,11 +7,11 @@
"0.0" +
"5.0" +
"" +
- DamageTypes.BuildSchema("damage protection") +
+ BuildDamageTypesSchema("damage protection") +
"" +
"" +
"" +
- DamageTypes.BuildSchema("damage protection") +
+ BuildDamageTypesSchema("damage protection") +
"" +
"" +
"";
@@ -59,9 +59,9 @@
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 @@
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;
};
Index: ps/trunk/binaries/data/mods/public/simulation/components/Attack.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/Attack.js
+++ ps/trunk/binaries/data/mods/public/simulation/components/Attack.js
@@ -131,7 +131,7 @@
"" +
"" +
"" +
- DamageTypes.BuildSchema("damage strength") +
+ BuildDamageTypesSchema("damage strength") +
"" +
"" +
"" +
@@ -150,7 +150,7 @@
"" +
"" +
"" +
- DamageTypes.BuildSchema("damage strength") +
+ BuildDamageTypesSchema("damage strength") +
"" +
"" +
"" +
@@ -180,7 +180,7 @@
"" +
"" +
"" +
- DamageTypes.BuildSchema("damage strength") +
+ BuildDamageTypesSchema("damage strength") +
"" +
Attack.prototype.bonusesSchema +
"" +
@@ -242,7 +242,7 @@
"" +
"" +
"" +
- DamageTypes.BuildSchema("damage strength") +
+ BuildDamageTypesSchema("damage strength") +
"" +
"" + // TODO: how do these work?
Attack.prototype.bonusesSchema +
@@ -470,7 +470,7 @@
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;
Index: ps/trunk/binaries/data/mods/public/simulation/components/DeathDamage.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/DeathDamage.js
+++ ps/trunk/binaries/data/mods/public/simulation/components/DeathDamage.js
@@ -34,7 +34,7 @@
"" +
"" +
"" +
- DamageTypes.BuildSchema("damage strength") +
+ BuildDamageTypesSchema("damage strength") +
"" +
DeathDamage.prototype.bonusesSchema;
@@ -51,7 +51,7 @@
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;
Index: ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js
+++ ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js
@@ -547,14 +547,14 @@
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)
Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_UpgradeModification.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_UpgradeModification.js
+++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_UpgradeModification.js
@@ -126,11 +126,11 @@
* 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 @@
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...
Index: ps/trunk/binaries/data/mods/public/simulation/helpers/DamageTypes.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/helpers/DamageTypes.js
+++ ps/trunk/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);