1
0
forked from 0ad/0ad

Petra: Look for aquatic treasure on naval maps

Patch by Sandarac

Reviewed By: mimo
Differential Revision: https://code.wildfiregames.com/D765
This was SVN commit r20108.
This commit is contained in:
mimo 2017-09-04 18:06:02 +00:00
parent bce425ede5
commit a3b9d16eff
4 changed files with 67 additions and 46 deletions

View File

@ -99,7 +99,7 @@ m.getLandAccess = function(gameState, ent)
return access;
};
m.getSeaAccess = function(gameState, ent)
m.getSeaAccess = function(gameState, ent, warning = true)
{
let sea = ent.getMetadata(PlayerID, "sea");
if (!sea)
@ -118,7 +118,7 @@ m.getSeaAccess = function(gameState, ent)
break;
}
}
if (sea < 2)
if (warning && sea < 2)
API3.warn("ERROR in Petra getSeaAccess because of position with sea index " + sea);
ent.setMetadata(PlayerID, "sea", sea);
}
@ -317,6 +317,50 @@ m.isLineInsideEnemyTerritory = function(gameState, pos1, pos2, step=70)
return false;
};
m.gatherTreasure = function(gameState, ent, water = false)
{
if (!gameState.ai.HQ.treasures.hasEntities())
return false;
if (!ent || !ent.position())
return false;
let rates = ent.resourceGatherRates();
if (!rates || !rates.treasure || rates.treasure <= 0)
return false;
let treasureFound;
let distmin = Math.min();
let access = gameState.ai.accessibility.getAccessValue(ent.position(), water);
for (let treasure of gameState.ai.HQ.treasures.values())
{
if (m.IsSupplyFull(gameState, treasure))
continue;
// let some time for the previous gatherer to reach the treasure before trying again
let lastGathered = treasure.getMetadata(PlayerID, "lastGathered");
if (lastGathered && gameState.ai.elapsedTime - lastGathered < 20)
continue;
if (!water && access !== m.getLandAccess(gameState, treasure))
continue;
if (water && access !== m.getSeaAccess(gameState, treasure, false))
continue;
let territoryOwner = gameState.ai.HQ.territoryMap.getOwner(treasure.position());
if (territoryOwner !== 0 && !gameState.isPlayerAlly(territoryOwner))
continue;
let dist = API3.SquareVectorDistance(ent.position(), treasure.position());
if (dist > 120000 || territoryOwner !== PlayerID && dist > 14000) // AI has no LOS, so restrict it a bit
continue;
if (dist > distmin)
continue;
distmin = dist;
treasureFound = treasure;
}
if (!treasureFound)
return false;
treasureFound.setMetadata(PlayerID, "lastGathered", gameState.ai.elapsedTime);
ent.gather(treasureFound);
gameState.ai.HQ.AddTCGatherer(treasureFound.id());
ent.setMetadata(PlayerID, "supply", treasureFound.id());
return true;
};
m.dumpEntity = function(ent)
{
if (!ent)

View File

@ -550,8 +550,19 @@ m.NavalManager.prototype.moveApart = function(gameState)
let sea = ship.getMetadata(PlayerID, "sea");
if (ship.getMetadata(PlayerID, "transporter") === undefined)
{
if (ship.isIdle()) // do not stay idle near a dock to not disturb other ships
if (ship.isIdle())
{
// Check if there are some treasure around
let currentPos = ship.position();
if (!currentPos)
return;
let treasurePosChecked = ship.getMetadata(PlayerID, "treasurePosChecked");
if ((!treasurePosChecked || treasurePosChecked[0] != currentPos[0] ||
treasurePosChecked[1] != currentPos[1]) &&
m.gatherTreasure(gameState, ship, true))
return;
ship.setMetadata(PlayerID, "treasurePosChecked", currentPos);
// Do not stay idle near a dock to not disturb other ships
gameState.getAllyStructures().filter(API3.Filters.byClass("Dock")).forEach(function(dock) {
if (dock.getMetadata(PlayerID, "sea") !== sea)
return;

View File

@ -113,11 +113,18 @@ m.TradeManager.prototype.trainMoreTraders = function(gameState, queues)
m.TradeManager.prototype.updateTrader = function(gameState, ent)
{
if (ent.hasClass("Ship") && gameState.ai.playedTurn % 5 === 0 &&
!ent.unitAIState().startsWith("INDIVIDUAL.GATHER") &&
m.gatherTreasure(gameState, ent, true))
return;
if (!this.hasTradeRoute() || !ent.isIdle() || !ent.position())
return;
if (ent.getMetadata(PlayerID, "transport") !== undefined)
return;
// TODO if the trader is idle and has workOrders, restore them to avoid losing the current gain
Engine.ProfileStart("Trade Manager");
let access = ent.hasClass("Ship") ? ent.getMetadata(PlayerID, "sea") : gameState.ai.accessibility.getAccessValue(ent.position());
let route = this.checkRoutes(gameState, access);

View File

@ -326,7 +326,7 @@ m.Worker.prototype.startGathering = function(gameState)
let access = gameState.ai.accessibility.getAccessValue(this.ent.position());
// First look for possible treasure if any
if (this.gatherTreasure(gameState))
if (m.gatherTreasure(gameState, this.ent))
return true;
let resource = this.ent.getMetadata(PlayerID, "gather-type");
@ -609,7 +609,7 @@ m.Worker.prototype.startGathering = function(gameState)
m.Worker.prototype.startHunting = function(gameState, position)
{
// First look for possible treasure if any
if (!position && this.gatherTreasure(gameState))
if (!position && m.gatherTreasure(gameState, this.ent))
return true;
let resources = gameState.getHuntableSupplies();
@ -855,47 +855,6 @@ m.Worker.prototype.buildAnyField = function(gameState, baseID)
return bestFarmEnt;
};
/**
* Look for some treasure to gather
*/
m.Worker.prototype.gatherTreasure = function(gameState)
{
let rates = this.ent.resourceGatherRates();
if (!rates || !rates.treasure || rates.treasure <= 0)
return false;
let treasureFound;
let distmin = Math.min();
let access = gameState.ai.accessibility.getAccessValue(this.ent.position());
for (let treasure of gameState.ai.HQ.treasures.values())
{
if (m.IsSupplyFull(gameState, treasure))
continue;
// let some time for the previous gatherer to reach the treasure befor trying again
let lastGathered = treasure.getMetadata(PlayerID, "lastGathered");
if (lastGathered && gameState.ai.elapsedTime - lastGathered < 20)
continue;
if (access !== m.getLandAccess(gameState, treasure))
continue;
let territoryOwner = gameState.ai.HQ.territoryMap.getOwner(treasure.position());
if (territoryOwner !== 0 && !gameState.isPlayerAlly(territoryOwner))
continue;
let dist = API3.SquareVectorDistance(this.ent.position(), treasure.position());
if (territoryOwner !== PlayerID && dist > 14000) // AI has no LOS, so restrict it a bit
continue;
if (dist > distmin)
continue;
distmin = dist;
treasureFound = treasure;
}
if (!treasureFound)
return false;
treasureFound.setMetadata(PlayerID, "lastGathered", gameState.ai.elapsedTime);
this.ent.gather(treasureFound);
gameState.ai.HQ.AddTCGatherer(treasureFound.id());
this.ent.setMetadata(PlayerID, "supply", treasureFound.id());
return true;
};
/**
* Workers elephant should move away from the buildings they've built to avoid being trapped in between constructions
* For the time being, we move towards the nearest gatherer (providing him a dropsite)