petra: fix a side effect of d5dcb0c61e

Differential Revision: https://code.wildfiregames.com/D607
This was SVN commit r19756.
This commit is contained in:
mimo
2017-06-09 17:07:50 +00:00
parent 395fe8a86d
commit 57fbcab3bf
3 changed files with 82 additions and 19 deletions
@@ -504,28 +504,41 @@ m.AttackManager.prototype.raidTargetEntity = function(gameState, ent)
};
/**
* Response to the capture of one of our structure:
* transform all defense armies around into a new attack army and target this structure
* Switch defense armies into an attack one against the given target
* 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;
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 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)
return false;
this.totalNumber++;
attackPlan.init(gameState);
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)
{
let army = gameState.ai.HQ.defenseManager.armies[i];
army.recalculatePosition(gameState);
if (API3.SquareVectorDistance(pos, army.foePosition) > range*range)
if (data.range)
{
army.recalculatePosition(gameState);
if (API3.SquareVectorDistance(pos, army.foePosition) > data.range * data.range)
continue;
}
else if (army.ID != +data.armyID)
continue;
while (army.foeEntities.length > 0)
army.removeFoe(gameState, army.foeEntities[0]);
while (army.ownEntities.length > 0)
@@ -539,16 +552,15 @@ m.AttackManager.prototype.counterAttack = function(gameState, ent, range=150)
attackPlan.unitCollection.updateEnt(unit);
}
}
gameState.ai.HQ.defenseManager.armies.splice(i--, 1);
}
if (!attackPlan.unitCollection.hasEntities())
{
attackPlan.Abort(gameState);
return false;
}
attackPlan.targetPlayer = ent.owner();
attackPlan.targetPlayer = target.owner();
attackPlan.targetPos = pos;
attackPlan.target = ent;
attackPlan.target = target;
attackPlan.state = "arrived";
return true;
};
@@ -28,6 +28,8 @@ m.AttackPlan = function(gameState, Config, uniqueID, type, data)
this.targetPlayer = undefined;
}
this.uniqueTargetId = data && data.uniqueTargetId || undefined;
// get a starting rallyPoint ... will be improved later
let rallyPoint;
let rallyAccess;
@@ -712,6 +714,9 @@ m.AttackPlan.prototype.chooseTarget = function(gameState)
this.target = this.getNearestTarget(gameState, this.rallyPoint);
if (!this.target)
{
if (this.uniqueTargetId)
return false;
// may-be all our previous enemey target (if not recomputed here) have been destroyed ?
this.targetPlayer = gameState.ai.HQ.attackManager.getEnemyPlayer(gameState, this);
if (this.targetPlayer !== undefined)
@@ -782,12 +787,22 @@ m.AttackPlan.prototype.getNearestTarget = function(gameState, position, sameLand
this.isBlocked = false;
let targets;
if (this.type === "Raid")
targets = this.raidTargetFinder(gameState);
else if (this.type === "Rush" || this.type === "Attack")
targets = this.rushTargetFinder(gameState, this.targetPlayer);
if (this.uniqueTargetId)
{
targets = new API3.EntityCollection(gameState.sharedScript);
let ent = gameState.getEntityById(this.uniqueTargetId);
if (ent)
targets.addEnt(ent);
}
else
targets = this.defaultTargetFinder(gameState, this.targetPlayer);
{
if (this.type === "Raid")
targets = this.raidTargetFinder(gameState);
else if (this.type === "Rush" || this.type === "Attack")
targets = this.rushTargetFinder(gameState, this.targetPlayer);
else
targets = this.defaultTargetFinder(gameState, this.targetPlayer);
}
if (!targets.hasEntities())
return undefined;
@@ -1788,6 +1803,9 @@ m.AttackPlan.prototype.UpdateTarget = function(gameState, events)
this.target = this.getNearestTarget(gameState, this.position, true);
if (!this.target)
{
if (this.uniqueTargetId)
return false;
// Check if we could help any current attack
let attackManager = gameState.ai.HQ.attackManager;
let accessIndex = gameState.ai.accessibility.getAccessValue(this.position);
@@ -1978,6 +1996,7 @@ m.AttackPlan.prototype.Serialize = function()
"targetPlayer": this.targetPlayer,
"target": this.target !== undefined ? this.target.id() : undefined,
"targetPos": this.targetPos,
"uniqueTargetId": this.uniqueTargetId,
"path": this.path
};
@@ -266,6 +266,7 @@ m.DefenseManager.prototype.checkEnemyArmies = function(gameState)
if (army.getState() === 0)
{
this.switchToAttack(gameState, army);
army.clear(gameState);
this.armies.splice(i--,1);
continue;
@@ -347,6 +348,7 @@ m.DefenseManager.prototype.checkEnemyArmies = function(gameState)
if (stillDangerous)
continue;
this.switchToAttack(gameState, army);
army.clear(gameState);
this.armies.splice(i--,1);
}
@@ -471,7 +473,7 @@ m.DefenseManager.prototype.checkEvents = function(gameState, events)
{
let ent = gameState.getEntityById(evt.entity);
if (ent && ent.hasClass("CivCentre")) // one of our cc has been captured
gameState.ai.HQ.attackManager.counterAttack(gameState, ent);
gameState.ai.HQ.attackManager.switchDefenseToAttack(gameState, ent, { "range": 150 });
}
}
@@ -725,6 +727,36 @@ m.DefenseManager.prototype.GetCooperationLevel = function(ent)
return cooperation;
};
/**
* Switch a defense army into an attack if needed
*/
m.DefenseManager.prototype.switchToAttack = function(gameState, army)
{
if (!army)
return;
for (let targetId of this.targetList)
{
let target = gameState.getEntityById(targetId);
if (!target || !target.position() || !gameState.isPlayerEnemy(target.owner()))
continue;
let targetAccess = m.getLandAccess(gameState, target);
let targetPos = target.position();
for (let entId of army.ownEntities)
{
let ent = gameState.getEntityById(entId);
if (!ent)
continue;
let pos = ent.position();
if (!pos || gameState.ai.accessibility.getAccessValue(pos) !== targetAccess)
continue;
if (API3.SquareVectorDistance(targetPos, pos) > 14400)
continue;
gameState.ai.HQ.attackManager.switchDefenseToAttack(gameState, target, { "armyID": army.ID, "uniqueTarget": true });
return;
}
}
};
m.DefenseManager.prototype.Serialize = function()
{
let properties = {