mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Move damage types definition to a new helper similar to how resources are handled.
This should make adding new damage types a little easier, however such an extension would still need changes to the AI, and to all templates that have Armour, Attack, or DeathDamage. Reviewed By: elexis Differential Revision: https://code.wildfiregames.com/D866 This was SVN commit r20203.
This commit is contained in:
parent
2e02c88d2c
commit
725aa8a686
16 changed files with 116 additions and 106 deletions
22
binaries/data/mods/public/globalscripts/DamageTypes.js
Normal file
22
binaries/data/mods/public/globalscripts/DamageTypes.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
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);
|
||||
};
|
||||
|
|
@ -117,11 +117,12 @@ function GetModifiedTemplateDataValue(template, value_path, mod_key, player, mod
|
|||
* of properties.
|
||||
* @param {object} auraTemplates - In the form of { key: { "auraName": "", "auraDescription": "" } }.
|
||||
* @param {object} resources - An instance of the Resources prototype.
|
||||
* @param {object} damageTypes - An instance of the DamageTypes prototype.
|
||||
* @param {object} modifiers - Modifications from auto-researched techs, unit upgrades
|
||||
* etc. Optional as only used if there's no player
|
||||
* id provided.
|
||||
*/
|
||||
function GetTemplateDataHelper(template, player, auraTemplates, resources, modifiers={})
|
||||
function GetTemplateDataHelper(template, player, auraTemplates, resources, damageTypes, modifiers={})
|
||||
{
|
||||
// Return data either from template (in tech tree) or sim state (ingame).
|
||||
// @param {string} value_path - Route to the value within the template.
|
||||
|
|
@ -133,11 +134,11 @@ function GetTemplateDataHelper(template, player, auraTemplates, resources, modif
|
|||
let ret = {};
|
||||
|
||||
if (template.Armour)
|
||||
ret.armour = {
|
||||
"hack": getEntityValue("Armour/Hack"),
|
||||
"pierce": getEntityValue("Armour/Pierce"),
|
||||
"crush": getEntityValue("Armour/Crush")
|
||||
};
|
||||
{
|
||||
ret.armour = {};
|
||||
for (let damageType of damageTypes.GetTypes())
|
||||
ret.armour[damageType] = getEntityValue("Armour/" + damageType);
|
||||
}
|
||||
|
||||
if (template.Attack)
|
||||
{
|
||||
|
|
@ -155,38 +156,38 @@ function GetTemplateDataHelper(template, player, auraTemplates, resources, modif
|
|||
else
|
||||
{
|
||||
ret.attack[type] = {
|
||||
"hack": getAttackStat("Hack"),
|
||||
"pierce": getAttackStat("Pierce"),
|
||||
"crush": getAttackStat("Crush"),
|
||||
"minRange": getAttackStat("MinRange"),
|
||||
"maxRange": getAttackStat("MaxRange"),
|
||||
"elevationBonus": getAttackStat("ElevationBonus")
|
||||
};
|
||||
for (let damageType of damageTypes.GetTypes())
|
||||
ret.attack[type][damageType] = getAttackStat(damageType);
|
||||
|
||||
ret.attack[type].elevationAdaptedRange = Math.sqrt(ret.attack[type].maxRange *
|
||||
(2 * ret.attack[type].elevationBonus + ret.attack[type].maxRange));
|
||||
}
|
||||
ret.attack[type].repeatTime = getAttackStat("RepeatTime");
|
||||
|
||||
if (template.Attack[type].Splash)
|
||||
{
|
||||
ret.attack[type].splash = {
|
||||
"hack": getAttackStat("Splash/Hack"),
|
||||
"pierce": getAttackStat("Splash/Pierce"),
|
||||
"crush": getAttackStat("Splash/Crush"),
|
||||
// true if undefined
|
||||
"friendlyFire": template.Attack[type].Splash.FriendlyFire != "false",
|
||||
"shape": template.Attack[type].Splash.Shape
|
||||
};
|
||||
for (let damageType of damageTypes.GetTypes())
|
||||
ret.attack[type].splash[damageType] = getAttackStat("Splash/" + damageType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (template.DeathDamage)
|
||||
{
|
||||
ret.deathDamage = {
|
||||
"hack": getEntityValue("DeathDamage/Hack"),
|
||||
"pierce": getEntityValue("DeathDamage/Pierce"),
|
||||
"crush": getEntityValue("DeathDamage/Crush"),
|
||||
"friendlyFire": template.DeathDamage.FriendlyFire != "false"
|
||||
};
|
||||
for (let damageType of damageTypes.GetTypes())
|
||||
ret.deathDamage[damageType] = getEntityValue("DeathDamage/" + damageType);
|
||||
}
|
||||
|
||||
if (template.Auras)
|
||||
|
|
|
|||
|
|
@ -11,11 +11,7 @@ var g_AttackTypes = {
|
|||
"Capture": translate("Capture Attack:")
|
||||
};
|
||||
|
||||
var g_DamageTypes = {
|
||||
"hack": translate("Hack"),
|
||||
"pierce": translate("Pierce"),
|
||||
"crush": translate("Crush"),
|
||||
};
|
||||
var g_DamageTypes = new DamageTypes();
|
||||
|
||||
var g_SplashDamageTypes = {
|
||||
"Circular": translate("Circular Splash Damage"),
|
||||
|
|
@ -188,7 +184,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(g_DamageTypes[dmgType]),
|
||||
"damageType": unitFont(translateWithContext("damage type", g_DamageTypes.GetNames()[dmgType])),
|
||||
"armorPercentage":
|
||||
'[font="sans-10"]' +
|
||||
sprintf(translate("(%(armorPercentage)s)"), {
|
||||
|
|
@ -204,11 +200,11 @@ function damageTypesToText(dmg)
|
|||
if (!dmg)
|
||||
return '[font="sans-12"]' + translate("(None)") + '[/font]';
|
||||
|
||||
return Object.keys(g_DamageTypes).filter(
|
||||
return g_DamageTypes.GetTypes().filter(
|
||||
dmgType => dmg[dmgType]).map(
|
||||
dmgType => sprintf(translate("%(damage)s %(damageType)s"), {
|
||||
"damage": dmg[dmgType].toFixed(1),
|
||||
"damageType": unitFont(g_DamageTypes[dmgType])
|
||||
"damageType": unitFont(translateWithContext("damage type", g_DamageTypes.GetNames()[dmgType]))
|
||||
})).join(commaFont(translate(", ")));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ function getActualUpgradeData(upgradesInfo)
|
|||
{
|
||||
upgrade.entity = upgrade.entity.replace("{civ}", g_SelectedCiv);
|
||||
|
||||
let data = GetTemplateDataHelper(loadTemplate(upgrade.entity), null, g_AuraData, g_ResourceData);
|
||||
let data = GetTemplateDataHelper(loadTemplate(upgrade.entity), null, g_AuraData, g_ResourceData, g_DamageTypes);
|
||||
data.cost = upgrade.cost;
|
||||
data.icon = upgrade.icon || data.icon;
|
||||
data.tooltip = upgrade.tooltip || data.tooltip;
|
||||
|
|
@ -177,7 +177,7 @@ function unravelPhases(techs)
|
|||
function GetTemplateData(templateName)
|
||||
{
|
||||
var template = loadTemplate(templateName);
|
||||
return GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData, g_CurrentModifiers);
|
||||
return GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData, g_DamageTypes, g_CurrentModifiers);
|
||||
}
|
||||
|
||||
function isPairTech(technologyCode)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ 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();
|
||||
|
|
@ -101,7 +102,7 @@ function loadUnit(templateName)
|
|||
return null;
|
||||
|
||||
let template = loadTemplate(templateName);
|
||||
let unit = GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData, g_CurrentModifiers);
|
||||
let unit = GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData, g_DamageTypes, g_CurrentModifiers);
|
||||
|
||||
if (template.ProductionQueue)
|
||||
{
|
||||
|
|
@ -157,7 +158,7 @@ function loadStructure(templateName)
|
|||
return null;
|
||||
|
||||
let template = loadTemplate(templateName);
|
||||
let structure = GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData, g_CurrentModifiers);
|
||||
let structure = GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData, g_DamageTypes, g_CurrentModifiers);
|
||||
|
||||
structure.production = {
|
||||
"technology": [],
|
||||
|
|
|
|||
|
|
@ -214,14 +214,14 @@ m.Template = m.Class({
|
|||
return +this.get("Cost/PopulationBonus");
|
||||
},
|
||||
|
||||
armourStrengths: function() {
|
||||
"armourStrengths": function() {
|
||||
if (!this.get("Armour"))
|
||||
return undefined;
|
||||
|
||||
return {
|
||||
hack: +this.get("Armour/Hack"),
|
||||
pierce: +this.get("Armour/Pierce"),
|
||||
crush: +this.get("Armour/Crush")
|
||||
"Hack": +this.get("Armour/Hack"),
|
||||
"Pierce": +this.get("Armour/Pierce"),
|
||||
"Crush": +this.get("Armour/Crush")
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -246,14 +246,14 @@ m.Template = m.Class({
|
|||
};
|
||||
},
|
||||
|
||||
attackStrengths: function(type) {
|
||||
"attackStrengths": function(type) {
|
||||
if (!this.get("Attack/" + type +""))
|
||||
return undefined;
|
||||
|
||||
return {
|
||||
hack: +(this.get("Attack/" + type + "/Hack") || 0),
|
||||
pierce: +(this.get("Attack/" + type + "/Pierce") || 0),
|
||||
crush: +(this.get("Attack/" + type + "/Crush") || 0)
|
||||
"Hack": +(this.get("Attack/" + type + "/Hack") || 0),
|
||||
"Pierce": +(this.get("Attack/" + type + "/Pierce") || 0),
|
||||
"Crush": +(this.get("Attack/" + type + "/Crush") || 0)
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ m.getMaxStrength = function(ent, againstClass)
|
|||
val *= ent.getMultiplierAgainst(type, againstClass);
|
||||
switch (str)
|
||||
{
|
||||
case "crush":
|
||||
case "Crush":
|
||||
strength += val * 0.085 / 3;
|
||||
break;
|
||||
case "hack":
|
||||
case "Hack":
|
||||
strength += val * 0.075 / 3;
|
||||
break;
|
||||
case "pierce":
|
||||
case "Pierce":
|
||||
strength += val * 0.065 / 3;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -70,13 +70,13 @@ m.getMaxStrength = function(ent, againstClass)
|
|||
let val = parseFloat(armourStrength[str]);
|
||||
switch (str)
|
||||
{
|
||||
case "crush":
|
||||
case "Crush":
|
||||
strength += val * 0.085 / 3;
|
||||
break;
|
||||
case "hack":
|
||||
case "Hack":
|
||||
strength += val * 0.075 / 3;
|
||||
break;
|
||||
case "pierce":
|
||||
case "Pierce":
|
||||
strength += val * 0.065 / 3;
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -7,27 +7,11 @@ Armour.prototype.Schema =
|
|||
"<Pierce>0.0</Pierce>" +
|
||||
"<Crush>5.0</Crush>" +
|
||||
"</a:example>" +
|
||||
"<element name='Hack' a:help='Hack damage protection'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>" +
|
||||
"<element name='Pierce' a:help='Pierce damage protection'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>" +
|
||||
"<element name='Crush' a:help='Crush damage protection'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>" +
|
||||
DamageTypes.BuildSchema("damage protection") +
|
||||
"<optional>" +
|
||||
"<element name='Foundation' a:help='Armour given to building foundations'>" +
|
||||
"<interleave>" +
|
||||
"<element name='Hack' a:help='Hack damage protection'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>" +
|
||||
"<element name='Pierce' a:help='Pierce damage protection'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>" +
|
||||
"<element name='Crush' a:help='Crush damage protection'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>" +
|
||||
DamageTypes.BuildSchema("damage protection") +
|
||||
"</interleave>" +
|
||||
"</element>" +
|
||||
"</optional>";
|
||||
|
|
@ -85,11 +69,11 @@ Armour.prototype.GetArmourStrengths = function()
|
|||
|
||||
var foundation = Engine.QueryInterface(this.entity, IID_Foundation) && this.template.Foundation;
|
||||
|
||||
return {
|
||||
"hack": applyMods("Hack", foundation),
|
||||
"pierce": applyMods("Pierce", foundation),
|
||||
"crush": applyMods("Crush", foundation)
|
||||
};
|
||||
let ret = {};
|
||||
for (let damageType of DamageTypes.GetTypes())
|
||||
ret[damageType] = applyMods(damageType, foundation);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
Engine.RegisterComponentType(IID_DamageReceiver, "Armour", Armour);
|
||||
|
|
|
|||
|
|
@ -100,9 +100,7 @@ Attack.prototype.Schema =
|
|||
"<optional>" +
|
||||
"<element name='Melee'>" +
|
||||
"<interleave>" +
|
||||
"<element name='Hack' a:help='Hack damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='Pierce' a:help='Pierce damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='Crush' a:help='Crush damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
DamageTypes.BuildSchema("damage strength") +
|
||||
"<element name='MaxRange' a:help='Maximum attack range (in metres)'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='PrepareTime' a:help='Time from the start of the attack command until the attack actually occurs (in milliseconds). This value relative to RepeatTime should closely match the \"event\" point in the actor's attack animation'>" +
|
||||
"<data type='nonNegativeInteger'/>" +
|
||||
|
|
@ -119,9 +117,7 @@ Attack.prototype.Schema =
|
|||
"<optional>" +
|
||||
"<element name='Ranged'>" +
|
||||
"<interleave>" +
|
||||
"<element name='Hack' a:help='Hack damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='Pierce' a:help='Pierce damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='Crush' a:help='Crush damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
DamageTypes.BuildSchema("damage strength") +
|
||||
"<element name='MaxRange' a:help='Maximum attack range (in metres)'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='MinRange' a:help='Minimum attack range (in metres)'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<optional>"+
|
||||
|
|
@ -149,9 +145,7 @@ Attack.prototype.Schema =
|
|||
"<element name='Shape' a:help='Shape of the splash damage, can be circular or linear'><text/></element>" +
|
||||
"<element name='Range' a:help='Size of the area affected by the splash'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='FriendlyFire' a:help='Whether the splash damage can hurt non enemy units'><data type='boolean'/></element>" +
|
||||
"<element name='Hack' a:help='Hack damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='Pierce' a:help='Pierce damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='Crush' a:help='Crush damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
DamageTypes.BuildSchema("damage strength") +
|
||||
Attack.prototype.bonusesSchema +
|
||||
"</interleave>" +
|
||||
"</element>" +
|
||||
|
|
@ -176,9 +170,7 @@ Attack.prototype.Schema =
|
|||
"<optional>" +
|
||||
"<element name='Slaughter' a:help='A special attack to kill domestic animals'>" +
|
||||
"<interleave>" +
|
||||
"<element name='Hack' a:help='Hack damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='Pierce' a:help='Pierce damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='Crush' a:help='Crush damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
DamageTypes.BuildSchema("damage strength") +
|
||||
"<element name='MaxRange'><ref name='nonNegativeDecimal'/></element>" + // TODO: how do these work?
|
||||
Attack.prototype.bonusesSchema +
|
||||
Attack.prototype.preferredClassesSchema +
|
||||
|
|
@ -403,11 +395,11 @@ Attack.prototype.GetAttackStrengths = function(type)
|
|||
if (type == "Capture")
|
||||
return { "value": applyMods("Value") };
|
||||
|
||||
return {
|
||||
"hack": applyMods("Hack"),
|
||||
"pierce": applyMods("Pierce"),
|
||||
"crush": applyMods("Crush")
|
||||
};
|
||||
let ret = {};
|
||||
for (let damageType of DamageTypes.GetTypes())
|
||||
ret[damageType] = applyMods(damageType);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
Attack.prototype.GetSplashDamage = function(type)
|
||||
|
|
@ -502,7 +494,6 @@ Attack.prototype.PerformAttack = function(type, target)
|
|||
let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager);
|
||||
let id = cmpProjectileManager.LaunchProjectileAtPoint(this.entity, realTargetPosition, horizSpeed, gravity);
|
||||
|
||||
cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
let data = {
|
||||
"type": type,
|
||||
"attacker": this.entity,
|
||||
|
|
|
|||
|
|
@ -31,9 +31,7 @@ DeathDamage.prototype.Schema =
|
|||
"<element name='Shape' a:help='Shape of the splash damage, can be circular'><text/></element>" +
|
||||
"<element name='Range' a:help='Size of the area affected by the splash'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='FriendlyFire' a:help='Whether the splash damage can hurt non enemy units'><data type='boolean'/></element>" +
|
||||
"<element name='Hack' a:help='Hack damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='Pierce' a:help='Pierce damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
"<element name='Crush' a:help='Crush damage strength'><ref name='nonNegativeDecimal'/></element>" +
|
||||
DamageTypes.BuildSchema("damage strength") +
|
||||
DeathDamage.prototype.bonusesSchema;
|
||||
|
||||
DeathDamage.prototype.Init = function()
|
||||
|
|
@ -48,11 +46,11 @@ DeathDamage.prototype.GetDeathDamageStrengths = function()
|
|||
let applyMods = damageType =>
|
||||
ApplyValueModificationsToEntity("DeathDamage/" + damageType, +(this.template[damageType] || 0), this.entity);
|
||||
|
||||
return {
|
||||
"hack": applyMods("Hack"),
|
||||
"pierce": applyMods("Pierce"),
|
||||
"crush": applyMods("Crush")
|
||||
};
|
||||
let ret = {};
|
||||
for (let damageType of DamageTypes.GetTypes())
|
||||
ret[damageType] = applyMods(damageType);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
DeathDamage.prototype.GetBonusTemplate = function()
|
||||
|
|
|
|||
|
|
@ -656,14 +656,14 @@ GuiInterface.prototype.GetTemplateData = function(player, name)
|
|||
let aurasTemplate = {};
|
||||
|
||||
if (!template.Auras)
|
||||
return GetTemplateDataHelper(template, player, aurasTemplate, Resources);
|
||||
return GetTemplateDataHelper(template, player, aurasTemplate, Resources, DamageTypes);
|
||||
|
||||
// Add aura name and description loaded from JSON file
|
||||
let auraNames = template.Auras._string.split(/\s+/);
|
||||
let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
|
||||
for (let name of auraNames)
|
||||
aurasTemplate[name] = cmpDataTemplateManager.GetAuraTemplate(name);
|
||||
return GetTemplateDataHelper(template, player, aurasTemplate, Resources);
|
||||
return GetTemplateDataHelper(template, player, aurasTemplate, Resources, DamageTypes);
|
||||
};
|
||||
|
||||
GuiInterface.prototype.GetTechnologyData = function(player, data)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
Engine.LoadHelperScript("DamageBonus.js");
|
||||
Engine.LoadHelperScript("DamageTypes.js");
|
||||
Engine.LoadHelperScript("Player.js");
|
||||
Engine.LoadHelperScript("ValueModification.js");
|
||||
Engine.LoadComponentScript("interfaces/Auras.js");
|
||||
|
|
@ -139,15 +140,15 @@ attackComponentTest(undefined, true ,(attacker, cmpAttack, defender) => {
|
|||
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetAttackStrengths("Capture"), { "value": 8 });
|
||||
|
||||
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetAttackStrengths("Ranged"), {
|
||||
"hack": 0,
|
||||
"pierce": 10,
|
||||
"crush": 0
|
||||
"Hack": 0,
|
||||
"Pierce": 10,
|
||||
"Crush": 0
|
||||
});
|
||||
|
||||
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetAttackStrengths("Ranged.Splash"), {
|
||||
"hack": 0.0,
|
||||
"pierce": 15.0,
|
||||
"crush": 35.0
|
||||
"Hack": 0.0,
|
||||
"Pierce": 15.0,
|
||||
"Crush": 35.0
|
||||
});
|
||||
|
||||
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetTimers("Ranged"), {
|
||||
|
|
@ -160,7 +161,13 @@ attackComponentTest(undefined, true ,(attacker, cmpAttack, defender) => {
|
|||
"repeat": 1000
|
||||
});
|
||||
|
||||
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetSplashDamage("Ranged"), { "hack": 0, "pierce": 15, "crush": 35, "friendlyFire": false, "shape": "Circular" });
|
||||
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetSplashDamage("Ranged"), {
|
||||
"Hack": 0,
|
||||
"Pierce": 15,
|
||||
"Crush": 35,
|
||||
"friendlyFire": false,
|
||||
"shape": "Circular"
|
||||
});
|
||||
});
|
||||
|
||||
for (let className of ["Infantry", "Cavalry"])
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
Engine.LoadHelperScript("DamageBonus.js");
|
||||
Engine.LoadHelperScript("DamageTypes.js");
|
||||
Engine.LoadHelperScript("Player.js");
|
||||
Engine.LoadHelperScript("Sound.js");
|
||||
Engine.LoadHelperScript("ValueModification.js");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
Engine.LoadHelperScript("DamageBonus.js");
|
||||
Engine.LoadHelperScript("DamageTypes.js");
|
||||
Engine.LoadHelperScript("ValueModification.js");
|
||||
Engine.LoadComponentScript("interfaces/AuraManager.js");
|
||||
Engine.LoadComponentScript("interfaces/Damage.js");
|
||||
|
|
@ -26,9 +27,9 @@ let template = {
|
|||
};
|
||||
|
||||
let modifiedDamage = {
|
||||
"hack": 0.0,
|
||||
"pierce": 215.0,
|
||||
"crush": 35.0
|
||||
"Hack": 0.0,
|
||||
"Pierce": 215.0,
|
||||
"Crush": 35.0
|
||||
};
|
||||
|
||||
let cmpDeathDamage = ConstructComponent(deadEnt, "DeathDamage", template);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
let parsed_template = GetTemplateDataHelper(template, null, {}, Resources, DamageTypes);
|
||||
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);
|
||||
parsed_template = GetTemplateDataHelper(template, playerID, {}, Resources, DamageTypes);
|
||||
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);
|
||||
parsed_template = GetTemplateDataHelper(template, null, {}, Resources, DamageTypes);
|
||||
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);
|
||||
parsed_template = GetTemplateDataHelper(template, playerID, {}, Resources, DamageTypes);
|
||||
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...
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
DamageTypes.prototype.BuildSchema = function(helptext = "")
|
||||
{
|
||||
return this.GetTypes().reduce((schema, type) =>
|
||||
schema + "<element name='"+type+"' a:help='"+type+" "+helptext+"'><ref name='nonNegativeDecimal'/></element>",
|
||||
"");
|
||||
};
|
||||
|
||||
DamageTypes = new DamageTypes();
|
||||
Loading…
Reference in a new issue