Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/Attack.js
Show First 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | "<a:example>" + | ||||
"<Ranged>" + | "<Ranged>" + | ||||
"<Damage>" + | "<Damage>" + | ||||
"<Hack>0.0</Hack>" + | "<Hack>0.0</Hack>" + | ||||
"<Pierce>10.0</Pierce>" + | "<Pierce>10.0</Pierce>" + | ||||
"<Crush>0.0</Crush>" + | "<Crush>0.0</Crush>" + | ||||
"</Damage>" + | "</Damage>" + | ||||
"<MaxRange>44.0</MaxRange>" + | "<MaxRange>44.0</MaxRange>" + | ||||
"<MinRange>20.0</MinRange>" + | "<MinRange>20.0</MinRange>" + | ||||
"<ElevationBonus>15.0</ElevationBonus>" + | "<AttackHeightOffset>15.0</AttackHeightOffset>" + | ||||
"<PrepareTime>800</PrepareTime>" + | "<PrepareTime>800</PrepareTime>" + | ||||
"<RepeatTime>1600</RepeatTime>" + | "<RepeatTime>1600</RepeatTime>" + | ||||
"<Delay>1000</Delay>" + | "<DamageDelay>1000</DamageDelay>" + | ||||
"<Bonuses>" + | "<Bonuses>" + | ||||
"<Bonus1>" + | "<Bonus1>" + | ||||
"<Classes>Cavalry</Classes>" + | "<Classes>Cavalry</Classes>" + | ||||
"<Multiplier>2</Multiplier>" + | "<Multiplier>2</Multiplier>" + | ||||
"</Bonus1>" + | "</Bonus1>" + | ||||
"</Bonuses>" + | "</Bonuses>" + | ||||
"<Projectile>" + | "<Projectile>" + | ||||
"<Speed>50.0</Speed>" + | "<Speed>50.0</Speed>" + | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | "<optional>" + | ||||
"<element name='Ranged'>" + | "<element name='Ranged'>" + | ||||
"<interleave>" + | "<interleave>" + | ||||
"<element name='Damage'>" + | "<element name='Damage'>" + | ||||
BuildDamageTypesSchema("damage strength") + | BuildDamageTypesSchema("damage strength") + | ||||
"</element>" + | "</element>" + | ||||
"<element name='MaxRange' a:help='Maximum attack range (in metres)'><ref name='nonNegativeDecimal'/></element>" + | "<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>" + | "<element name='MinRange' a:help='Minimum attack range (in metres)'><ref name='nonNegativeDecimal'/></element>" + | ||||
"<optional>"+ | "<optional>"+ | ||||
"<element name='ElevationBonus' a:help='give an elevation advantage (in meters)'><ref name='nonNegativeDecimal'/></element>" + | "<element name='AttackHeightOffset' a:help='give an elevation advantage (in meters)'><ref name='nonNegativeDecimal'/></element>" + | ||||
"</optional>" + | "</optional>" + | ||||
"<optional>" + | "<optional>" + | ||||
"<element name='RangeOverlay'>" + | "<element name='RangeOverlay'>" + | ||||
"<interleave>" + | "<interleave>" + | ||||
"<element name='LineTexture'><text/></element>" + | "<element name='LineTexture'><text/></element>" + | ||||
"<element name='LineTextureMask'><text/></element>" + | "<element name='LineTextureMask'><text/></element>" + | ||||
"<element name='LineThickness'><ref name='nonNegativeDecimal'/></element>" + | "<element name='LineThickness'><ref name='nonNegativeDecimal'/></element>" + | ||||
"</interleave>" + | "</interleave>" + | ||||
"</element>" + | "</element>" + | ||||
"</optional>" + | "</optional>" + | ||||
"<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'>" + | "<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'/>" + | "<data type='nonNegativeInteger'/>" + | ||||
"</element>" + | "</element>" + | ||||
"<element name='RepeatTime' a:help='Time between attacks (in milliseconds). The attack animation will be stretched to match this time'>" + | "<element name='RepeatTime' a:help='Time between attacks (in milliseconds). The attack animation will be stretched to match this time'>" + | ||||
"<data type='positiveInteger'/>" + | "<data type='positiveInteger'/>" + | ||||
"</element>" + | "</element>" + | ||||
"<element name='Delay' a:help='Delay of the damage in milliseconds'><ref name='nonNegativeDecimal'/></element>" + | "<optional>" + | ||||
"<element name='DamageDelay' a:help='Delay of the damage (including splash) after projectile hit in milliseconds'><ref name='nonNegativeDecimal'/></element>" + | |||||
"</optional>"+ | |||||
"<optional>" + | "<optional>" + | ||||
"<element name='Splash'>" + | "<element name='Splash'>" + | ||||
"<interleave>" + | "<interleave>" + | ||||
"<element name='Shape' a:help='Shape of the splash damage, can be circular or linear'><text/></element>" + | "<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='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='FriendlyFire' a:help='Whether the splash damage can hurt non enemy units'><data type='boolean'/></element>" + | ||||
"<element name='Damage'>" + | "<element name='Damage'>" + | ||||
BuildDamageTypesSchema("damage strength") + | BuildDamageTypesSchema("damage strength") + | ||||
▲ Show 20 Lines • Show All 303 Lines • ▼ Show 20 Lines | |||||
Attack.prototype.GetRange = function(type) | Attack.prototype.GetRange = function(type) | ||||
{ | { | ||||
let max = +this.template[type].MaxRange; | let max = +this.template[type].MaxRange; | ||||
max = ApplyValueModificationsToEntity("Attack/" + type + "/MaxRange", max, this.entity); | max = ApplyValueModificationsToEntity("Attack/" + type + "/MaxRange", max, this.entity); | ||||
let min = +(this.template[type].MinRange || 0); | let min = +(this.template[type].MinRange || 0); | ||||
min = ApplyValueModificationsToEntity("Attack/" + type + "/MinRange", min, this.entity); | min = ApplyValueModificationsToEntity("Attack/" + type + "/MinRange", min, this.entity); | ||||
let elevationBonus = +(this.template[type].ElevationBonus || 0); | let attackHeightOffset = +(this.template[type].AttackHeightOffset || 0); | ||||
elevationBonus = ApplyValueModificationsToEntity("Attack/" + type + "/ElevationBonus", elevationBonus, this.entity); | attackHeightOffset = ApplyValueModificationsToEntity("Attack/" + type + "/AttackHeightOffset", attackHeightOffset, this.entity); | ||||
return { "max": max, "min": min, "elevationBonus": elevationBonus }; | return { "max": max, "min": min, "attackHeightOffset": attackHeightOffset }; | ||||
}; | }; | ||||
Attack.prototype.GetBonusTemplate = function(type) | Attack.prototype.GetBonusTemplate = function(type) | ||||
{ | { | ||||
let template = this.template[type]; | let template = this.template[type]; | ||||
if (!template) | if (!template) | ||||
template = this.template[type.split(".")[0]].Splash; | template = this.template[type.split(".")[0]].Splash; | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | if (type == "Ranged") | ||||
let impactActorName = ""; | let impactActorName = ""; | ||||
let impactAnimationLifetime = 0; | let impactAnimationLifetime = 0; | ||||
actorName = this.template[type].Projectile.ActorName || ""; | actorName = this.template[type].Projectile.ActorName || ""; | ||||
impactActorName = this.template[type].Projectile.ImpactActorName || ""; | impactActorName = this.template[type].Projectile.ImpactActorName || ""; | ||||
impactAnimationLifetime = this.template[type].Projectile.ImpactAnimationLifetime || 0; | impactAnimationLifetime = this.template[type].Projectile.ImpactAnimationLifetime || 0; | ||||
// TODO: Use unit rotation to implement x/z offsets. | // TODO: Use unit rotation to implement x/z offsets. | ||||
let deltaLaunchPoint = new Vector3D(0, this.template[type].Projectile.LaunchPoint["@y"], 0.0); | let deltaLaunchPoint = new Vector3D(0, this.template[type].Projectile.LaunchPoint["@y"], 0.0); | ||||
Silier: arent now origin and launchpoint basically the same? | |||||
Not Done Inline ActionsI would advocate to that, yeah. Just that the Origin doesn't need a projectile. Freagarach: I would advocate to that, yeah. Just that the `Origin` doesn't need a projectile. | |||||
Not Done Inline ActionsI think launchpoint can be both defined in the template and the mesh? Stan: I think launchpoint can be both defined in the template and the mesh? | |||||
let launchPoint = Vector3D.add(selfPosition, deltaLaunchPoint); | let launchPoint = Vector3D.add(selfPosition, deltaLaunchPoint); | ||||
let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); | let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); | ||||
if (cmpVisual) | if (cmpVisual) | ||||
{ | { | ||||
// if the projectile definition is missing from the template | // if the projectile definition is missing from the template | ||||
// then fallback to the projectile name and launchpoint in the visual actor | // then fallback to the projectile name and launchpoint in the visual actor | ||||
if (!actorName) | if (!actorName) | ||||
Show All 29 Lines | if (type == "Ranged") | ||||
{ | { | ||||
data.friendlyFire = this.template[type].Splash.FriendlyFire != "false"; | data.friendlyFire = this.template[type].Splash.FriendlyFire != "false"; | ||||
data.radius = +this.template[type].Splash.Range; | data.radius = +this.template[type].Splash.Range; | ||||
data.shape = this.template[type].Splash.Shape; | data.shape = this.template[type].Splash.Shape; | ||||
data.isSplash = true; | data.isSplash = true; | ||||
data.splashStrengths = this.GetAttackStrengths(type + ".Splash"); | data.splashStrengths = this.GetAttackStrengths(type + ".Splash"); | ||||
data.splashBonus = this.GetBonusTemplate(type + ".Splash"); | data.splashBonus = this.GetBonusTemplate(type + ".Splash"); | ||||
} | } | ||||
cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Damage, "MissileHit", timeToTarget * 1000 + +this.template[type].Delay, data); | cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Damage, "MissileHit", +(this.template[type].DamageDelay || 0) + timeToTarget * 1000, data); | ||||
} | } | ||||
else if (type == "Capture") | else if (type == "Capture") | ||||
{ | { | ||||
if (attackerOwner == INVALID_PLAYER) | if (attackerOwner == INVALID_PLAYER) | ||||
return; | return; | ||||
let multiplier = GetDamageBonus(this.entity, target, type, this.GetBonusTemplate(type)); | let multiplier = GetDamageBonus(this.entity, target, type, this.GetBonusTemplate(type)); | ||||
let cmpHealth = Engine.QueryInterface(target, IID_Health); | let cmpHealth = Engine.QueryInterface(target, IID_Health); | ||||
▲ Show 20 Lines • Show All 95 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
arent now origin and launchpoint basically the same?