Ticket #3586: headquarters-v3.patch
File headquarters-v3.patch, 10.4 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/simulation/ai/petra/config.js
30 30 "targetNumWorkers" : 40, // dummy, will be changed later 31 31 "targetNumTraders" : 5, // Target number of traders 32 32 "targetNumFishers" : 1, // Target number of fishers per sea 33 " femaleRatio" : 0.5, // fraction of females among the workforce33 "supportRatio" : 0.5, // fraction of support workers among the workforce 34 34 "provisionFields" : 2 35 35 }; 36 36 … … 125 125 if (this.difficulty < 2) 126 126 { 127 127 this.Economy.cityPhase = 240000; 128 this.Economy. femaleRatio = 0.7;128 this.Economy.supportRatio = 0.7; 129 129 this.Economy.provisionFields = 1; 130 130 this.Military.numWoodenTowers = (this.personality.defensive > 0.66) ? 1 : 0; 131 131 } … … 132 132 else if (this.difficulty < 3) 133 133 { 134 134 this.Economy.cityPhase = 1800; 135 this.Economy. femaleRatio = 0.6;135 this.Economy.supportRatio = 0.6; 136 136 this.Economy.provisionFields = 1; 137 137 this.Military.numWoodenTowers = (this.personality.defensive > 0.66) ? 1 : 0; 138 138 } … … 154 154 this.Military.popForBarracks1 = 12; 155 155 this.Economy.popForTown = 55; 156 156 this.Economy.popForMarket = 60; 157 this.Economy. femaleRatio = 0.3;157 this.Economy.supportRatio = 0.3; 158 158 this.priorities.defenseBuilding = 60; 159 159 } 160 160 } -
binaries/data/mods/public/simulation/ai/petra/headquarters.js
29 29 30 30 // workers configuration 31 31 this.targetNumWorkers = this.Config.Economy.targetNumWorkers; 32 this. femaleRatio = this.Config.Economy.femaleRatio;32 this.supportRatio = this.Config.Economy.supportRatio; 33 33 34 34 this.lastTerritoryUpdate = -1; 35 35 this.stopBuilding = new Map(); // list of buildings to stop (temporarily) production because no room … … 211 211 ent.setMetadata(PlayerID, "role", undefined); 212 212 ent.setMetadata(PlayerID, "subrole", undefined); 213 213 ent.setMetadata(PlayerID, "plan", undefined); 214 ent.setMetadata(PlayerID, "PartOfArmy", undefined); 214 ent.setMetadata(PlayerID, "PartOfArmy", undefined); 215 215 if (ent.hasClass("Trader")) 216 216 { 217 217 ent.setMetadata(PlayerID, "role", "trader"); 218 218 ent.setMetadata(PlayerID, "route", undefined); 219 219 } 220 if (ent.hasClass(" Female") || ent.hasClass("CitizenSoldier"))220 if (ent.hasClass("Worker")) 221 221 { 222 222 ent.setMetadata(PlayerID, "role", "worker"); 223 223 ent.setMetadata(PlayerID, "subrole", "idle"); … … 379 379 // Called by the "town phase" research plan once it's started 380 380 m.HQ.prototype.OnTownPhase = function(gameState) 381 381 { 382 if (this.Config.difficulty > 2 && this. femaleRatio > 0.4)383 this. femaleRatio = 0.4;382 if (this.Config.difficulty > 2 && this.supportRatio > 0.4) 383 this.supportRatio = 0.4; 384 384 385 385 var phaseName = gameState.getTemplate(gameState.townPhase()).name(); 386 386 m.chatNewPhase(gameState, phaseName, true); … … 389 389 // Called by the "city phase" research plan once it's started 390 390 m.HQ.prototype.OnCityPhase = function(gameState) 391 391 { 392 if (this.Config.difficulty > 2 && this. femaleRatio > 0.3)393 this. femaleRatio = 0.3;392 if (this.Config.difficulty > 2 && this.supportRatio > 0.3) 393 this.supportRatio = 0.3; 394 394 395 395 // increase the priority of defense buildings to free this queue for our first fortress 396 396 gameState.ai.queueManager.changePriority("defenseBuilding", 2*this.Config.priorities.defenseBuilding); … … 399 399 m.chatNewPhase(gameState, phaseName, true); 400 400 }; 401 401 402 // This code trains females and citizen workers, trying to keep close to a ratio of females/CS 403 // TODO: this should choose a base depending on which base need workers 404 // TODO: also there are several things that could be greatly improved here. 402 // This code trains citizen workers, trying to keep close to a ratio of worker/soldiers 405 403 m.HQ.prototype.trainMoreWorkers = function(gameState, queues) 406 404 { 407 // Count the workers in the world and in progress 408 var numFemales = gameState.countEntitiesAndQueuedByType(gameState.applyCiv("units/{civ}_support_female_citizen"), true); 405 // default template 406 var requirementsDef = [["cost", 1], ["costsResource", 1, "food"]]; 407 var classesDef = ["Support", "Worker"]; 408 var templateDef = this.findBestTrainableUnit(gameState, classesDef, requirementsDef); 409 409 410 410 // counting the workers that aren't part of a plan 411 var numWorkers = 0; 411 var numberOfWorkers = 0; // all workers 412 var numberOfSupports = 0; // only support workers (i.e. non fighting) 412 413 gameState.getOwnUnits().forEach (function (ent) { 413 414 if (ent.getMetadata(PlayerID, "role") == "worker" && ent.getMetadata(PlayerID, "plan") == undefined) 414 ++numWorkers; 415 { 416 ++numberOfWorkers; 417 if (ent.hasClass("Support")) 418 ++numberOfSupports; 419 } 415 420 }); 416 var num InTraining = 0;421 var numberInTraining = 0; 417 422 gameState.getOwnTrainingFacilities().forEach(function(ent) { 418 423 ent.trainingQueue().forEach(function(item) { 424 numberInTraining += item.count; 419 425 if (item.metadata && item.metadata.role && item.metadata.role == "worker" && item.metadata.plan == undefined) 420 numWorkers += item.count; 421 numInTraining += item.count; 426 { 427 numberOfWorkers += item.count; 428 if (ent.hasClass("Support")) 429 numberOfSupports += item.count; 430 } 422 431 }); 423 432 }); 424 433 425 434 // Anticipate the optimal batch size when this queue will start 426 // and adapt the batch size of the first and second queued workers and femalesto the present population435 // and adapt the batch size of the first and second queued workers to the present population 427 436 // to ease a possible recovery if our population was drastically reduced by an attack 428 437 // (need to go up to second queued as it is accounted in queueManager) 429 var size = num Workers < 12 ? 1 : Math.min(5, Math.ceil(numWorkers / 10));438 var size = numberOfWorkers < 12 ? 1 : Math.min(5, Math.ceil(numberOfWorkers / 10)); 430 439 if (queues.villager.plans[0]) 431 440 { 432 441 queues.villager.plans[0].number = Math.min(queues.villager.plans[0].number, size); … … 440 449 queues.citizenSoldier.plans[1].number = Math.min(queues.citizenSoldier.plans[1].number, size); 441 450 } 442 451 443 var num QueuedF= queues.villager.countQueuedUnits();444 var num QueuedS= queues.citizenSoldier.countQueuedUnits();445 var num Queued = numQueuedS + numQueuedF;446 var num Total = numWorkers + numQueued;452 var numberOfQueuedSupports = queues.villager.countQueuedUnits(); 453 var numberOfQueuedSoldiers = queues.citizenSoldier.countQueuedUnits(); 454 var numberQueued = numberOfQueuedSupports + numberOfQueuedSoldiers; 455 var numberTotal = numberOfWorkers + numberQueued; 447 456 448 if (this.saveResources && num Total > this.Config.Economy.popForTown + 10)457 if (this.saveResources && numberTotal > this.Config.Economy.popForTown + 10) 449 458 return; 450 if (num Total > this.targetNumWorkers || (numTotal >= this.Config.Economy.popForTown &&459 if (numberTotal > this.targetNumWorkers || (numberTotal >= this.Config.Economy.popForTown && 451 460 gameState.currentPhase() == 1 && !gameState.isResearching(gameState.townPhase()))) 452 461 return; 453 if (num Queued > 50 || (numQueuedF > 20 && numQueuedS > 20) || numInTraining > 15)462 if (numberQueued > 50 || (numberOfQueuedSupports > 20 && numberOfQueuedSoldiers > 20) || numberInTraining > 15) 454 463 return; 455 464 456 // default template457 var templateDef = gameState.applyCiv("units/{civ}_support_female_citizen");458 465 // Choose whether we want soldiers instead. 459 let femaleRatio = (gameState.isDisabledTemplates(gameState.applyCiv("structures/{civ}_field")) ? Math.min(this.femaleRatio, 0.2) : this.femaleRatio);466 let supportRatio = (gameState.isDisabledTemplates(gameState.applyCiv("structures/{civ}_field")) ? Math.min(this.supportRatio, 0.2) : this.supportRatio); 460 467 let template; 461 if ( !gameState.templates[templateDef] || ((numFemales+numQueuedF) > 8 && (numFemales+numQueuedF)/numTotal > femaleRatio))468 if ((numberOfSupports + numberOfQueuedSupports) > 8 && (numberOfSupports + numberOfQueuedSupports)/numberTotal > supportRatio) 462 469 { 463 470 let requirements; 464 if (num Total < 45)471 if (numberTotal < 45) 465 472 requirements = [ ["cost", 1], ["speed", 0.5], ["costsResource", 0.5, "stone"], ["costsResource", 0.5, "metal"]]; 466 473 else 467 474 requirements = [ ["strength", 1] ]; 468 475 476 let classes = ["CitizenSoldier", "Infantry"]; 469 477 let proba = Math.random(); 470 if (proba < 0.6)471 { // we require at least 30% ranged and 30% melee472 let classes = proba < 0.3 ? ["CitizenSoldier", "Infantry", "Ranged"] : ["CitizenSoldier", "Infantry", "Melee"];473 template = this.findBestTrainableUnit(gameState, classes, requirements);474 }475 if (!template) 476 template = this.findBestTrainableUnit(gameState, ["CitizenSoldier", "Infantry"], requirements);478 // we require at least 30% ranged and 30% melee 479 if ( proba < 0.3 ) 480 classes.push("Ranged") 481 else if ( proba < 0.6 ) 482 classes.push("Melee"); 483 484 template = this.findBestTrainableUnit(gameState, classes, requirements); 477 485 } 478 if (!template && gameState.templates[templateDef])479 template = templateDef;480 486 487 // If the template variable is empty, the default unit (Support unit) 488 // would be used in the next turn 489 // 481 490 // base "0" means "auto" 482 if ( template === gameState.applyCiv("units/{civ}_support_female_citizen"))483 queues.villager.addPlan(new m.TrainingPlan(gameState, template , { "role": "worker", "base": 0 }, size, size));491 if (!template && templateDef) 492 queues.villager.addPlan(new m.TrainingPlan(gameState, templateDef, { "role": "worker", "base": 0 }, size, size)); 484 493 else if (template) 485 494 queues.citizenSoldier.addPlan(new m.TrainingPlan(gameState, template, { "role": "worker", "base": 0 }, size, size)); 486 495 }; … … 504 513 var availableResources = gameState.ai.queueManager.getAvailableResources(gameState); // available (gathered) resources 505 514 for (let type in remainingResources) 506 515 { 507 if (type === "food")508 continue;509 516 if (availableResources[type] > 800) 510 517 continue; 511 518 if (remainingResources[type] > 800) … … 638 645 } 639 646 this.turnCache.gatherRates = true; 640 647 } 641 648 642 649 return this.currentRates; 643 650 }; 644 651 … … 2065 2072 "wantedRates": this.wantedRates, 2066 2073 "currentRates": this.currentRates, 2067 2074 "lastFailedGather": this.lastFailedGather, 2068 " femaleRatio": this.femaleRatio,2075 "supportRatio": this.supportRatio, 2069 2076 "targetNumWorkers": this.targetNumWorkers, 2070 2077 "lastTerritoryUpdate": this.lastTerritoryUpdate, 2071 2078 "stopBuilding": this.stopBuilding,