diff --git a/binaries/data/mods/public/simulation/ai/petra/army.js b/binaries/data/mods/public/simulation/ai/petra/army.js index 8f571b882a..e0e2ff981b 100644 --- a/binaries/data/mods/public/simulation/ai/petra/army.js +++ b/binaries/data/mods/public/simulation/ai/petra/army.js @@ -214,37 +214,39 @@ m.Army.prototype.removeOwn = function (gameState, id, Entity) this.assignedTo[id] = undefined; let ent = Entity ? Entity : gameState.getEntityById(id); - if (ent) // TODO recompute strength when no entities (could happen if capture+destroy) + if (!ent) + return true; + + this.evaluateStrength(ent, true, true); + ent.setMetadata(PlayerID, "PartOfArmy", undefined); + if (ent.getMetadata(PlayerID, "plan") === -2) + ent.setMetadata(PlayerID, "plan", -1); + else + ent.setMetadata(PlayerID, "plan", undefined); + + let formerSubrole = ent.getMetadata(PlayerID, "formerSubrole"); + if (formerSubrole !== undefined) + ent.setMetadata(PlayerID, "subrole", formerSubrole); + else + ent.setMetadata(PlayerID, "subrole", undefined); + ent.setMetadata(PlayerID, "formerSubrole", undefined); + +/* + // TODO be sure that all units in the transport need the cancelation + if (!ent.position()) // this unit must still be in a transport plan ... try to cancel it { - this.evaluateStrength(ent, true, true); - ent.setMetadata(PlayerID, "PartOfArmy", undefined); - if (ent.getMetadata(PlayerID, "plan") === -2) - ent.setMetadata(PlayerID, "plan", -1); - else - ent.setMetadata(PlayerID, "plan", undefined); - - let formerSubrole = ent.getMetadata(PlayerID, "formerSubrole"); - if (formerSubrole !== undefined) - ent.setMetadata(PlayerID, "subrole", formerSubrole); - else - ent.setMetadata(PlayerID, "subrole", undefined); - ent.setMetadata(PlayerID, "formerSubrole", undefined); - - // TODO be sure that all units in the transport need the cancelation -/* if (!ent.position()) // this unit must still be in a transport plan ... try to cancel it + let planID = ent.getMetadata(PlayerID, "transport"); + // no plans must mean that the unit was in a ship which was destroyed, so do nothing + if (planID) { - let planID = ent.getMetadata(PlayerID, "transport"); - // no plans must mean that the unit was in a ship which was destroyed, so do nothing - if (planID) - { - if (gameState.ai.Config.debug > 0) - warn("ent from army still in transport plan: plan " + planID + " canceled"); - let plan = gameState.ai.HQ.navalManager.getPlan(planID); - if (plan && !plan.canceled) - plan.cancelTransport(gameState); - } - } */ + if (gameState.ai.Config.debug > 0) + warn("ent from army still in transport plan: plan " + planID + " canceled"); + let plan = gameState.ai.HQ.navalManager.getPlan(planID); + if (plan && !plan.canceled) + plan.cancelTransport(gameState); + } } +*/ return true; }; diff --git a/binaries/data/mods/public/simulation/ai/petra/entityExtend.js b/binaries/data/mods/public/simulation/ai/petra/entityExtend.js index 6b9e6c82df..44e8773329 100644 --- a/binaries/data/mods/public/simulation/ai/petra/entityExtend.js +++ b/binaries/data/mods/public/simulation/ai/petra/entityExtend.js @@ -81,6 +81,44 @@ m.getMaxStrength = function(ent, againstClass) return strength * ent.maxHitpoints() / 100.0; }; +/** Get access and cache it in metadata if not already done */ +m.GetLandAccess = function(gameState, ent) +{ + let access = ent.getMetadata(PlayerID, "access"); + if (!access) + { + access = gameState.ai.accessibility.getAccessValue(ent.position()); + ent.setMetadata(PlayerID, "access", access); + } + return access; +}; + +m.GetSeaAccess = function(gameState, ent) +{ + let sea = ent.getMetadata(PlayerID, "sea"); + if (!sea) + { + sea = gameState.ai.accessibility.getAccessValue(ent.position(), true); + if (sea < 2) // pre-positioned docks are sometimes not well positionned + { + let entPos = ent.position(); + let radius = ent.footprintRadius(); + for (let i = 0; i < 16; ++i) + { + let pos = [ entPos[0] + radius*Math.cos(i*Math.PI/8), + entPos[1] + radius*Math.sin(i*Math.PI/8) ]; + sea = gameState.ai.accessibility.getAccessValue(pos, true); + if (sea >= 2) + break; + } + } + if (sea < 2) + API3.warn("ERROR in Petra GetSeaAccess because of dock position with index " + sea); + ent.setMetadata(PlayerID, "sea", sea); + } + return sea; +}; + /** Decide if we should try to capture or destroy */ m.allowCapture = function(ent, target) { diff --git a/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js b/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js index 053c92e5b1..9804f08aac 100644 --- a/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js @@ -79,15 +79,7 @@ m.GarrisonManager.prototype.update = function(gameState, events) } else { - let ok = false; - for (let order of ent.unitAIOrderData()) - { - if (!order.target || order.target != id) - continue; - ok = true; - break; - } - if (ok) + if (ent.unitAIOrderData().some(order => order.target && order.target == id)) continue; if (ent.getMetadata(PlayerID, "garrisonHolder") == id) { diff --git a/binaries/data/mods/public/simulation/ai/petra/headquarters.js b/binaries/data/mods/public/simulation/ai/petra/headquarters.js index 59e7e75763..bb0e859aa0 100644 --- a/binaries/data/mods/public/simulation/ai/petra/headquarters.js +++ b/binaries/data/mods/public/simulation/ai/petra/headquarters.js @@ -1093,11 +1093,11 @@ m.HQ.prototype.findMarketLocation = function(gameState, template) { if (isNavalMarket && market.hasClass("NavalMarket")) { - if (this.navalManager.getDockIndex(gameState, market, true) !== gameState.ai.accessibility.getAccessValue(pos, true)) + if (m.GetSeaAccess(gameState, market) !== gameState.ai.accessibility.getAccessValue(pos, true)) continue; gainMultiplier = traderTemplatesGains.navalGainMultiplier; } - else if (gameState.ai.accessibility.getAccessValue(market.position()) === index) + else if (m.GetLandAccess(gameState, market) === index) gainMultiplier = traderTemplatesGains.landGainMultiplier; else continue; diff --git a/binaries/data/mods/public/simulation/ai/petra/navalManager.js b/binaries/data/mods/public/simulation/ai/petra/navalManager.js index 217486dbdd..bc2e040ce3 100644 --- a/binaries/data/mods/public/simulation/ai/petra/navalManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/navalManager.js @@ -171,7 +171,7 @@ m.NavalManager.prototype.init = function(gameState, deserializing) for (let ship of this.ships.values()) this.setShipIndex(gameState, ship); for (let dock of this.docks.values()) - this.setDockIndex(gameState, dock); + this.SetAccessIndices(gameState, dock); }; m.NavalManager.prototype.updateFishingBoats = function(sea, num) @@ -188,54 +188,18 @@ m.NavalManager.prototype.resetFishingBoats = function(gameState, sea) this.wantedFishShips.fill(0); }; +m.NavalManager.prototype.SetAccessIndices = function(gameState, ent) +{ + m.GetLandAccess(gameState, ent); + m.GetSeaAccess(gameState, ent); +}; + m.NavalManager.prototype.setShipIndex = function(gameState, ship) { let sea = gameState.ai.accessibility.getAccessValue(ship.position(), true); ship.setMetadata(PlayerID, "sea", sea); }; -m.NavalManager.prototype.setDockIndex = function(gameState, dock) -{ - let land = dock.getMetadata(PlayerID, "access"); - if (land === undefined) - { - land = this.getDockIndex(gameState, dock, false); - dock.setMetadata(PlayerID, "access", land); - } - let sea = dock.getMetadata(PlayerID, "sea"); - if (sea === undefined) - { - sea = this.getDockIndex(gameState, dock, true); - dock.setMetadata(PlayerID, "sea", sea); - } -}; - -/** - * get the indices for our starting docks and those of our allies - * land index when onWater=false, sea indes when true - */ -m.NavalManager.prototype.getDockIndex = function(gameState, dock, onWater) -{ - let index = gameState.ai.accessibility.getAccessValue(dock.position(), onWater); - if (index < 2) - { - // pre-positioned docks are sometimes not well positionned - let dockPos = dock.position(); - let radius = dock.footprintRadius(); - for (let i = 0; i < 16; i++) - { - let pos = [ dockPos[0] + radius*Math.cos(i*Math.PI/8), dockPos[1] + radius*Math.sin(i*Math.PI/8)]; - - index = gameState.ai.accessibility.getAccessValue(pos, onWater); - if (index >= 2) - break; - } - } - if (index < 2) - API3.warn("ERROR in Petra navalManager because of dock position (onWater=" + onWater + ") index " + index); - return index; -}; - /** get the list of seas (or lands) around this region not connected by a dock */ m.NavalManager.prototype.getUnconnectedSeas = function(gameState, region) { @@ -259,7 +223,7 @@ m.NavalManager.prototype.checkEvents = function(gameState, queues, events) continue; let entity = gameState.getEntityById(evt.newentity); if (entity && entity.hasClass("Dock") && entity.isOwn(PlayerID)) - this.setDockIndex(gameState, entity); + this.SetAccessIndices(gameState, entity); } for (let evt of events.TrainingFinished) @@ -326,7 +290,7 @@ m.NavalManager.prototype.checkEvents = function(gameState, queues, events) { let ent = gameState.getEntityById(evt.entity); if (ent && ent.hasClass("Dock")) - this.setDockIndex(gameState, ent); + this.setAccessIndices(gameState, ent); } } }; diff --git a/binaries/data/mods/public/simulation/ai/petra/tradeManager.js b/binaries/data/mods/public/simulation/ai/petra/tradeManager.js index 9a528bb61e..ea0a214ecc 100644 --- a/binaries/data/mods/public/simulation/ai/petra/tradeManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/tradeManager.js @@ -412,16 +412,16 @@ m.TradeManager.prototype.checkRoutes = function(gameState, accessIndex) { if (!m1.position()) continue; - let access1 = gameState.ai.accessibility.getAccessValue(m1.position()); - let sea1 = m1.hasClass("NavalMarket") ? gameState.ai.HQ.navalManager.getDockIndex(gameState, m1, true) : undefined; + let access1 = m.GetLandAccess(gameState, m1); + let sea1 = m1.hasClass("NavalMarket") ? m.GetSeaAccess(gameState, m1) : undefined; for (let m2 of market2) { if (m1.id() === m2.id()) continue; if (!m2.position()) continue; - let access2 = gameState.ai.accessibility.getAccessValue(m2.position()); - let sea2 = m2.hasClass("NavalMarket") ? gameState.ai.HQ.navalManager.getDockIndex(gameState, m2, true) : undefined; + let access2 = m.GetLandAccess(gameState, m2); + let sea2 = m2.hasClass("NavalMarket") ? m.GetSeaAccess(gameState, m2) : undefined; let land = access1 == access2 ? access1 : undefined; let sea = (sea1 && sea1 == sea2) ? sea1 : undefined; if (!land && !sea) diff --git a/binaries/data/mods/public/simulation/ai/petra/worker.js b/binaries/data/mods/public/simulation/ai/petra/worker.js index 732b2c4319..240a90007f 100644 --- a/binaries/data/mods/public/simulation/ai/petra/worker.js +++ b/binaries/data/mods/public/simulation/ai/petra/worker.js @@ -167,12 +167,7 @@ m.Worker.prototype.update = function(gameState, ent) else { let access = gameState.ai.accessibility.getAccessValue(ent.position()); - let goalAccess = target.getMetadata(PlayerID, "access"); - if (!goalAccess) - { - goalAccess = gameState.ai.accessibility.getAccessValue(target.position()); - target.setMetadata(PlayerID, "access", goalAccess); - } + let goalAccess = m.GetLandAccess(gameState, target); if (access === goalAccess) ent.repair(target, target.hasClass("House")); // autocontinue=true for houses else @@ -459,12 +454,7 @@ m.Worker.prototype.startGathering = function(gameState) return false; if (foundation.resourceDropsiteTypes() && foundation.resourceDropsiteTypes().indexOf(resource) !== -1) { - let foundationAccess = foundation.getMetadata(PlayerID, "access"); - if (!foundationAccess) - { - foundationAccess = gameState.ai.accessibility.getAccessValue(foundation.position()); - foundation.setMetadata(PlayerID, "access", foundationAccess); - } + let foundationAccess = m.GetLandAccess(gameState, foundation); if (navalManager.requireTransport(gameState, this.ent, access, foundationAccess, foundation.position())) { if (foundation.getMetadata(PlayerID, "base") !== this.baseID) @@ -557,13 +547,7 @@ m.Worker.prototype.startHunting = function(gameState, position) // owner !== PlayerID can only happen when hasSharedDropsites === true, so no need to test it again if (owner !== PlayerID && (!dropsite.isSharedDropsite() || !gameState.isPlayerMutualAlly(owner))) continue; - let dropsiteAccess = dropsite.getMetadata(PlayerID, "access"); - if (!dropsiteAccess) - { - dropsiteAccess = gameState.ai.accessibility.getAccessValue(dropsite.position()); - dropsite.setMetadata(PlayerID, "access", dropsiteAccess); - } - if (dropsiteAccess !== access) + if (access !== m.GetLandAccess(gameState, dropsite)) continue; distMin = Math.min(distMin, API3.SquareVectorDistance(pos, dropsite.position())); } @@ -667,13 +651,7 @@ m.Worker.prototype.startFishing = function(gameState) // owner !== PlayerID can only happen when hasSharedDropsites === true, so no need to test it again if (owner !== PlayerID && (!dropsite.isSharedDropsite() || !gameState.isPlayerMutualAlly(owner))) continue; - let dropsiteSea = dropsite.getMetadata(PlayerID, "sea"); - if (!dropsiteSea) - { - dropsiteSea = gameState.ai.accessibility.getAccessValue(dropsite.position(), true); - dropsite.setMetadata(PlayerID, "sea", dropsiteSea); - } - if (dropsiteSea !== fisherSea) + if (fisherSea !== m.GetSeaAccess(gameState, dropsite)) continue; distMin = Math.min(distMin, API3.SquareVectorDistance(pos, dropsite.position())); } @@ -808,13 +786,7 @@ m.Worker.prototype.gatherTreasure = function(gameState) let lastGathered = treasure.getMetadata(PlayerID, "lastGathered"); if (lastGathered && gameState.ai.elapsedTime - lastGathered < 20) continue; - let treasureAccess = treasure.getMetadata(PlayerID, "access"); - if (!treasureAccess) - { - treasureAccess = gameState.ai.accessibility.getAccessValue(treasure.position()); - treasure.setMetadata(PlayerID, "access", treasureAccess); - } - if (treasureAccess !== access) + if (access !== m.GetLandAccess(gameState, treasure)) continue; let territoryOwner = gameState.ai.HQ.territoryMap.getOwner(treasure.position()); if (territoryOwner !== 0 && !gameState.isPlayerAlly(territoryOwner))