Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/ai/common-api/entity.js
Show First 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | if (!this.get("Attack/" + type +"")) | ||||
return undefined; | return undefined; | ||||
return { | return { | ||||
"max": +this.get("Attack/" + type +"/MaxRange"), | "max": +this.get("Attack/" + type +"/MaxRange"), | ||||
"min": +(this.get("Attack/" + type +"/MinRange") || 0) | "min": +(this.get("Attack/" + type +"/MinRange") || 0) | ||||
}; | }; | ||||
}, | }, | ||||
// TODO: maybe DPS | |||||
"attackStrengths": function(type) { | "attackStrengths": function(type) { | ||||
let attackDamageTypes = this.get("Attack/" + type + "/Damage"); | let attackDamageTypes = this.get("Attack/" + type + "/Damage"); | ||||
if (!attackDamageTypes) | if (!attackDamageTypes) | ||||
return undefined; | return undefined; | ||||
let damage = {}; | let strength = {}; | ||||
for (let damageType in attackDamageTypes) | for (let damageType in attackDamageTypes) | ||||
damage[damageType] = +attackDamageTypes[damageType]; | strength[damageType] = +attackDamageTypes[damageType]; | ||||
return damage; | strength.Capture = +this.get("Attack/" + type + "/Capture") || 0; | ||||
return strength; | |||||
}, | }, | ||||
"captureStrength": function() { | "captureStrength": function(target) { | ||||
if (!this.get("Attack/Capture")) | let strength = 0; | ||||
return undefined; | for (let type in this.get("Attack")) | ||||
strength = Math.max(strength, +(this.get("Attack/"+ type + "/Capture")|| 0) * this.getAttackBonus(this, target, type)); | |||||
return +this.get("Attack/Capture/Capture") || 0; | return strength; | ||||
}, | |||||
"getAttackBonus": function(target, type) { | |||||
let attackBonus = 1; | |||||
if (!this.get("Attack/" + type) || !this.get("Attack/" + type + "/Bonuses")) | |||||
return attackBonus; | |||||
let bonuses = this.get("Attack/" + type + "/Bonuses"); | |||||
for (let key in bonuses) | |||||
{ | |||||
let bonus = bonuses[key]; | |||||
if (bonus.Civ && bonus.Civ !== target.civ()) | |||||
continue; | |||||
if (bonus.Classes && bonus.Classes.split(/\s+/).some(cls => !target.hasClass(cls))) | |||||
continue; | |||||
attackBonus *= bonus.Multiplier; | |||||
} | |||||
return attackBonus; | |||||
}, | }, | ||||
"attackTimes": function(type) { | "attackTimes": function(type) { | ||||
if (!this.get("Attack/" + type +"")) | if (!this.get("Attack/" + type +"")) | ||||
return undefined; | return undefined; | ||||
return { | return { | ||||
"prepare": +(this.get("Attack/" + type + "/PrepareTime") || 0), | "prepare": +(this.get("Attack/" + type + "/PrepareTime") || 0), | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | for (let i in classes) | ||||
if (mcounter.indexOf(classes[i]) != -1) | if (mcounter.indexOf(classes[i]) != -1) | ||||
return true; | return true; | ||||
return false; | return false; | ||||
}, | }, | ||||
// returns, if it exists, the multiplier from each attack against a given class | // returns, if it exists, the multiplier from each attack against a given class | ||||
"getMultiplierAgainst": function(type, againstClass) { | "getMultiplierAgainst": function(type, againstClass) { | ||||
if (!this.get("Attack/" + type +"")) | if (!this.get("Attack/" + type +"")) | ||||
return undefined; | return undefined; | ||||
Freagarach: Is this needed? | |||||
Done Inline ActionsI basicly merged two functions here: the original getMutliplierAgainst and the GetAttackBonus from entityExtend (and this makes some code simpler and better). You are right however that this can/should be split of this patch (was on my radar, but didn't get to that yet) bb: I basicly merged two functions here: the original getMutliplierAgainst and the GetAttackBonus… | |||||
if (this.get("Attack/" + type + "/Bonuses")) | if (this.get("Attack/" + type + "/Bonuses")) | ||||
{ | { | ||||
for (let b in this.get("Attack/" + type + "/Bonuses")) | for (let b in this.get("Attack/" + type + "/Bonuses")) | ||||
{ | { | ||||
let bonusClasses = this.get("Attack/" + type + "/Bonuses/" + b + "/Classes"); | let bonusClasses = this.get("Attack/" + type + "/Bonuses/" + b + "/Classes"); | ||||
if (!bonusClasses) | if (!bonusClasses) | ||||
continue; | continue; | ||||
▲ Show 20 Lines • Show All 198 Lines • ▼ Show 20 Lines | for (let r in gatherRates) | ||||
if (r.split('.')[0] === type) | if (r.split('.')[0] === type) | ||||
return true; | return true; | ||||
return false; | return false; | ||||
}, | }, | ||||
"isGarrisonHolder": function() { return this.get("GarrisonHolder") !== undefined; }, | "isGarrisonHolder": function() { return this.get("GarrisonHolder") !== undefined; }, | ||||
/** | /** | ||||
* returns true if the tempalte can capture the given target entity | * returns true if the template can capture the given target entity | ||||
* if no target is given, returns true if the template has the Capture attack | * if no target is given, returns true if the template has the Capture attack | ||||
*/ | */ | ||||
"canCapture": function(target) | "canCapture": function(target) | ||||
{ | { | ||||
if (!this.get("Attack/Capture")) | if (!this.get("Attack") || Object.keys(this.get("Attack")).every(type => !this.get("Attack/" + type + "/Capture"))) | ||||
return false; | return false; | ||||
if (!target) | if (!target) | ||||
return true; | return true; | ||||
if (!target.get("Capturable")) | if (!target.get("Capturable")) | ||||
return false; | return false; | ||||
let restrictedClasses = this.get("Attack/Capture/RestrictedClasses/_string"); | let restrictedClasses = this.get("Attack/Capture/RestrictedClasses/_string"); | ||||
return !restrictedClasses || !MatchesClassList(target.classes(), restrictedClasses); | return !restrictedClasses || !MatchesClassList(target.classes(), restrictedClasses); | ||||
}, | }, | ||||
Not Done Inline ActionsPerhaps change the order a bit? Freagarach: Perhaps change the order a bit? | |||||
Done Inline ActionsChange what order? bb: Change what order? | |||||
Not Done Inline ActionsE.g., if we check for !target first we don't need to calculate the attacks. Freagarach: E.g., if we check for `!target` first we don't need to calculate the attacks. | |||||
Done Inline Actionsk bb: k | |||||
Done Inline ActionsIf fact, no, the comment tells us it is designed to only return true in case there is no target when we can capture bb: If fact, no, the comment tells us it is designed to only return true in case there is no target… | |||||
"isCapturable": function() { return this.get("Capturable") !== undefined; }, | "isCapturable": function() { return this.get("Capturable") !== undefined; }, | ||||
"canGuard": function() { return this.get("UnitAI/CanGuard") === "true"; }, | "canGuard": function() { return this.get("UnitAI/CanGuard") === "true"; }, | ||||
"canGarrison": function() { return "Garrisonable" in this._template; }, | "canGarrison": function() { return "Garrisonable" in this._template; }, | ||||
}); | }); | ||||
▲ Show 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | "canAttackClass": function(aClass) | ||||
} | } | ||||
return false; | return false; | ||||
}, | }, | ||||
/** | /** | ||||
* Derived from Attack.js' similary named function. | * Derived from Attack.js' similary named function. | ||||
* @return {boolean} - Whether an entity can attack a given target. | * @return {boolean} - Whether an entity can attack a given target. | ||||
*/ | */ | ||||
"canAttackTarget": function(target, allowCapture) | "canAttackTarget": function(target) | ||||
{ | { | ||||
let attackTypes = this.get("Attack"); | let attackTypes = this.get("Attack"); | ||||
if (!attackTypes) | if (!attackTypes) | ||||
return false; | return false; | ||||
let canCapture = allowCapture && this.canCapture(target); | // TODO there was some stuff from allowCapture here, which did not esily translate | ||||
let armourStrengths = target.get("Armour"); | |||||
if (!armourStrengths) | |||||
return canCapture; | |||||
for (let type in attackTypes) | for (let type in attackTypes) | ||||
{ | { | ||||
if (type == "Capture" ? !canCapture : target.isInvulnerable()) | |||||
continue; | |||||
let restrictedClasses = this.get("Attack/" + type + "/RestrictedClasses/_string"); | let restrictedClasses = this.get("Attack/" + type + "/RestrictedClasses/_string"); | ||||
if (!restrictedClasses || !MatchesClassList(target.classes(), restrictedClasses)) | if (!restrictedClasses || !MatchesClassList(target.classes(), restrictedClasses)) | ||||
return true; | return true; | ||||
}; | }; | ||||
return false; | return false; | ||||
}, | }, | ||||
"move": function(x, z, queued = false) { | "move": function(x, z, queued = false) { | ||||
Engine.PostCommand(PlayerID, { "type": "walk", "entities": [this.id()], "x": x, "z": z, "queued": queued }); | Engine.PostCommand(PlayerID, { "type": "walk", "entities": [this.id()], "x": x, "z": z, "queued": queued }); | ||||
return this; | return this; | ||||
}, | }, | ||||
"moveToRange": function(x, z, min, max, queued = false) { | "moveToRange": function(x, z, min, max, queued = false) { | ||||
Engine.PostCommand(PlayerID, { "type": "walk-to-range", "entities": [this.id()], "x": x, "z": z, "min": min, "max": max, "queued": queued }); | Engine.PostCommand(PlayerID, { "type": "walk-to-range", "entities": [this.id()], "x": x, "z": z, "min": min, "max": max, "queued": queued }); | ||||
return this; | return this; | ||||
}, | }, | ||||
"attackMove": function(x, z, targetClasses, allowCapture = true, queued = false) { | "attackMove": function(x, z, targetClasses, prefAttackForms = ["Capture"], prefAttackTypes = undefined, queued = false) { | ||||
Engine.PostCommand(PlayerID, { "type": "attack-walk", "entities": [this.id()], "x": x, "z": z, "targetClasses": targetClasses, "allowCapture": allowCapture, "queued": queued }); | Engine.PostCommand(PlayerID, { "type": "attack-walk", "entities": [this.id()], "x": x, "z": z, "targetClasses": targetClasses, "prefAttackForms": prefAttackForms, "prefAttackTypes": prefAttackTypes, "queued": queued }); | ||||
return this; | return this; | ||||
}, | }, | ||||
// violent, aggressive, defensive, passive, standground | // violent, aggressive, defensive, passive, standground | ||||
"setStance": function(stance, queued = false) { | "setStance": function(stance, queued = false) { | ||||
if (this.getStance() === undefined) | if (this.getStance() === undefined) | ||||
return undefined; | return undefined; | ||||
Engine.PostCommand(PlayerID, { "type": "stance", "entities": [this.id()], "name": stance, "queued": queued }); | Engine.PostCommand(PlayerID, { "type": "stance", "entities": [this.id()], "name": stance, "queued": queued }); | ||||
Show All 19 Lines | "unloadAll": function() { | ||||
return this; | return this; | ||||
}, | }, | ||||
"garrison": function(target, queued = false) { | "garrison": function(target, queued = false) { | ||||
Engine.PostCommand(PlayerID, { "type": "garrison", "entities": [this.id()], "target": target.id(), "queued": queued }); | Engine.PostCommand(PlayerID, { "type": "garrison", "entities": [this.id()], "target": target.id(), "queued": queued }); | ||||
return this; | return this; | ||||
}, | }, | ||||
"attack": function(unitId, allowCapture = true, queued = false) { | "attack": function(unitId, prefAttackForms = ["Capture"], prefAttackTypes = undefined, queued = false) { | ||||
Engine.PostCommand(PlayerID, { "type": "attack", "entities": [this.id()], "target": unitId, "allowCapture": allowCapture, "queued": queued }); | Engine.PostCommand(PlayerID, { "type": "attack", "entities": [this.id()], "target": unitId, "prefAttackForms": prefAttackForms, "prefAttackTypes": prefAttackTypes, "queued": queued }); | ||||
return this; | return this; | ||||
}, | }, | ||||
// moveApart from a point in the opposite direction with a distance dist | // moveApart from a point in the opposite direction with a distance dist | ||||
"moveApart": function(point, dist) { | "moveApart": function(point, dist) { | ||||
if (this.position() !== undefined) { | if (this.position() !== undefined) { | ||||
let direction = [this.position()[0] - point[0], this.position()[1] - point[1]]; | let direction = [this.position()[0] - point[0], this.position()[1] - point[1]]; | ||||
let norm = m.VectorDistance(point, this.position()); | let norm = m.VectorDistance(point, this.position()); | ||||
▲ Show 20 Lines • Show All 145 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
Is this needed?