Ticket #3586: headquarters_js_v2.patch
File headquarters_js_v2.patch, 8.9 KB (added by , 8 years ago) |
---|
-
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.workerRatio = this.Config.Economy.workerRatio; 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.workerRatio > 0.4) 383 this.workerRatio = 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.workerRatio > 0.3) 393 this.workerRatio = 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 // Count the workers in the world and in progress 411 var numberOfWorkers = gameState.countEntitiesAndQueuedByType(templateDef); 412 410 413 // counting the workers that aren't part of a plan 411 var num Workers = 0;414 var numberOfIddleWorkers = 0; 412 415 gameState.getOwnUnits().forEach (function (ent) { 413 416 if (ent.getMetadata(PlayerID, "role") == "worker" && ent.getMetadata(PlayerID, "plan") == undefined) 414 ++num Workers;417 ++numberOfIddleWorkers; 415 418 }); 416 var num InTraining = 0;419 var numberOfWorkersInTraining = 0; 417 420 gameState.getOwnTrainingFacilities().forEach(function(ent) { 418 421 ent.trainingQueue().forEach(function(item) { 419 422 if (item.metadata && item.metadata.role && item.metadata.role == "worker" && item.metadata.plan == undefined) 420 num Workers += item.count;421 num InTraining += item.count;423 numberOfIddleWorkers += item.count; 424 numberOfWorkersInTraining += item.count; 422 425 }); 423 426 }); 424 427 425 428 // 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 population429 // and adapt the batch size of the first and second queued workers to the present population 427 430 // to ease a possible recovery if our population was drastically reduced by an attack 428 431 // (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));432 var size = numberOfIddleWorkers < 12 ? 1 : Math.min(5, Math.ceil(numberOfIddleWorkers / 10)); 430 433 if (queues.villager.plans[0]) 431 434 { 432 435 queues.villager.plans[0].number = Math.min(queues.villager.plans[0].number, size); … … 440 443 queues.citizenSoldier.plans[1].number = Math.min(queues.citizenSoldier.plans[1].number, size); 441 444 } 442 445 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;446 var numberOfQueuedWorkers = queues.villager.countQueuedUnits(); 447 var numberOfQueuedSoldiers = queues.citizenSoldier.countQueuedUnits(); 448 var numberQueued = numberOfQueuedSoldiers + numberOfQueuedWorkers; 449 var numberTotal = numberOfIddleWorkers + numberQueued; 447 450 448 if (this.saveResources && num Total > this.Config.Economy.popForTown + 10)451 if (this.saveResources && numberTotal > this.Config.Economy.popForTown + 10) 449 452 return; 450 if (num Total > this.targetNumWorkers || (numTotal >= this.Config.Economy.popForTown &&453 if (numberTotal > this.targetNumWorkers || (numberTotal >= this.Config.Economy.popForTown && 451 454 gameState.currentPhase() == 1 && !gameState.isResearching(gameState.townPhase()))) 452 455 return; 453 if (num Queued > 50 || (numQueuedF > 20 && numQueuedS > 20) || numInTraining > 15)456 if (numberQueued > 50 || (numberOfQueuedWorkers > 20 && numberOfQueuedSoldiers > 20) || numberOfWorkersInTraining > 15) 454 457 return; 455 458 456 // default template457 var templateDef = gameState.applyCiv("units/{civ}_support_female_citizen");458 459 // Choose whether we want soldiers instead. 459 let femaleRatio = (gameState.isDisabledTemplates(gameState.applyCiv("structures/{civ}_field")) ? Math.min(this.femaleRatio, 0.2) : this.femaleRatio);460 let workerRatio = (gameState.isDisabledTemplates(gameState.applyCiv("structures/{civ}_field")) ? Math.min(this.workerRatio, 0.2) : this.workerRatio); 460 461 let template; 461 if ( !gameState.templates[templateDef] || ((numFemales+numQueuedF) > 8 && (numFemales+numQueuedF)/numTotal > femaleRatio))462 if ((numberOfWorkers + numberOfQueuedWorkers) > 8 && (numberOfWorkers + numberOfQueuedWorkers)/numberTotal > workerRatio) 462 463 { 463 464 let requirements; 464 if (num Total < 45)465 if (numberTotal < 45) 465 466 requirements = [ ["cost", 1], ["speed", 0.5], ["costsResource", 0.5, "stone"], ["costsResource", 0.5, "metal"]]; 466 467 else 467 468 requirements = [ ["strength", 1] ]; 468 469 470 var classes = ["CitizenSoldier", "Infantry"]; 469 471 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);472 // we require at least 30% ranged and 30% melee 473 if ( proba < 0.3 ) 474 classes.push("Ranged") 475 else if ( proba < 0.6 ) 476 classes.push("Melee"); 477 478 template = this.findBestTrainableUnit(gameState, classes, requirements); 477 479 } 478 if (!template && gameState.templates[templateDef])479 template = templateDef;480 480 481 // If the template variable is empty, the default unit (Support unit) 482 // would be used in the next turn 483 // 481 484 // 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));485 if (!template && gameState.templates[templateDef]) 486 queues.villager.addPlan(new m.TrainingPlan(gameState, templateDef, { "role": "worker", "base": 0 }, size, size)); 484 487 else if (template) 485 488 queues.citizenSoldier.addPlan(new m.TrainingPlan(gameState, template, { "role": "worker", "base": 0 }, size, size)); 486 489 }; … … 504 507 var availableResources = gameState.ai.queueManager.getAvailableResources(gameState); // available (gathered) resources 505 508 for (let type in remainingResources) 506 509 { 507 if (type === "food")508 continue;509 510 if (availableResources[type] > 800) 510 511 continue; 511 512 if (remainingResources[type] > 800) … … 638 639 } 639 640 this.turnCache.gatherRates = true; 640 641 } 641 642 642 643 return this.currentRates; 643 644 }; 644 645 … … 2065 2066 "wantedRates": this.wantedRates, 2066 2067 "currentRates": this.currentRates, 2067 2068 "lastFailedGather": this.lastFailedGather, 2068 " femaleRatio": this.femaleRatio,2069 "workerRatio": this.workerRatio, 2069 2070 "targetNumWorkers": this.targetNumWorkers, 2070 2071 "lastTerritoryUpdate": this.lastTerritoryUpdate, 2071 2072 "stopBuilding": this.stopBuilding,