Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/Attack.js
Show First 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | "<Ranged>" + | ||||
"<Shape>Circular</Shape>" + | "<Shape>Circular</Shape>" + | ||||
"<Range>20</Range>" + | "<Range>20</Range>" + | ||||
"<FriendlyFire>false</FriendlyFire>" + | "<FriendlyFire>false</FriendlyFire>" + | ||||
"<Hack>0.0</Hack>" + | "<Hack>0.0</Hack>" + | ||||
"<Pierce>10.0</Pierce>" + | "<Pierce>10.0</Pierce>" + | ||||
"<Crush>0.0</Crush>" + | "<Crush>0.0</Crush>" + | ||||
"</Splash>" + | "</Splash>" + | ||||
"</Ranged>" + | "</Ranged>" + | ||||
"<Slaughter>" + | "<Slaughter>" + | ||||
"<Hack>1000.0</Hack>" + | |||||
"<Pierce>0.0</Pierce>" + | |||||
"<Crush>0.0</Crush>" + | |||||
"<MaxRange>4.0</MaxRange>" + | "<MaxRange>4.0</MaxRange>" + | ||||
Stan: I believe you can do <instantkill/>
With
<element><empty/></element> | |||||
Done Inline ActionsBut how to check for that then? Because then it has a 'value' of void ( ({InstantKill:(void 0), MaxRange:"2"}) ) so every check I try returns not what is expected :(
Freagarach: But how to check for that then? Because then it has a 'value' of void (
```
({InstantKill:(void… | |||||
Done Inline Actionshttps://stackoverflow.com/questions/1098040/checking-if-a-key-exists-in-a-javascript-object Maybe a better approach InstantKill in object Stan: https://stackoverflow.com/questions/1098040/checking-if-a-key-exists-in-a-javascript-object… | |||||
Done Inline ActionsYep, seems better; I'll try that tomorrow. Freagarach: Yep, seems better; I'll try that tomorrow. | |||||
"</Slaughter>" + | "</Slaughter>" + | ||||
"</a:example>" + | "</a:example>" + | ||||
"<optional>" + | "<optional>" + | ||||
"<element name='Melee'>" + | "<element name='Melee'>" + | ||||
"<interleave>" + | "<interleave>" + | ||||
DamageTypes.BuildSchema("damage strength") + | DamageTypes.BuildSchema("damage strength") + | ||||
"<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='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'>" + | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | "<element name='Capture'>" + | ||||
Attack.prototype.preferredClassesSchema + | Attack.prototype.preferredClassesSchema + | ||||
Attack.prototype.restrictedClassesSchema + | Attack.prototype.restrictedClassesSchema + | ||||
"</interleave>" + | "</interleave>" + | ||||
"</element>" + | "</element>" + | ||||
"</optional>" + | "</optional>" + | ||||
"<optional>" + | "<optional>" + | ||||
"<element name='Slaughter' a:help='A special attack to kill domestic animals'>" + | "<element name='Slaughter' a:help='A special attack to kill domestic animals'>" + | ||||
"<interleave>" + | "<interleave>" + | ||||
DamageTypes.BuildSchema("damage strength") + | |||||
"<element name='MaxRange'><ref name='nonNegativeDecimal'/></element>" + // TODO: how do these work? | "<element name='MaxRange'><ref name='nonNegativeDecimal'/></element>" + // TODO: how do these work? | ||||
Attack.prototype.bonusesSchema + | |||||
Attack.prototype.preferredClassesSchema + | Attack.prototype.preferredClassesSchema + | ||||
Attack.prototype.restrictedClassesSchema + | Attack.prototype.restrictedClassesSchema + | ||||
"</interleave>" + | "</interleave>" + | ||||
"</element>" + | "</element>" + | ||||
"</optional>"; | "</optional>"; | ||||
Attack.prototype.Init = function() | Attack.prototype.Init = function() | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 201 Lines • ▼ Show 20 Lines | Attack.prototype.GetAttackStrengths = function(type) | ||||
let template = this.template[type]; | let template = this.template[type]; | ||||
let splash = ""; | let splash = ""; | ||||
if (!template) | if (!template) | ||||
{ | { | ||||
template = this.template[type.split(".")[0]].Splash; | template = this.template[type.split(".")[0]].Splash; | ||||
splash = "/Splash"; | splash = "/Splash"; | ||||
} | } | ||||
let applyMods = damageType => | let applyMods = damageType => | ||||
Done Inline ActionsLooks like you figured it out ? Stan: Looks like you figured it out ?
The only way I found was to check for !== undefined | |||||
Done Inline ActionsStan: https://stackoverflow.com/questions/1291942/what-does-javascriptvoid0-mean | |||||
ApplyValueModificationsToEntity("Attack/" + type + splash + "/" + damageType, +(template[damageType] || 0), this.entity); | ApplyValueModificationsToEntity("Attack/" + type + splash + "/" + damageType, +(template[damageType] || 0), this.entity); | ||||
if (type == "Capture") | if (type == "Capture") | ||||
return { "value": applyMods("Value") }; | return { "value": applyMods("Value") }; | ||||
let ret = {}; | let ret = {}; | ||||
for (let damageType of DamageTypes.GetTypes()) | for (let damageType of DamageTypes.GetTypes()) | ||||
ret[damageType] = applyMods(damageType); | ret[damageType] = applyMods(damageType); | ||||
▲ Show 20 Lines • Show All 169 Lines • ▼ Show 20 Lines | if (cmpCapturable.Reduce(strength, attackerOwner) && IsOwnedByEnemyOfPlayer(attackerOwner, target)) | ||||
Engine.PostMessage(target, MT_Attacked, { | Engine.PostMessage(target, MT_Attacked, { | ||||
"attacker": this.entity, | "attacker": this.entity, | ||||
"target": target, | "target": target, | ||||
"type": type, | "type": type, | ||||
"damage": strength, | "damage": strength, | ||||
"attackerOwner": attackerOwner | "attackerOwner": attackerOwner | ||||
}); | }); | ||||
} | } | ||||
else if (type == "Melee") | |||||
{ | |||||
// Melee attack - hurt the target immediately. | |||||
cmpDamage.CauseDamage({ | |||||
"strengths": this.GetAttackStrengths(type), | |||||
"target": target, | |||||
"attacker": this.entity, | |||||
"multiplier": GetDamageBonus(this.entity, target, type, this.GetBonusTemplate(type)), | |||||
"type": type, | |||||
"attackerOwner": attackerOwner | |||||
}); | |||||
} | |||||
else if (type == "Slaughter") | |||||
{ | |||||
// Special attack to instantly kill domestic animals. | |||||
let cmpTargetHealth = Engine.QueryInterface(target, IID_Health); | |||||
if (cmpTargetHealth) | |||||
cmpTargetHealth.Reduce(cmpTargetHealth.GetHitpoints()); | |||||
} | |||||
else | else | ||||
{ | { | ||||
// Melee attack - hurt the target immediately | warn("This attack type is not (yet) implemented."); | ||||
cmpDamage.CauseDamage({ | cmpDamage.CauseDamage({ | ||||
wraitiiUnsubmitted Done Inline ActionsShould probably remove the CauseDamage then ;) wraitii: Should probably remove the CauseDamage then ;) | |||||
FreagarachAuthorUnsubmitted Done Inline ActionsHence the question in the summary ;) Freagarach: Hence the question in the summary ;) | |||||
"strengths": this.GetAttackStrengths(type), | "strengths": this.GetAttackStrengths(type), | ||||
"target": target, | "target": target, | ||||
"attacker": this.entity, | "attacker": this.entity, | ||||
"multiplier": GetDamageBonus(this.entity, target, type, this.GetBonusTemplate(type)), | "multiplier": GetDamageBonus(this.entity, target, type, this.GetBonusTemplate(type)), | ||||
"type": type, | "type": type, | ||||
"attackerOwner": attackerOwner | "attackerOwner": attackerOwner | ||||
}); | }); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 65 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
I believe you can do <instantkill/>
With
<element><empty/></element>