diff --git a/binaries/data/mods/public/simulation/ai/petra/attackPlan.js b/binaries/data/mods/public/simulation/ai/petra/attackPlan.js index 8097cfe35a..176f0b4fed 100644 --- a/binaries/data/mods/public/simulation/ai/petra/attackPlan.js +++ b/binaries/data/mods/public/simulation/ai/petra/attackPlan.js @@ -1272,14 +1272,20 @@ m.AttackPlan.prototype.update = function(gameState, events) } let time = gameState.ai.elapsedTime; + let attackedByStructure = {}; for (let evt of events.Attacked) { if (!this.unitCollection.hasEntId(evt.target)) continue; let attacker = gameState.getEntityById(evt.attacker); let ourUnit = gameState.getEntityById(evt.target); - if (!ourUnit || !attacker || !attacker.position() || !attacker.hasClass("Unit")) + if (!ourUnit || !attacker || !attacker.position()) continue; + if (!attacker.hasClass("Unit")) + { + attackedByStructure[evt.target] = true; + continue; + } if (m.isSiegeUnit(ourUnit)) { // if our siege units are attacked, we'll send some units to deal with enemies. let collec = this.unitCollection.filter(API3.Filters.not(API3.Filters.byClass("Siege"))).filterNearest(ourUnit.position(), 5); @@ -1421,6 +1427,9 @@ m.AttackPlan.prototype.update = function(gameState, events) let ent = gameState.getEntityById(this.unitCollUpdateArray[check]); if (!ent || !ent.position()) continue; + // Do not reaffect units which have reacted to an attack in that same turn + if (ent.getMetadata(PlayerID, "lastAttackPlanUpdateTime") == time) + continue; let targetId; let orderData = ent.unitAIOrderData(); @@ -1458,6 +1467,8 @@ m.AttackPlan.prototype.update = function(gameState, events) } else if (target.hasClass("Ship") && !ent.hasClass("Ship")) maybeUpdate = true; + else if (attackedByStructure[ent.id()] && target.hasClass("Field")) + maybeUpdate = true; else if (!ent.hasClass("Cavalry") && !ent.hasClass("Ranged") && target.hasClass("FemaleCitizen") && target.unitAIState().split(".")[1] == "FLEEING") maybeUpdate = true; diff --git a/binaries/data/mods/public/simulation/ai/petra/headquarters.js b/binaries/data/mods/public/simulation/ai/petra/headquarters.js index e6bd1fb754..82aad1660b 100644 --- a/binaries/data/mods/public/simulation/ai/petra/headquarters.js +++ b/binaries/data/mods/public/simulation/ai/petra/headquarters.js @@ -1058,6 +1058,7 @@ m.HQ.prototype.findStrategicCCLocation = function(gameState, template) let cellSize = this.territoryMap.cellSize; let currentVal, delta; let distcc0, distcc1, distcc2; + let favoredDistance = template.hasClass("Colony") ? 220 : 280; for (let j = 0; j < this.territoryMap.length; ++j) { @@ -1112,13 +1113,13 @@ m.HQ.prototype.findStrategicCCLocation = function(gameState, template) if (minDist < 1 || minDist > 170000 && !this.navalMap) continue; - delta = Math.sqrt(distcc0) - 300; // favor a distance of 300 + delta = Math.sqrt(distcc0) - favoredDistance; currentVal = delta*delta; - delta = Math.sqrt(distcc1) - 300; + delta = Math.sqrt(distcc1) - favoredDistance; currentVal += delta*delta; if (distcc2) { - delta = Math.sqrt(distcc2) - 300; + delta = Math.sqrt(distcc2) - favoredDistance; currentVal += delta*delta; } // disfavor border of the map diff --git a/binaries/data/mods/public/simulation/ai/petra/tradeManager.js b/binaries/data/mods/public/simulation/ai/petra/tradeManager.js index 8cd534ec54..584a4b0290 100644 --- a/binaries/data/mods/public/simulation/ai/petra/tradeManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/tradeManager.js @@ -619,9 +619,6 @@ m.TradeManager.prototype.update = function(gameState, events, queues) if (this.Config.difficulty <= 1) return; - if (this.routeProspection) - this.prospectForNewMarket(gameState, queues); - if (this.checkEvents(gameState, events)) // true if one market was built or destroyed { this.traders.forEach(ent => { this.checkTrader(gameState, ent); }); @@ -631,33 +628,55 @@ m.TradeManager.prototype.update = function(gameState, events, queues) if (this.tradeRoute) { this.traders.forEach(ent => { this.updateTrader(gameState, ent); }); - if (gameState.ai.playedTurn % 5 === 0) + if (gameState.ai.playedTurn % 5 == 0) this.trainMoreTraders(gameState, queues); - if (gameState.ai.playedTurn % 20 === 0 && this.traders.length >= 2) + if (gameState.ai.playedTurn % 20 == 0 && this.traders.length >= 2) gameState.ai.HQ.researchManager.researchTradeBonus(gameState, queues); - if (gameState.ai.playedTurn % 60 === 0) + if (gameState.ai.playedTurn % 60 == 0) this.setTradingGoods(gameState); } + + if (this.routeProspection) + this.prospectForNewMarket(gameState, queues); }; m.TradeManager.prototype.routeEntToId = function(route) { if (!route) - return route; + return undefined; + let ret = {}; for (let key in route) - ret[key] = key == "source" || key == "target" ? route[key].id() : route[key]; + { + if (key == "source" || key == "target") + { + if (!route[key]) + return undefined; + ret[key] = route[key].id(); + } + else + ret[key] = route[key]; + } return ret; }; m.TradeManager.prototype.routeIdToEnt = function(gameState, route) { if (!route) - return route; + return undefined; + let ret = {}; for (let key in route) - ret[key] = key == "source" || key == "target" ? gameState.getEntityById(route[key]) : route[key]; - return ret; + { + if (key == "source" || key == "target") + { + ret[key] = gameState.getEntityById(route[key]); + if (!ret[key]) + return undefined; + } + else + ret[key] = route[key]; + } }; m.TradeManager.prototype.Serialize = function()