Changeset View
Standalone View
binaries/data/mods/public/simulation/components/Attack.js
function Attack() {} | function Attack() {} | ||||
var g_AttackTypes = ["Melee", "Ranged", "Capture"]; | |||||
Attack.prototype.bonusesSchema = | Attack.prototype.bonusesSchema = | ||||
"<optional>" + | "<optional>" + | ||||
"<element name='Bonuses'>" + | "<element name='Bonuses'>" + | ||||
"<zeroOrMore>" + | "<zeroOrMore>" + | ||||
"<element>" + | "<element>" + | ||||
"<anyName/>" + | "<anyName/>" + | ||||
"<interleave>" + | "<interleave>" + | ||||
"<optional>" + | "<optional>" + | ||||
▲ Show 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | Attack.prototype.Schema = | ||||
"</optional>"; | "</optional>"; | ||||
Attack.prototype.Init = function() | Attack.prototype.Init = function() | ||||
{ | { | ||||
}; | }; | ||||
Attack.prototype.Serialize = null; // we have no dynamic state to save | Attack.prototype.Serialize = null; // we have no dynamic state to save | ||||
Attack.prototype.GetAttackTypes = function() | Attack.prototype.GetAttackTypes = function(wantedTypes) | ||||
{ | { | ||||
return ["Melee", "Ranged", "Capture"].filter(type => !!this.template[type]); | let types = g_AttackTypes.filter(type => !!this.template[type]); | ||||
fatherbushido: Perhaps let types = Object.keys(this.template) | |||||
bbAuthorUnsubmitted Not Done Inline ActionsNope since slaughter needs to be excluded anyway, and having a global for the non types seems worse than for the pro types. bb: Nope since slaughter needs to be excluded anyway, and having a global for the non types seems… | |||||
fatherbushidoUnsubmitted Not Done Inline ActionsAh yes I didn't consider that. Yes the second thing would be ugly (I didn't even have that idea). fatherbushido: Ah yes I didn't consider that. Yes the second thing would be ugly (I didn't even have that… | |||||
bbAuthorUnsubmitted Not Done Inline ActionsIt should be g_AttackTypes anyway following the coding conventions, whether we use var or const idc, I choose var here because a mod might want to extend it, and probably from a triggerscript. bb: It should be `g_AttackTypes` anyway following the coding conventions, whether we use `var` or… | |||||
if (!wantedTypes) | |||||
return types; | |||||
let wantedTypesReal = wantedTypes.filter(wtype => wtype.indexOf("!") != 0); | |||||
return types.filter(type => wantedTypes.indexOf("!" + type) == -1 && | |||||
(!wantedTypesReal || !wantedTypesReal.length || wantedTypesReal.indexOf(type) != -1)); | |||||
Not Done Inline ActionsPerhaps it could be simplified but we'll let that for the future. fatherbushido: Perhaps it could be simplified but we'll let that for the future. | |||||
}; | }; | ||||
Attack.prototype.GetPreferredClasses = function(type) | Attack.prototype.GetPreferredClasses = function(type) | ||||
{ | { | ||||
if (this.template[type] && this.template[type].PreferredClasses && | if (this.template[type] && this.template[type].PreferredClasses && | ||||
this.template[type].PreferredClasses._string) | this.template[type].PreferredClasses._string) | ||||
return this.template[type].PreferredClasses._string.split(/\s+/); | return this.template[type].PreferredClasses._string.split(/\s+/); | ||||
return []; | return []; | ||||
}; | }; | ||||
Attack.prototype.GetRestrictedClasses = function(type) | Attack.prototype.GetRestrictedClasses = function(type) | ||||
{ | { | ||||
if (this.template[type] && this.template[type].RestrictedClasses && | if (this.template[type] && this.template[type].RestrictedClasses && | ||||
this.template[type].RestrictedClasses._string) | this.template[type].RestrictedClasses._string) | ||||
return this.template[type].RestrictedClasses._string.split(/\s+/); | return this.template[type].RestrictedClasses._string.split(/\s+/); | ||||
return []; | return []; | ||||
}; | }; | ||||
Attack.prototype.CanAttack = function(target) | Attack.prototype.CanAttack = function(target, wantedTypes) | ||||
{ | { | ||||
let cmpFormation = Engine.QueryInterface(target, IID_Formation); | let cmpFormation = Engine.QueryInterface(target, IID_Formation); | ||||
if (cmpFormation) | if (cmpFormation) | ||||
return true; | return true; | ||||
let cmpThisPosition = Engine.QueryInterface(this.entity, IID_Position); | let cmpThisPosition = Engine.QueryInterface(this.entity, IID_Position); | ||||
let cmpTargetPosition = Engine.QueryInterface(target, IID_Position); | let cmpTargetPosition = Engine.QueryInterface(target, IID_Position); | ||||
if (!cmpThisPosition || !cmpTargetPosition || !cmpThisPosition.IsInWorld() || !cmpTargetPosition.IsInWorld()) | if (!cmpThisPosition || !cmpTargetPosition || !cmpThisPosition.IsInWorld() || !cmpTargetPosition.IsInWorld()) | ||||
return false; | return false; | ||||
let cmpIdentity = Engine.QueryInterface(target, IID_Identity); | |||||
if (!cmpIdentity) | |||||
return false; | |||||
let cmpEntityPlayer = QueryOwnerInterface(this.entity); | |||||
let cmpTargetPlayer = QueryOwnerInterface(target); | |||||
if (!cmpTargetPlayer || !cmpEntityPlayer) | |||||
Not Done Inline Actionstypo I guess fatherbushido: typo I guess | |||||
Not Done Inline ActionsI don't see him, please point me at it ;) bb: I don't see him, please point me at it ;) | |||||
Not Done Inline Actionsah no it's ok, sorry for the noise :-) fatherbushido: ah no it's ok, sorry for the noise :-)
You handle thing like !domes!tic in fact :p | |||||
return false; | |||||
let types = this.GetAttackTypes(wantedTypes); | |||||
let targetOwner = cmpEntityPlayer.GetPlayerID(); | |||||
let targetClasses = cmpIdentity.GetClassesList(); | |||||
let cmpCapturable = QueryMiragedInterface(target, IID_Capturable); | |||||
if (targetClasses.indexOf("Domestic") == -1 && !cmpEntityPlayer.IsEnemy(cmpTargetPlayer.GetPlayerID()) && | |||||
(!cmpCapturable || !cmpCapturable.CanCapture(targetOwner) || types.indexOf("Capture"))) | |||||
Not Done Inline Actionstypes.indexOf("Capture") == -1 wantedtypes undefined It's annoying to not have catched that with the test. (I write quickly so be tolerant :p) fatherbushido: types.indexOf("Capture") == -1
wantedtypes undefined
Not a 'sheep', not an ennemy, capturable… | |||||
Not Done Inline Actions(which would be mostly impossible to trigger as Capture is the last in the array currently and then...) fatherbushido: (which would be mostly impossible to trigger as Capture is the last in the array currently and… | |||||
Not Done Inline ActionsThe check isn't only wrong, but also badly placed, and even more wrong than this comment states. It should be merged better with the loop below, and the whole "domestic" part should be split from it. bb: The check isn't only wrong, but also badly placed, and even more wrong than this comment states. | |||||
return false; | |||||
Not Done Inline Actionsnote for myself: Is it possible to have a null Player here? fatherbushido: note for myself: Is it possible to have a null Player here? | |||||
// Check if the relative height difference is larger than the attack range | // Check if the relative height difference is larger than the attack range | ||||
// If the relative height is bigger, it means they will never be able to | // If the relative height is bigger, it means they will never be able to | ||||
// reach each other, no matter how close they come. | // reach each other, no matter how close they come. | ||||
let heightDiff = Math.abs(cmpThisPosition.GetHeightOffset() - cmpTargetPosition.GetHeightOffset()); | let heightDiff = Math.abs(cmpThisPosition.GetHeightOffset() - cmpTargetPosition.GetHeightOffset()); | ||||
const cmpIdentity = Engine.QueryInterface(target, IID_Identity); | for (let type of types) | ||||
if (!cmpIdentity) | |||||
return undefined; | |||||
const targetClasses = cmpIdentity.GetClassesList(); | |||||
for (let type of this.GetAttackTypes()) | |||||
{ | { | ||||
if (type == "Capture" && !QueryMiragedInterface(target, IID_Capturable)) | if (type == "Capture" && (!cmpCapturable || !cmpCapturable.CanCapture(targetOwner))) | ||||
continue; | continue; | ||||
if (heightDiff > this.GetRange(type).max) | if (heightDiff > this.GetRange(type).max) | ||||
continue; | continue; | ||||
let restrictedClasses = this.GetRestrictedClasses(type); | let restrictedClasses = this.GetRestrictedClasses(type); | ||||
if (!restrictedClasses.length) | if (!restrictedClasses.length) | ||||
return true; | return true; | ||||
▲ Show 20 Lines • Show All 358 Lines • Show Last 20 Lines |
Perhaps let types = Object.keys(this.template)