Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/Armour.js
function Armour() {} | function Armour() {} | ||||
Armour.prototype.DamageResistanceSchema = "" + | |||||
"<oneOrMore>" + | |||||
"<element a:help='Resistance against any number of damage types'>" + | |||||
"<anyName>" + | |||||
"<except><name>Foundation</name></except>" + | |||||
"</anyName>" + | |||||
"<ref name='nonNegativeDecimal' />" + | |||||
"</element>" + | |||||
"</oneOrMore>"; | |||||
Armour.prototype.Schema = | Armour.prototype.Schema = | ||||
"<a:help>Controls the damage resistance of the unit.</a:help>" + | "<a:help>Controls the damage resistance of the unit.</a:help>" + | ||||
"<a:example>" + | "<a:example>" + | ||||
"<Hack>10.0</Hack>" + | "<Hack>10.0</Hack>" + | ||||
"<Pierce>0.0</Pierce>" + | "<Pierce>0.0</Pierce>" + | ||||
"<Crush>5.0</Crush>" + | "<Crush>5.0</Crush>" + | ||||
"</a:example>" + | "</a:example>" + | ||||
BuildDamageTypesSchema("damage protection") + | Armour.prototype.DamageResistanceSchema + | ||||
"<optional>" + | "<optional>" + | ||||
"<element name='Foundation' a:help='Armour given to building foundations'>" + | "<element name='Foundation' a:help='Armour given to building foundations'>" + | ||||
"<interleave>" + | Armour.prototype.DamageResistanceSchema + | ||||
BuildDamageTypesSchema("damage protection") + | |||||
"</interleave>" + | |||||
"</element>" + | "</element>" + | ||||
"</optional>"; | "</optional>"; | ||||
Armour.prototype.Init = function() | Armour.prototype.Init = function() | ||||
{ | { | ||||
this.invulnerable = false; | this.invulnerable = false; | ||||
}; | }; | ||||
Armour.prototype.IsInvulnerable = function() | Armour.prototype.IsInvulnerable = function() | ||||
{ | { | ||||
return this.invulnerable; | return this.invulnerable; | ||||
}; | }; | ||||
Armour.prototype.SetInvulnerability = function(invulnerability) | Armour.prototype.SetInvulnerability = function(invulnerability) | ||||
{ | { | ||||
this.invulnerable = invulnerability; | this.invulnerable = invulnerability; | ||||
Engine.PostMessage(this.entity, MT_InvulnerabilityChanged, { "entity": this.entity, "invulnerability": invulnerability }); | Engine.PostMessage(this.entity, MT_InvulnerabilityChanged, { "entity": this.entity, "invulnerability": invulnerability }); | ||||
}; | }; | ||||
/** | Armour.prototype.GetArmourStrengths = function(effectType) | ||||
* Take damage according to the entity's armor. | |||||
* @param {Object} strengths - { "hack": number, "pierce": number, "crush": number } or something like that. | |||||
* @param {number} multiplier - the damage multiplier. | |||||
* Returns object of the form { "killed": false, "change": -12 }. | |||||
*/ | |||||
Armour.prototype.TakeDamage = function(strengths, multiplier = 1) | |||||
{ | |||||
if (this.invulnerable) | |||||
return { "killed": false, "change": 0 }; | |||||
// Adjust damage values based on armour; exponential armour: damage = attack * 0.9^armour | |||||
var armourStrengths = this.GetArmourStrengths(); | |||||
// Total is sum of individual damages | |||||
// Don't bother rounding, since HP is no longer integral. | |||||
var total = 0; | |||||
for (let type in strengths) | |||||
total += strengths[type] * multiplier * Math.pow(0.9, armourStrengths[type] || 0); | |||||
// Reduce health | |||||
var cmpHealth = Engine.QueryInterface(this.entity, IID_Health); | |||||
return cmpHealth.Reduce(total); | |||||
}; | |||||
Armour.prototype.GetArmourStrengths = function() | |||||
{ | { | ||||
// Work out the armour values with technology effects. | // Work out the armour values with technology effects. | ||||
let applyMods = (type, foundation) => { | let applyMods = (type, foundation) => { | ||||
let strength; | let strength; | ||||
if (foundation) | if (foundation) | ||||
{ | { | ||||
strength = +this.template.Foundation[type]; | strength = +this.template.Foundation[type]; | ||||
type = "Foundation/" + type; | type = "Foundation/" + type; | ||||
} | } | ||||
else | else | ||||
strength = +this.template[type]; | strength = +this.template[type]; | ||||
return ApplyValueModificationsToEntity("Armour/" + type, strength, this.entity); | return ApplyValueModificationsToEntity("Armour/" + effectType + "/" + type, strength, this.entity); | ||||
}; | }; | ||||
let foundation = Engine.QueryInterface(this.entity, IID_Foundation) && this.template.Foundation; | let foundation = Engine.QueryInterface(this.entity, IID_Foundation) && this.template.Foundation; | ||||
Freagarach: invulnerable != uncapturable (e.g. relics) | |||||
Done Inline ActionsIndeed. wraitii: Indeed. | |||||
let ret = {}; | let ret = {}; | ||||
if (effectType != "Damage") | |||||
return ret; | |||||
Not Done Inline ActionsShould probably be a resistance. Freagarach: Should probably be a resistance. | |||||
Done Inline Actionslater diff wraitii: later diff | |||||
for (let damageType in this.template) | for (let damageType in this.template) | ||||
if (damageType != "Foundation") | if (damageType != "Foundation") | ||||
ret[damageType] = applyMods(damageType, foundation); | ret[damageType] = applyMods(damageType, foundation); | ||||
return ret; | return ret; | ||||
}; | }; | ||||
Not Done Inline ActionsNot sure, wouldn't it be the idea that if you kill/tear down a unit/building you get loot, but if you capture it you can't loot it? Freagarach: Not sure, wouldn't it be the idea that if you kill/tear down a unit/building you get loot, but… | |||||
Done Inline ActionsXP loot. wraitii: XP loot. | |||||
Done Inline ActionsPoint taken. Freagarach: Point taken. | |||||
Engine.RegisterComponentType(IID_DamageReceiver, "Armour", Armour); | Engine.RegisterComponentType(IID_Resistance, "Armour", Armour); |
Wildfire Games · Phabricator
invulnerable != uncapturable (e.g. relics)