Ticket #3586: headquarters_js_v2.patch

File headquarters_js_v2.patch, 8.9 KB (added by otero, 8 years ago)
  • binaries/data/mods/public/simulation/ai/petra/headquarters.js

     
    2929
    3030    // workers configuration
    3131    this.targetNumWorkers = this.Config.Economy.targetNumWorkers;
    32     this.femaleRatio = this.Config.Economy.femaleRatio;
     32    this.workerRatio = this.Config.Economy.workerRatio;
    3333
    3434    this.lastTerritoryUpdate = -1;
    3535    this.stopBuilding = new Map(); // list of buildings to stop (temporarily) production because no room
     
    211211            ent.setMetadata(PlayerID, "role", undefined);
    212212            ent.setMetadata(PlayerID, "subrole", undefined);
    213213            ent.setMetadata(PlayerID, "plan", undefined);
    214             ent.setMetadata(PlayerID, "PartOfArmy", undefined);     
     214            ent.setMetadata(PlayerID, "PartOfArmy", undefined);
    215215            if (ent.hasClass("Trader"))
    216216            {
    217217                ent.setMetadata(PlayerID, "role", "trader");
    218218                ent.setMetadata(PlayerID, "route", undefined);
    219219            }
    220             if (ent.hasClass("Female") || ent.hasClass("CitizenSoldier"))
     220            if (ent.hasClass("Worker"))
    221221            {
    222222                ent.setMetadata(PlayerID, "role", "worker");
    223223                ent.setMetadata(PlayerID, "subrole", "idle");
     
    379379// Called by the "town phase" research plan once it's started
    380380m.HQ.prototype.OnTownPhase = function(gameState)
    381381{
    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;
    384384
    385385    var phaseName = gameState.getTemplate(gameState.townPhase()).name();
    386386    m.chatNewPhase(gameState, phaseName, true);
     
    389389// Called by the "city phase" research plan once it's started
    390390m.HQ.prototype.OnCityPhase = function(gameState)
    391391{
    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;
    394394
    395395    // increase the priority of defense buildings to free this queue for our first fortress
    396396    gameState.ai.queueManager.changePriority("defenseBuilding", 2*this.Config.priorities.defenseBuilding);
     
    399399    m.chatNewPhase(gameState, phaseName, true);
    400400};
    401401
    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
    405403m.HQ.prototype.trainMoreWorkers = function(gameState, queues)
    406404{
    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);
    409409
     410    // Count the workers in the world and in progress
     411    var numberOfWorkers = gameState.countEntitiesAndQueuedByType(templateDef);
     412
    410413    // counting the workers that aren't part of a plan
    411     var numWorkers = 0;
     414    var numberOfIddleWorkers = 0;
    412415    gameState.getOwnUnits().forEach (function (ent) {
    413416        if (ent.getMetadata(PlayerID, "role") == "worker" && ent.getMetadata(PlayerID, "plan") == undefined)
    414             ++numWorkers;
     417            ++numberOfIddleWorkers;
    415418    });
    416     var numInTraining = 0;
     419    var numberOfWorkersInTraining = 0;
    417420    gameState.getOwnTrainingFacilities().forEach(function(ent) {
    418421        ent.trainingQueue().forEach(function(item) {
    419422            if (item.metadata && item.metadata.role && item.metadata.role == "worker" && item.metadata.plan == undefined)
    420                 numWorkers += item.count;
    421             numInTraining += item.count;
     423                numberOfIddleWorkers += item.count;
     424            numberOfWorkersInTraining += item.count;
    422425        });
    423426    });
    424427
    425428    // Anticipate the optimal batch size when this queue will start
    426     // and adapt the batch size of the first and second queued workers and females to the present population
     429    // and adapt the batch size of the first and second queued workers to the present population
    427430    // to ease a possible recovery if our population was drastically reduced by an attack
    428431    // (need to go up to second queued as it is accounted in queueManager)
    429     var size = numWorkers < 12 ? 1 : Math.min(5, Math.ceil(numWorkers / 10));
     432    var size = numberOfIddleWorkers < 12 ? 1 : Math.min(5, Math.ceil(numberOfIddleWorkers / 10));
    430433    if (queues.villager.plans[0])
    431434    {
    432435        queues.villager.plans[0].number = Math.min(queues.villager.plans[0].number, size);
     
    440443            queues.citizenSoldier.plans[1].number = Math.min(queues.citizenSoldier.plans[1].number, size);
    441444    }
    442445
    443     var numQueuedF = queues.villager.countQueuedUnits();
    444     var numQueuedS = queues.citizenSoldier.countQueuedUnits();
    445     var numQueued = numQueuedS + numQueuedF;
    446     var numTotal = numWorkers + numQueued;
     446    var numberOfQueuedWorkers = queues.villager.countQueuedUnits();
     447    var numberOfQueuedSoldiers = queues.citizenSoldier.countQueuedUnits();
     448    var numberQueued = numberOfQueuedSoldiers + numberOfQueuedWorkers;
     449    var numberTotal = numberOfIddleWorkers + numberQueued;
    447450
    448     if (this.saveResources && numTotal > this.Config.Economy.popForTown + 10)
     451    if (this.saveResources && numberTotal > this.Config.Economy.popForTown + 10)
    449452        return;
    450     if (numTotal > this.targetNumWorkers || (numTotal >= this.Config.Economy.popForTown &&
     453    if (numberTotal > this.targetNumWorkers || (numberTotal >= this.Config.Economy.popForTown &&
    451454        gameState.currentPhase() == 1 && !gameState.isResearching(gameState.townPhase())))
    452455        return;
    453     if (numQueued > 50 || (numQueuedF > 20 && numQueuedS > 20) || numInTraining > 15)
     456    if (numberQueued > 50 || (numberOfQueuedWorkers > 20 && numberOfQueuedSoldiers > 20) || numberOfWorkersInTraining > 15)
    454457        return;
    455458
    456     // default template
    457     var templateDef = gameState.applyCiv("units/{civ}_support_female_citizen");
    458459    // 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);
    460461    let template;
    461     if (!gameState.templates[templateDef] || ((numFemales+numQueuedF) > 8 && (numFemales+numQueuedF)/numTotal > femaleRatio))
     462    if ((numberOfWorkers + numberOfQueuedWorkers) > 8 && (numberOfWorkers + numberOfQueuedWorkers)/numberTotal > workerRatio)
    462463    {
    463464        let requirements;
    464         if (numTotal < 45)
     465        if (numberTotal < 45)
    465466            requirements = [ ["cost", 1], ["speed", 0.5], ["costsResource", 0.5, "stone"], ["costsResource", 0.5, "metal"]];
    466467        else
    467468            requirements = [ ["strength", 1] ];
    468469
     470        var classes = ["CitizenSoldier", "Infantry"];
    469471        let proba = Math.random();
    470         if (proba < 0.6)
    471         {   // we require at least 30% ranged and 30% melee
    472             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);
    477479    }
    478     if (!template && gameState.templates[templateDef])
    479         template = templateDef;
    480480
     481    // If the template variable is empty, the default unit (Support unit)
     482    // would be used in the next turn
     483    //
    481484    // 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));
    484487    else if (template)
    485488        queues.citizenSoldier.addPlan(new m.TrainingPlan(gameState, template, { "role": "worker", "base": 0 }, size, size));
    486489};
     
    504507    var availableResources = gameState.ai.queueManager.getAvailableResources(gameState); // available (gathered) resources
    505508    for (let type in remainingResources)
    506509    {
    507         if (type === "food")
    508             continue;
    509510        if (availableResources[type] > 800)
    510511            continue;
    511512        if (remainingResources[type] > 800)
     
    638639        }
    639640        this.turnCache.gatherRates = true;
    640641    }
    641    
     642
    642643    return this.currentRates;
    643644};
    644645
     
    20652066        "wantedRates": this.wantedRates,
    20662067        "currentRates": this.currentRates,
    20672068        "lastFailedGather": this.lastFailedGather,
    2068         "femaleRatio": this.femaleRatio,
     2069        "workerRatio": this.workerRatio,
    20692070        "targetNumWorkers": this.targetNumWorkers,
    20702071        "lastTerritoryUpdate": this.lastTerritoryUpdate,
    20712072        "stopBuilding": this.stopBuilding,