diff --git a/binaries/data/mods/public/simulation/ai/petra/navalManager.js b/binaries/data/mods/public/simulation/ai/petra/navalManager.js index 9de180017a..f916049ec4 100644 --- a/binaries/data/mods/public/simulation/ai/petra/navalManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/navalManager.js @@ -175,10 +175,19 @@ m.NavalManager.prototype.init = function(gameState, deserializing) this.setDockIndex(gameState, dock); }; -m.NavalManager.prototype.resetFishingBoats = function(gameState) +m.NavalManager.prototype.updateFishingBoats = function(sea, num) { - for (let i = 0; i < gameState.ai.accessibility.regionSize.length; ++i) - this.wantedFishShips[i] = 0; + if (this.wantedFishShips[sea]) + this.wantedFishShips[sea] = num; +}; + +m.NavalManager.prototype.resetFishingBoats = function(gameState, sea) +{ + if (sea !== undefined) + this.wantedFishShips[sea] = 0; + else + for (let i = 0; i < gameState.ai.accessibility.regionSize.length; ++i) + this.wantedFishShips[i] = 0; }; m.NavalManager.prototype.setShipIndex = function(gameState, ship) @@ -227,7 +236,7 @@ m.NavalManager.prototype.getDockIndex = function(gameState, dock, onWater) return index; }; -// get the list of seas around this region not connected by a dock +// get the list of seas (or lands) around this region not connected by a dock m.NavalManager.prototype.getUnconnectedSeas = function(gameState, region) { var seas = gameState.ai.accessibility.regionLinks[region].slice(); diff --git a/binaries/data/mods/public/simulation/ai/petra/queueManager.js b/binaries/data/mods/public/simulation/ai/petra/queueManager.js index 96c8c3d7d7..80bfb42d6f 100644 --- a/binaries/data/mods/public/simulation/ai/petra/queueManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/queueManager.js @@ -426,6 +426,19 @@ m.QueueManager.prototype.checkPausedQueues = function(gameState) toBePaused = (q === "civilCentre" || q === "defenseBuilding" || q == "majorTech" || q.indexOf("_siege") != -1 || q.indexOf("_champ") != -1); + if (toBePaused) + { + if (q === "field" && gameState.ai.HQ.needFarm && + gameState.getOwnStructures().filter(API3.Filters.byClass("Field")).length === 0) + toBePaused = false; + if (q === "dock" && gameState.ai.HQ.needFish && + gameState.getOwnStructures().filter(API3.Filters.byClass("Dock")).length === 0) + toBePaused = false; + if (q === "ships" && gameState.ai.HQ.needFish && + gameState.ai.HQ.navalManager.ships.filter(API3.Filters.byClass("FishingBoat")).length === 0) + toBePaused = false; + } + let queue = this.queues[q]; if (!queue.paused && toBePaused) { diff --git a/binaries/data/mods/public/simulation/ai/petra/startingStrategy.js b/binaries/data/mods/public/simulation/ai/petra/startingStrategy.js index e16214a147..3104f2e637 100644 --- a/binaries/data/mods/public/simulation/ai/petra/startingStrategy.js +++ b/binaries/data/mods/public/simulation/ai/petra/startingStrategy.js @@ -414,6 +414,7 @@ m.HQ.prototype.configFirstBase = function(gameState) return; var startingSize = 0; + var startingLand = []; for (let region in this.landRegions) { for (let base of this.baseManagers) @@ -421,6 +422,7 @@ m.HQ.prototype.configFirstBase = function(gameState) if (!base.anchor || base.accessIndex != +region) continue; startingSize += gameState.ai.accessibility.regionSize[region]; + startingLand.push(base.accessIndex); break; } } @@ -432,12 +434,46 @@ m.HQ.prototype.configFirstBase = function(gameState) { this.saveSpace = true; this.Config.Economy.popForDock = Math.min(this.Config.Economy.popForDock, 16); - this.Config.Economy.targetNumFishers = Math.max(this.Config.Economy.targetNumFishers, 2); + let num = Math.max(this.Config.Economy.targetNumFishers, 2); + for (let land of startingLand) + { + for (let sea of gameState.ai.accessibility.regionLinks[land]) + { + if (gameState.ai.HQ.navalRegions[sea]) + this.navalManager.updateFishingBoats(sea, num); + } + } } + // - count the available wood resource, and react accordingly + var startingFood = gameState.getResources().food; + var check = {}; + for (let proxim of ["nearby", "medium", "faraway"]) + { + for (let base of this.baseManagers) + { + for (let supply of base.dropsiteSupplies.food[proxim]) + { + if (check[supply.id]) // avoid double counting as same resource can appear several time + continue; + check[supply.id] = true; + startingFood += supply.ent.resourceSupplyAmount(); + } + } + } + if (startingFood < 800) + { + if (startingSize < 24000) + { + this.needFish = true; + this.Config.Economy.popForDock = 1; + } + else + this.needFarm = true; + } // - count the available wood resource, and allow rushes only if enough (we should otherwise favor expansion) var startingWood = gameState.getResources().wood; - var check = {}; + check = {}; for (let proxim of ["nearby", "medium", "faraway"]) { for (let base of this.baseManagers) @@ -454,7 +490,10 @@ m.HQ.prototype.configFirstBase = function(gameState) if (this.Config.debug > 1) API3.warn("startingWood: " + startingWood + " (cut at 8500 for no rush and 6000 for saveResources)"); if (startingWood < 6000) + { this.saveResources = true; + this.Config.Economy.popForTown = 40; // Switch to town phase as soon as possible to be able to expand + } if (startingWood > 8500 && this.canBuildUnits) { let allowed = Math.ceil((startingWood - 8500) / 3000); diff --git a/binaries/data/mods/public/simulation/ai/petra/worker.js b/binaries/data/mods/public/simulation/ai/petra/worker.js index 3f99dc1a2e..a05243384b 100644 --- a/binaries/data/mods/public/simulation/ai/petra/worker.js +++ b/binaries/data/mods/public/simulation/ai/petra/worker.js @@ -50,8 +50,13 @@ m.Worker.prototype.update = function(gameState, ent) var unitAIStateOrder = unitAIState.split(".")[1]; // If we're fighting or hunting, let's not start gathering + // but for fishers where UnitAI must have made us target a moving whale. if (unitAIStateOrder === "COMBAT") + { + if (subrole === "fisher") + this.startFishing(gameState); return; + } // Okay so we have a few tasks. // If we're gathering, we'll check that we haven't run idle. @@ -648,24 +653,27 @@ m.Worker.prototype.startFishing = function(gameState) return distMin; }; + var exhausted = true; resources.forEach(function(supply) { if (!supply.position()) return; - if (m.IsSupplyFull(gameState, supply)) - return; - // check if available resource is worth one additionnal gatherer (except for farms) - var nbGatherers = supply.resourceSupplyNumGatherers() + gameState.ai.HQ.GetTCGatherer(supply.id()); - if (nbGatherers > 0 && supply.resourceSupplyAmount()/(1+nbGatherers) < 30) - return; - // check that it is accessible if (!supply.getMetadata(PlayerID, "sea")) supply.setMetadata(PlayerID, "sea", gameState.ai.accessibility.getAccessValue(supply.position(), true)); if (supply.getMetadata(PlayerID, "sea") !== fisherSea) return; + exhausted = false; + + if (m.IsSupplyFull(gameState, supply)) + return; + // check if available resource is worth one additionnal gatherer (except for farms) + var nbGatherers = supply.resourceSupplyNumGatherers() + gameState.ai.HQ.GetTCGatherer(supply.id()); + if (nbGatherers > 0 && supply.resourceSupplyAmount()/(1+nbGatherers) < 30) + return; + // measure the distance to the resource var dist = API3.SquareVectorDistance(entPosition, supply.position()); if (dist > 40000) @@ -686,6 +694,13 @@ m.Worker.prototype.startFishing = function(gameState) nearestSupply = supply; } }); + + if (exhausted) + { + gameState.ai.HQ.navalManager.resetFishingBoats(gameState, fisherSea); + this.ent.destroy(); + return false; + } if (nearestSupply) {