Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js @@ -99,7 +99,7 @@ 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 @@ 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 @@ 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) Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/navalManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/navalManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/navalManager.js @@ -550,8 +550,19 @@ 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; Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js @@ -113,11 +113,18 @@ 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); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/worker.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/worker.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/worker.js @@ -326,7 +326,7 @@ 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.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(); @@ -856,47 +856,6 @@ }; /** - * 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) */