1
0
forked from mirrors/0ad

Petra: Capture gaia relics

Summary:
Petra will capture gaia relics on occasion. Because the AI has access to
all of the map and all entities in the game, these gaia capture events
have to be spaced out quite a bit to make things fair.

Reviewed By: mimo
Differential Revision: https://code.wildfiregames.com/D333
This was SVN commit r19596.
This commit is contained in:
mimo
2017-05-16 17:33:31 +00:00
parent 8156d297ea
commit 921c89d3a6
4 changed files with 33 additions and 11 deletions
@@ -362,24 +362,27 @@ m.AttackManager.prototype.getEnemyPlayer = function(gameState, attack)
}
else if (gameState.getGameType() === "capture_the_relic")
{
// Target the player with the most relics
// Target the player with the most relics (including gaia)
let allRelics = gameState.updatingGlobalCollection("allRelics", API3.Filters.byClass("Relic"));
let maxRelicsOwned = 0;
// TODO: target gaia relics
for (let i = 1; i < gameState.sharedScript.playersData.length; ++i)
for (let i = 0; i < gameState.sharedScript.playersData.length; ++i)
{
if (!gameState.isPlayerEnemy(i) || this.defeated[i])
if (!gameState.isPlayerEnemy(i) || this.defeated[i] || i === 0 &&
!gameState.ai.HQ.gameTypeManager.tryCaptureGaiaRelic)
continue;
let relicsCount = gameState.getEnemyUnits(i).filter(API3.Filters.byClass("Relic")).length;
let relicsCount = allRelics.filter(relic => relic.owner() === i).length;
if (relicsCount <= maxRelicsOwned)
continue;
maxRelicsOwned = relicsCount;
enemyPlayer = i;
}
if (enemyPlayer)
if (enemyPlayer !== undefined)
{
if (attack.targetPlayer === undefined)
this.currentEnemyPlayer = enemyPlayer;
if (enemyPlayer === 0)
gameState.ai.HQ.gameTypeManager.tryCaptureGaiaRelic = false;
return enemyPlayer;
}
}
@@ -479,7 +482,7 @@ m.AttackManager.prototype.getEnemyPlayer = function(gameState, attack)
};
/** f.e. if we have changed diplomacy with another player. */
m.AttackManager.prototype.cancelAttacksAgainstPlayer = function(player)
m.AttackManager.prototype.cancelAttacksAgainstPlayer = function(gameState, player)
{
for (let attackType in this.upcomingAttacks)
for (let attack of this.upcomingAttacks[attackType])
@@ -798,6 +798,8 @@ m.AttackPlan.prototype.getNearestTarget = function(gameState, position, sameLand
let minDist = Math.min();
for (let ent of targets.values())
{
if (this.targetPlayer === 0 && gameState.getGameType() === "capture_the_relic" && !ent.hasClass("Relic"))
continue;
if (!ent.position())
continue;
if (sameLand && gameState.ai.accessibility.getAccessValue(ent.position()) !== land)
@@ -835,7 +837,7 @@ m.AttackPlan.prototype.defaultTargetFinder = function(gameState, playerEnemy)
else if (gameState.getGameType() === "regicide")
targets = gameState.getEnemyUnits(playerEnemy).filter(API3.Filters.byClass("Hero"));
else if (gameState.getGameType() === "capture_the_relic")
targets = gameState.getEnemyUnits(playerEnemy).filter(API3.Filters.byClass("Relic"));
targets = gameState.updatingGlobalCollection("allRelics", API3.Filters.byClass("Relic")).filter(relic => relic.owner() === playerEnemy);
if (targets && targets.hasEntities())
return targets;
@@ -322,7 +322,7 @@ m.DiplomacyManager.prototype.handleDiplomacyRequest = function(gameState, player
m.DiplomacyManager.prototype.changePlayerDiplomacy = function(gameState, player, newDiplomaticStance)
{
if (gameState.isPlayerEnemy(player) && (newDiplomaticStance === "ally" || newDiplomaticStance === "neutral"))
gameState.ai.HQ.attackManager.cancelAttacksAgainstPlayer(player);
gameState.ai.HQ.attackManager.cancelAttacksAgainstPlayer(gameState, player);
Engine.PostCommand(PlayerID, { "type": "diplomacy", "player": player, "to": newDiplomaticStance });
if (this.Config.debug > 1)
API3.warn("diplomacy stance with player " + player + " is now " + newDiplomaticStance);
@@ -13,6 +13,8 @@ m.GameTypeManager = function(Config)
// Holds ids of all ents who are (or can be) guarding and if the ent is currently guarding
this.guardEnts = new Map();
this.healersPerCriticalEnt = 2 + Math.round(this.Config.personality.defensive * 2);
this.tryCaptureGaiaRelic = false;
this.tryCaptureGaiaRelicLapseTime = -1;
};
/**
@@ -244,7 +246,11 @@ m.GameTypeManager.prototype.checkEvents = function(gameState, events)
this.criticalEnts.set(ent.id(), { "guardsAssigned": 0, "guards": new Map() });
// Move captured relics to the closest base
if (ent.hasClass("Unit"))
{
this.pickCriticalEntRetreatLocation(gameState, ent, false);
if (evt.from === 0)
gameState.ai.HQ.attackManager.cancelAttacksAgainstPlayer(gameState, evt.from);
}
}
}
};
@@ -399,7 +405,8 @@ m.GameTypeManager.prototype.pickCriticalEntRetreatLocation = function(gameState,
return;
// Couldn't find a place to garrison, so the ent will flee from attacks
criticalEnt.setStance("passive");
if (!criticalEnt.hasClass("Relic"))
criticalEnt.setStance("passive");
let accessIndex = gameState.ai.accessibility.getAccessValue(criticalEnt.position());
let basePos = m.getBestBase(gameState, criticalEnt, true);
if (basePos && basePos.accessIndex == accessIndex)
@@ -516,7 +523,15 @@ m.GameTypeManager.prototype.update = function(gameState, events, queues)
}
if (gameState.getGameType() === "capture_the_relic" && gameState.ai.playedTurn % 10 === 0)
{
this.manageCriticalEntGuards(gameState);
// Do not capture gaia relics frequently, as the ai has access to the entire map
if (gameState.ai.elapsedTime > this.tryCaptureGaiaRelicLapseTime && !this.tryCaptureGaiaRelic)
{
this.tryCaptureGaiaRelic = true;
this.tryCaptureGaiaRelicLapseTime = gameState.ai.elapsedTime + (5 - 0.5 * (this.Config.difficulty - 3) * 60);
}
}
};
m.GameTypeManager.prototype.Serialize = function()
@@ -524,7 +539,9 @@ m.GameTypeManager.prototype.Serialize = function()
return {
"criticalEnts": this.criticalEnts,
"guardEnts": this.guardEnts,
"healersPerCriticalEnt": this.healersPerCriticalEnt
"healersPerCriticalEnt": this.healersPerCriticalEnt,
"tryCaptureGaiaRelic": this.tryCaptureGaiaRelic,
"tryCaptureGaiaRelicLapseTime": this.tryCaptureGaiaRelicLapseTime
};
};