0ad/binaries/data/mods/public/simulation/components/Armour.js
leper 4243433f94 Use a gaia specific player entity.
Fix some code that assumed components exist instead of testing for them.
EntityLimits and TechnologyManager are not needed for gaia and will be
removed in the future.

This was SVN commit r16119.
2015-01-07 20:33:19 +00:00

123 lines
3.3 KiB
JavaScript

function Armour() {}
Armour.prototype.Schema =
"<a:help>Controls the damage resistance of the unit.</a:help>" +
"<a:example>" +
"<Hack>10.0</Hack>" +
"<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>" +
"<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>" +
"</interleave>" +
"</element>" +
"</optional>";
Armour.prototype.Init = function()
{
this.nextAlertTime = 0;
this.invulnerable = false;
};
Armour.prototype.SetInvulnerability = function(invulnerability)
{
this.invulnerable = invulnerability;
};
/**
* Take damage according to the entity's armor.
* Returns object of the form { "killed": false, "change": -12 }
*/
Armour.prototype.TakeDamage = function(hack, pierce, crush, source)
{
// Alert target owner of attack
var cmpAttackDetection = QueryOwnerInterface(this.entity, IID_AttackDetection);
if (cmpAttackDetection)
{
var now = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).GetTime();
if (now > this.nextAlertTime)
{
this.nextAlertTime = now + cmpAttackDetection.GetSuppressionTime();
cmpAttackDetection.AttackAlert(this.entity, source);
}
}
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();
var adjHack = hack * Math.pow(0.9, armourStrengths.hack);
var adjPierce = pierce * Math.pow(0.9, armourStrengths.pierce);
var adjCrush = crush * Math.pow(0.9, armourStrengths.crush);
// Total is sum of individual damages
// Don't bother rounding, since HP is no longer integral.
var total = adjHack + adjPierce + adjCrush;
// 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
var self = this;
var applyMods = function(type, foundation)
{
var strength;
if (foundation)
{
strength = +self.template.Foundation[type];
type = "Foundation/" + type;
}
else
{
strength = +self.template[type];
}
strength = ApplyValueModificationsToEntity("Armour/" + type, strength, self.entity);
return strength;
};
if (Engine.QueryInterface(this.entity, IID_Foundation) && this.template.Foundation)
{
return {
hack: applyMods("Hack", true),
pierce: applyMods("Pierce", true),
crush: applyMods("Crush", true)
};
}
else
{
return {
hack: applyMods("Hack"),
pierce: applyMods("Pierce"),
crush: applyMods("Crush")
};
}
};
Engine.RegisterComponentType(IID_DamageReceiver, "Armour", Armour);