Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/ai/petra/attackManager.js
Show First 20 Lines • Show All 498 Lines • ▼ Show 20 Lines | if (!attackPlan.failed) | ||||
this.totalNumber++; | this.totalNumber++; | ||||
attackPlan.init(gameState); | attackPlan.init(gameState); | ||||
this.upcomingAttacks.Raid.push(attackPlan); | this.upcomingAttacks.Raid.push(attackPlan); | ||||
} | } | ||||
this.raidNumber++; | this.raidNumber++; | ||||
}; | }; | ||||
/** | /** | ||||
* Response to the capture of one of our structure: | * Switch defense armies into an attack one against the given target | ||||
* transform all defense armies around into a new attack army and target this structure | * data.range: transform all defense armies inside range of the target into a new attack | ||||
* data.armyID: transform only the defense army ID into a new attack | |||||
* data.uniqueTarget: the attack will stop when the target is destroyed or captured | |||||
*/ | */ | ||||
m.AttackManager.prototype.counterAttack = function(gameState, ent, range=150) | m.AttackManager.prototype.switchDefenseToAttack = function(gameState, target, data) | ||||
{ | { | ||||
if (!ent || !ent.position()) | if (!target || !target.position()) | ||||
return false; | return false; | ||||
let pos = ent.position(); | if (!data.range && !data.armyID) | ||||
{ | |||||
API3.warn(" attackManager.switchToAttack inconsistent data " + uneval(data)); | |||||
return false; | |||||
} | |||||
attackData = data.uniqueTarget ? { "uniqueTargetId": target.id() } : undefined; | |||||
let pos = target.position(); | |||||
let attackType = "Attack"; | let attackType = "Attack"; | ||||
let attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, attackType); | let attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, attackType, attackData); | ||||
if (attackPlan.failed) | if (attackPlan.failed) | ||||
return false; | return false; | ||||
this.totalNumber++; | this.totalNumber++; | ||||
attackPlan.init(gameState); | attackPlan.init(gameState); | ||||
this.startedAttacks[attackType].push(attackPlan); | this.startedAttacks[attackType].push(attackPlan); | ||||
for (let i = 0; i < gameState.ai.HQ.defenseManager.armies.length; ++i) | for (let army of gameState.ai.HQ.defenseManager.armies) | ||||
{ | |||||
if (data.range) | |||||
{ | { | ||||
let army = gameState.ai.HQ.defenseManager.armies[i]; | |||||
army.recalculatePosition(gameState); | army.recalculatePosition(gameState); | ||||
if (API3.SquareVectorDistance(pos, army.foePosition) > range*range) | if (API3.SquareVectorDistance(pos, army.foePosition) > data.range * data.range) | ||||
continue; | continue; | ||||
} | |||||
else if (army.ID != +data.armyID) | |||||
continue; | |||||
while (army.foeEntities.length > 0) | while (army.foeEntities.length > 0) | ||||
army.removeFoe(gameState, army.foeEntities[0]); | army.removeFoe(gameState, army.foeEntities[0]); | ||||
while (army.ownEntities.length > 0) | while (army.ownEntities.length > 0) | ||||
{ | { | ||||
let unitId = army.ownEntities[0]; | let unitId = army.ownEntities[0]; | ||||
army.removeOwn(gameState, unitId); | army.removeOwn(gameState, unitId); | ||||
let unit = gameState.getEntityById(unitId); | let unit = gameState.getEntityById(unitId); | ||||
if (unit && attackPlan.isAvailableUnit(gameState, unit)) | if (unit && attackPlan.isAvailableUnit(gameState, unit)) | ||||
{ | { | ||||
unit.setMetadata(PlayerID, "plan", attackPlan.name); | unit.setMetadata(PlayerID, "plan", attackPlan.name); | ||||
attackPlan.unitCollection.updateEnt(unit); | attackPlan.unitCollection.updateEnt(unit); | ||||
} | } | ||||
} | } | ||||
gameState.ai.HQ.defenseManager.armies.splice(i--, 1); | |||||
} | } | ||||
if (!attackPlan.unitCollection.hasEntities()) | if (!attackPlan.unitCollection.hasEntities()) | ||||
{ | { | ||||
attackPlan.Abort(gameState); | attackPlan.Abort(gameState); | ||||
return false; | return false; | ||||
} | } | ||||
attackPlan.targetPlayer = ent.owner(); | attackPlan.targetPlayer = target.owner(); | ||||
attackPlan.targetPos = pos; | attackPlan.targetPos = pos; | ||||
attackPlan.target = ent; | attackPlan.target = target; | ||||
attackPlan.state = "arrived"; | attackPlan.state = "arrived"; | ||||
return true; | return true; | ||||
}; | }; | ||||
m.AttackManager.prototype.Serialize = function() | m.AttackManager.prototype.Serialize = function() | ||||
{ | { | ||||
let properties = { | let properties = { | ||||
"totalNumber": this.totalNumber, | "totalNumber": this.totalNumber, | ||||
Sandarac: It seems this function contains a lot of duplicated code that is also in `counterAttack`. It… | |||||
"attackNumber": this.attackNumber, | "attackNumber": this.attackNumber, | ||||
"rushNumber": this.rushNumber, | "rushNumber": this.rushNumber, | ||||
"raidNumber": this.raidNumber, | "raidNumber": this.raidNumber, | ||||
"debugTime": this.debugTime, | "debugTime": this.debugTime, | ||||
"maxRushes": this.maxRushes, | "maxRushes": this.maxRushes, | ||||
"rushSize": this.rushSize, | "rushSize": this.rushSize, | ||||
"currentEnemyPlayer": this.currentEnemyPlayer, | "currentEnemyPlayer": this.currentEnemyPlayer, | ||||
"defeated": this.defeated | "defeated": this.defeated | ||||
▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
It seems this function contains a lot of duplicated code that is also in counterAttack. It seems that the main difference between them is that in counterAttack there is the loop on defenseManager.armies, so maybe they should be merged, and there could be a parameter that determines if all defense armies should be checked, or just use a single army passed to the function.