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 @@ -300,6 +300,25 @@ return false; }; +/** + * Check if the straight line between the two positions crosses an enemy territory + */ +m.isLineInsideEnemyTerritory = function(gameState, pos1, pos2, step=70) +{ + let dist = Math.sqrt(API3.SquareVectorDistance(pos1, pos2)); + let n = Math.floor(Math.sqrt(API3.SquareVectorDistance(pos1, pos2))/step) + 1; + let stepx = (pos2[0] - pos1[0]) / n; + let stepy = (pos2[1] - pos1[1]) / n; + for (let i = 1; i < n; ++i) + { + let pos = [pos1[0]+i*stepx, pos1[1]+i*stepy]; + let owner = gameState.ai.HQ.territoryMap.getOwner(pos); + if (owner && gameState.isPlayerEnemy(owner)) + return true; + } + return false; +}; + m.dumpEntity = function(ent) { if (!ent) Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js @@ -1083,7 +1083,8 @@ continue; gainMultiplier = traderTemplatesGains.navalGainMultiplier; } - else if (m.getLandAccess(gameState, market) === index) + else if (m.getLandAccess(gameState, market) === index && + !m.isLineInsideEnemyTerritory(gameState, market.position(), pos)) gainMultiplier = traderTemplatesGains.landGainMultiplier; else continue; 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 @@ -217,9 +217,9 @@ let rates = gameState.ai.HQ.GetCurrentGatherRates(gameState); - let prices = gameState.getBarterPrices(); + let barterPrices = gameState.getBarterPrices(); // calculates conversion rates - let getBarterRate = function (prices,buy,sell) { return Math.round(100 * prices.sell[sell] / prices.buy[buy]); }; + let getBarterRate = (prices, buy, sell) => Math.round(100 * prices.sell[sell] / prices.buy[buy]); // loop through each missing resource checking if we could barter and help finishing a queue quickly. for (let buy of needs.types) @@ -257,7 +257,7 @@ barterRateMin += 20; } - let barterRate = getBarterRate(prices, buy, sell); + let barterRate = getBarterRate(barterPrices, buy, sell); if (barterRate > bestRate && barterRate > barterRateMin) { bestRate = barterRate; @@ -287,7 +287,7 @@ let barterRateMin = 80; if (available[buy] < 5000 && available.food > 5000) barterRateMin -= 20 - Math.floor(available[buy]/250); - let barterRate = getBarterRate(prices, buy, "food"); + let barterRate = getBarterRate(barterPrices, buy, "food"); if (barterRate < barterRateMin) continue; let choice = barterRate / (100 + available[buy]); @@ -302,7 +302,7 @@ barterers[0].barter(bestToBuy, "food", 100); if (this.Config.debug > 2) API3.warn("Contingency bartering: sold food for " + bestToBuy + " available sell " + available.food + - " available buy " + available[bestToBuy] + " barterRate " + getBarterRate(prices, bestToBuy, "food")); + " available buy " + available[bestToBuy] + " barterRate " + getBarterRate(barterPrices, bestToBuy, "food")); return true; } @@ -391,8 +391,8 @@ */ m.TradeManager.prototype.checkRoutes = function(gameState, accessIndex) { - let market1 = gameState.updatingCollection("OwnMarkets", API3.Filters.byClass("Market"), gameState.getOwnStructures()).toEntityArray(); - let market2 = gameState.updatingCollection("ExclusiveAllyMarkets", API3.Filters.byClass("Market"), gameState.getExclusiveAllyEntities()).toEntityArray(); + let market1 = gameState.updatingCollection("OwnMarkets", API3.Filters.byClass("Market"), gameState.getOwnStructures()); + let market2 = gameState.updatingCollection("ExclusiveAllyMarkets", API3.Filters.byClass("Market"), gameState.getExclusiveAllyEntities()); if (market1.length + market2.length < 2) // We have to wait ... markets will be built soon { this.tradeRoute = undefined; @@ -400,7 +400,8 @@ return false; } - if (!market2.length) + let onlyOurs = !market2.hasEntities(); + if (onlyOurs) market2 = market1; let candidate = { "gain": 0 }; let potential = { "gain": 0 }; @@ -409,15 +410,15 @@ let traderTemplatesGains = gameState.getTraderTemplatesGains(); - for (let m1 of market1) + for (let m1 of market1.values()) { if (!m1.position()) continue; let access1 = m.getLandAccess(gameState, m1); let sea1 = m1.hasClass("NavalMarket") ? m.getSeaAccess(gameState, m1) : undefined; - for (let m2 of market2) + for (let m2 of market2.values()) { - if (m1.id() === m2.id()) + if (onlyOurs && m1.id() >= m2.id()) continue; if (!m2.position()) continue; @@ -427,6 +428,8 @@ let sea = sea1 && sea1 == sea2 ? sea1 : undefined; if (!land && !sea) continue; + if (land && m.isLineInsideEnemyTerritory(gameState, m1.position(), m2.position())) + continue; let gainMultiplier; if (land && traderTemplatesGains.landGainMultiplier) gainMultiplier = traderTemplatesGains.landGainMultiplier;