diff --git a/binaries/data/mods/public/simulation/ai/qbot-wc/attack_plan.js b/binaries/data/mods/public/simulation/ai/qbot-wc/attack_plan.js index 8453a7299c..fdaab2053e 100755 --- a/binaries/data/mods/public/simulation/ai/qbot-wc/attack_plan.js +++ b/binaries/data/mods/public/simulation/ai/qbot-wc/attack_plan.js @@ -20,12 +20,19 @@ function CityAttack(gameState, militaryManager, uniqueID, targetEnemy, type , ta max = enemyCount[i]; } } + warn ("target " + this.targetPlayer); if (this.targetPlayer === undefined || this.targetPlayer === -1) + { + this.failed = true; return false; + } var CCs = gameState.getOwnEntities().filter(Filters.byClass("CivCentre")); if (CCs.length === 0) + { + this.failed = true; return false; + } debug ("Target (" + PlayerID +") = " +this.targetPlayer); this.targetFinder = targetFinder || this.defaultTargetFinder; @@ -196,7 +203,7 @@ function CityAttack(gameState, militaryManager, uniqueID, targetEnemy, type , ta } // some variables for during the attack - this.position20TurnsAgo = [0,0]; + this.position10TurnsAgo = [0,0]; this.lastPosition = [0,0]; this.position = [0,0]; @@ -284,6 +291,7 @@ CityAttack.prototype.updatePreparation = function(gameState, militaryManager,eve targets = this.defaultTargetFinder(gameState, militaryManager); } if (targets.length) { + debug ("Aiming for " + targets); // picking a target var rand = Math.floor((Math.random()*targets.length)); this.targetPos = undefined; @@ -337,8 +345,16 @@ CityAttack.prototype.updatePreparation = function(gameState, militaryManager,eve Engine.ProfileStart("Update Preparation"); - // keep on while the units finish being trained. - if (this.mustStart(gameState) && (gameState.countOwnQueuedEntitiesWithMetadata("plan", +this.name) > 0 || (gameState.getPopulationMax() - gameState.getPopulation() < 10) )) { + // special case: if we're reached max pop, and we can start the plan, start it. + if ((gameState.getPopulationMax() - gameState.getPopulation() < 10) && this.canStart()) + { + this.assignUnits(gameState); + if (this.queue.length()) + this.queue.empty(); + if ( (gameState.ai.turn + gameState.ai.player) % 40 == 0) + this.AllToRallyPoint(gameState, false); + } else if (this.mustStart(gameState) && (gameState.countOwnQueuedEntitiesWithMetadata("plan", +this.name) > 0)) { + // keep on while the units finish being trained, then we'll start this.assignUnits(gameState); if (this.queue.length()) @@ -528,7 +544,6 @@ CityAttack.prototype.defaultTargetFinder = function(gameState, militaryManager){ if (targets.length == 0) { targets = gameState.getEnemyEntities().filter(Filters.and( Filters.byOwner(this.targetPlayer),Filters.byClass("ConquestCritical"))); } - debug ("target is " + targets); return targets; }; @@ -716,17 +731,13 @@ CityAttack.prototype.update = function(gameState, militaryManager, events){ if (this.state === "walking"){ this.position = this.unitCollection.filter(Filters.not(Filters.byClass("Warship"))).getCentrePosition(); - + // probably not too good. if (!this.position) return undefined; // should spawn an error. // basically haven't moved an inch: very likely stuck) - if (SquareVectorDistance(this.position, this.position20TurnsAgo) < 10 && this.path.length > 0 && gameState.ai.playedTurn % 100 === 0) { - - if (gameState.ai.playedTurn % 100 === 0) - this.position20TurnsAgo = this.position; - + if (SquareVectorDistance(this.position, this.position10TurnsAgo) < 10 && this.path.length > 0 && gameState.ai.playedTurn % 20 === 0) { // check for stuck siege units var sieges = this.unitCollection.filter(Filters.byClass("Siege")); @@ -742,6 +753,8 @@ CityAttack.prototype.update = function(gameState, militaryManager, events){ if (farthestEnt !== -1) farthestEnt.destroy(); } + if (gameState.ai.playedTurn % 20 === 0) + this.position10TurnsAgo = this.position; if (this.lastPosition && SquareVectorDistance(this.position, this.lastPosition) < 20 && this.path.length > 0) { this.unitCollection.filter(Filters.not(Filters.byClass("Warship"))).moveIndiv(this.path[0][0][0], this.path[0][0][1]); @@ -1123,14 +1136,14 @@ CityAttack.prototype.update = function(gameState, militaryManager, events){ } // updating targets. if (!gameState.getEntityById(this.target.id())) - { - debug ("Seems like our target has been destroyed. Switching."); - + { var targets = this.targetFinder(gameState, militaryManager); if (targets.length === 0){ targets = this.defaultTargetFinder(gameState, militaryManager); } if (targets.length) { + debug ("Seems like our target has been destroyed. Switching."); + debug ("Aiming for " + targets); // picking a target var rand = Math.floor((Math.random()*targets.length)); this.targetPos = undefined; diff --git a/binaries/data/mods/public/simulation/ai/qbot-wc/economy.js b/binaries/data/mods/public/simulation/ai/qbot-wc/economy.js index 0200d18a8a..c7e899f2d4 100644 --- a/binaries/data/mods/public/simulation/ai/qbot-wc/economy.js +++ b/binaries/data/mods/public/simulation/ai/qbot-wc/economy.js @@ -369,6 +369,11 @@ EconomyManager.prototype.assignToFoundations = function(gameState, noRepair) { } } else if (noRepair && !target.hasClass("CivCentre")) continue; + + var territory = Map.createTerritoryMap(gameState); + if (territory.getOwner(target.position()) !== PlayerID || territory.getOwner([target.position()[0] + 5, target.position()[1]]) !== PlayerID) + continue; + var assigned = gameState.getOwnEntitiesByMetadata("target-foundation", target).length; if (assigned < this.targetNumBuilders) { if (builderWorkers.length + addedWorkers < this.targetNumBuilders*4) { diff --git a/binaries/data/mods/public/simulation/ai/qbot-wc/military.js b/binaries/data/mods/public/simulation/ai/qbot-wc/military.js index d1f5b7a42b..de476c1242 100755 --- a/binaries/data/mods/public/simulation/ai/qbot-wc/military.js +++ b/binaries/data/mods/public/simulation/ai/qbot-wc/military.js @@ -588,7 +588,7 @@ MilitaryAttackManager.prototype.update = function(gameState, queues, events) { for (var i = 0;i < this.upcomingAttacks[attackType].length; ++i) { var attack = this.upcomingAttacks[attackType][i]; - + // okay so we'll get the support plan if (!attack.isStarted()) { var updateStep = attack.updatePreparation(gameState, this,events); @@ -637,7 +637,7 @@ MilitaryAttackManager.prototype.update = function(gameState, queues, events) { } } if (gameState.ai.strategy === "rush" && this.startedAttacks["CityAttack"].length !== 0) { - // and then we revert shit. + // and then we revert. gameState.ai.strategy = "normal"; Config.Economy.femaleRatio = 0.4; gameState.ai.modules.economy.targetNumWorkers = Math.max(Math.floor(gameState.getPopulationMax()*0.55), 1); @@ -654,7 +654,7 @@ MilitaryAttackManager.prototype.update = function(gameState, queues, events) { && gameState.getTimeElapsed() > this.attackPlansStartTime) { if (this.upcomingAttacks["CityAttack"].length == 0 && (gameState.getTimeElapsed() < 25*60000 || Config.difficulty < 2)) { var Lalala = new CityAttack(gameState, this,this.TotalAttackNumber, -1); - if (!Lalala) + if (Lalala.failed) { this.attackPlansEncounteredWater = true; // hack } else { @@ -664,7 +664,7 @@ MilitaryAttackManager.prototype.update = function(gameState, queues, events) { } } else if (this.upcomingAttacks["CityAttack"].length == 0 && Config.difficulty !== 0) { var Lalala = new CityAttack(gameState, this,this.TotalAttackNumber, -1, "superSized"); - if (!Lalala) + if (Lalala.failed) { this.attackPlansEncounteredWater = true; // hack } else { diff --git a/binaries/data/mods/public/simulation/ai/qbot-wc/plan-building.js b/binaries/data/mods/public/simulation/ai/qbot-wc/plan-building.js index 5a3d56ffe4..8cd9de1412 100644 --- a/binaries/data/mods/public/simulation/ai/qbot-wc/plan-building.js +++ b/binaries/data/mods/public/simulation/ai/qbot-wc/plan-building.js @@ -116,7 +116,11 @@ BuildingConstructionPlan.prototype.findGoodPosition = function(gameState) { friendlyTiles.addInfluence(x, z, Math.ceil(infl/2.0),infl); // houses are farther away from other buildings but houses friendlyTiles.addInfluence(x, z, Math.ceil(infl/4.0),-infl/2.0); // houses are farther away from other buildings but houses } else if (ent.genericName() != "House") // houses have no influence on other buildings + { friendlyTiles.addInfluence(x, z, infl); + //avoid building too close to each other if possible. + friendlyTiles.addInfluence(x, z, 5, -5, 'linear'); + } // If this is not a field add a negative influence near the CivCentre because we want to leave this // area for fields. if (ent.hasClass("CivCentre") && template.genericName() != "House"){ @@ -125,14 +129,12 @@ BuildingConstructionPlan.prototype.findGoodPosition = function(gameState) { friendlyTiles.addInfluence(x, z, infl/3.0, infl + 1); friendlyTiles.addInfluence(x, z, Math.ceil(infl/5.0), -(infl/2.0), 'linear'); } - //avoid building too close to each other if possible. - friendlyTiles.addInfluence(x, z, 5, -5, 'linear'); } } }); } - friendlyTiles.dumpIm(template.buildCategory() + "_" +gameState.getTimeElapsed() + ".png", 200); + //friendlyTiles.dumpIm(template.buildCategory() + "_" +gameState.getTimeElapsed() + ".png", 200); // Find target building's approximate obstruction radius, and expand by a bit to make sure we're not too close, this // allows room for units to walk between buildings. @@ -146,7 +148,7 @@ BuildingConstructionPlan.prototype.findGoodPosition = function(gameState) { else if (template.genericName() != "House" && !template.hasClass("DropsiteWood") && !template.hasClass("DropsiteStone") && !template.hasClass("DropsiteMetal")) radius = Math.ceil(template.obstructionRadius() / cellSize + 0.5); else if (gameState.civ() === "iber" || gameState.civ() === "gaul" || gameState.civ() === "brit") - radius = Math.ceil(template.obstructionRadius() / cellSize); + radius = Math.ceil(template.obstructionRadius() / cellSize - 0.5); else radius = Math.ceil(template.obstructionRadius() / cellSize); @@ -181,6 +183,9 @@ BuildingConstructionPlan.prototype.findGoodPosition = function(gameState) { // default angle var angle = 3*Math.PI/4; + if (template.genericName() == "House") + angle = Math.PI; + return { "x" : x, "z" : z, diff --git a/binaries/system/readme.txt b/binaries/system/readme.txt index e6cc923da2..71e542c66c 100644 --- a/binaries/system/readme.txt +++ b/binaries/system/readme.txt @@ -20,6 +20,7 @@ Random maps only: -autostart-random=SEED random map with SEED value (default 0, use -1 for random) -autostart-size=TILES random map SIZE in tiles (default 192) -autostart-players=NUMBER NUMBER of players on random map +-autostart-civ=PLAYER:CIV changes the civilisation of player PLAYER to CIV (default athen) Configuration: -conf=KEY:VALUE set a config value