0ad/binaries/data/mods/public/simulation/components/Attack.js
2010-02-05 22:00:39 +00:00

77 lines
2.3 KiB
JavaScript

function Attack() {}
Attack.prototype.Init = function()
{
};
/*
* TODO: to handle secondary attacks in the future, what we might do is
* add a 'mode' parameter to most of these functions, to indicate which
* attack mode we're trying to use, and some other function that allows
* UnitAI to pick the best attack mode (based on range, damage, etc)
*/
Attack.prototype.GetTimers = function()
{
var prepare = +(this.template.PrepareTime || 0);
var repeat = +(this.template.RepeatTime || 1000);
return { "prepare": prepare, "repeat": repeat, "recharge": repeat - prepare };
};
Attack.prototype.GetAttackStrengths = function()
{
// Convert attack values to numbers, default 0 if unspecified
return {
hack: +(this.template.Hack || 0),
pierce: +(this.template.Pierce || 0),
crush: +(this.template.Crush || 0)
};
};
function hypot2(x, y)
{
return x*x + y*y;
}
Attack.prototype.CheckRange = function(target)
{
// Target must be in the world
var cmpPositionTarget = Engine.QueryInterface(target, IID_Position);
if (!cmpPositionTarget || !cmpPositionTarget.IsInWorld())
return { "error": "not-in-world" };
// We must be in the world
var cmpPositionSelf = Engine.QueryInterface(this.entity, IID_Position);
if (!cmpPositionSelf || !cmpPositionSelf.IsInWorld())
return { "error": "not-in-world" };
// Target must be within range
var posTarget = cmpPositionTarget.GetPosition();
var posSelf = cmpPositionSelf.GetPosition();
var dist2 = hypot2(posTarget.x - posSelf.x, posTarget.z - posSelf.z);
// TODO: ought to be distance to closest point in footprint, not to center
var maxrange = +this.template.Range;
if (dist2 > maxrange*maxrange)
return { "error": "out-of-range", "maxrange": maxrange };
return {};
}
/**
* Attack the target entity. This should only be called after a successful CheckRange,
* and should only be called after GetTimers().repeat msec has passed since the last
* call to PerformAttack.
*/
Attack.prototype.PerformAttack = function(target)
{
var strengths = this.GetAttackStrengths();
// Inflict damage on the target
var cmpDamageReceiver = Engine.QueryInterface(target, IID_DamageReceiver);
if (!cmpDamageReceiver)
return;
cmpDamageReceiver.TakeDamage(strengths.hack, strengths.pierce, strengths.crush);
};
Engine.RegisterComponentType(IID_Attack, "Attack", Attack);