Ticket #4003: t4003-part2.patch

File t4003-part2.patch, 5.8 KB (added by mimo, 8 years ago)

second (and last) part of the patch, dealing with cost of trained units

  • binaries/data/mods/public/simulation/ai/petra/queueplanResearch.js

     
    1515        this.cost = new API3.Resources(this.template.cost(researchers[0]));
    1616
    1717    this.category = "technology";
    18 
    1918    this.rush = rush;
    2019
    2120    return true;
  • binaries/data/mods/public/simulation/ai/petra/queueplanTraining.js

     
    99        return false;
    1010    }
    1111
     12    // Refine the estimated cost and add pop cost
     13    let trainers = this.getBestTrainers(gameState);
     14    let trainer = trainers ? trainers[0] : undefined;
     15    this.cost = new API3.Resources(this.template.cost(trainer), +this.template._template.Cost.Population);
     16
    1217    this.category = "unit";
    13     this.cost = new API3.Resources(this.template.cost(), +this.template._template.Cost.Population);
    14 
    1518    this.number = number;
    1619    this.maxMerge = maxMerge;
    1720
     
    2225
    2326m.TrainingPlan.prototype.canStart = function(gameState)
    2427{
    25     let trainers = gameState.findTrainers(this.type);
     28    this.trainers = this.getBestTrainers(gameState);
     29    if (!this.trainers)
     30        return false;
     31    this.cost = new API3.Resources(this.template.cost(this.trainers[0]), +this.template._template.Cost.Population);
     32    return true;
     33};
     34
     35m.TrainingPlan.prototype.getBestTrainers = function(gameState)
     36{
     37    if (this.metadata && this.metadata.trainer)
     38    {
     39        let trainer = gameState.getEntityById(this.metadata.trainer);
     40        if (trainer)
     41            return [trainer];
     42    }
     43
     44    let allTrainers = gameState.findTrainers(this.type);
    2645    if (this.metadata && this.metadata.sea)
    27         trainers = trainers.filter(API3.Filters.byMetadata(PlayerID, "sea", this.metadata.sea));
     46        allTrainers = allTrainers.filter(API3.Filters.byMetadata(PlayerID, "sea", this.metadata.sea));
     47    if (this.metadata && this.metadata.base)
     48        allTrainers = allTrainers.filter(API3.Filters.byMetadata(PlayerID, "base", this.metadata.base));
     49    if (!allTrainers || !allTrainers.hasEntities())
     50        return undefined;
    2851
    29     return trainers.length !== 0;
     52    // Keep only trainers with smallest cost
     53    let costMin = Math.min();
     54    let trainers;
     55    for (let ent of allTrainers.values())
     56    {
     57        let cost = this.template.costSum(ent);
     58        if (cost === costMin)
     59            trainers.push(ent);
     60        else if (cost < costMin)
     61        {
     62            costMin = cost;
     63            trainers = [ent];
     64        }
     65    }
     66    return trainers;
    3067};
    3168
    3269m.TrainingPlan.prototype.start = function(gameState)
     
    3774        for (let key in this.metadata)
    3875            if (key !== "trainer")
    3976                metadata[key] = this.metadata[key];
    40         let trainer = gameState.getEntityById(this.metadata.trainer);
    41         if (trainer)
    42             trainer.train(gameState.civ(), this.type, this.number, metadata, this.promotedTypes(gameState));
    43         this.onStart(gameState);
    44         return;
     77        this.metadata = metadata;
    4578    }
    4679
    47     let trainersColl = gameState.findTrainers(this.type);
    48     if (this.metadata && this.metadata.sea)
    49         trainersColl = trainersColl.filter(API3.Filters.byMetadata(PlayerID, "sea", this.metadata.sea));
    50     else if (this.metadata && this.metadata.base)
    51         trainersColl = trainersColl.filter(API3.Filters.byMetadata(PlayerID, "base", this.metadata.base));
    52 
    53     // Prefer training buildings with short queues
    54     // (TODO: this should also account for units added to the queue by
    55     // plans that have already been executed this turn)
    56     if (trainersColl.length)
     80    if (this.trainers.length > 1)
    5781    {
    58         let trainers = trainersColl.toEntityArray();
    5982        let wantedIndex;
    6083        if (this.metadata && this.metadata.index)
    6184            wantedIndex = this.metadata.index;
    6285        let workerUnit = this.metadata && this.metadata.role && this.metadata.role == "worker";
    6386        let supportUnit = this.template.hasClass("Support");
    64         trainers.sort(function(a, b) {
     87        this.trainers.sort(function(a, b) {
     88            // Prefer training buildings with short queues
    6589            let aa = a.trainingQueueTime();
    6690            let bb = b.trainingQueueTime();
     91            // Give priority to support units in the cc
    6792            if (a.hasClass("Civic") && !supportUnit)
    6893                aa += 10;
    6994            if (b.hasClass("Civic") && !supportUnit)
    7095                bb += 10;
     96            // And support units should not be too near to dangerous place
    7197            if (supportUnit)
    7298            {
    7399                if (gameState.ai.HQ.isNearInvadingArmy(a.position()))
     
    75101                if (gameState.ai.HQ.isNearInvadingArmy(b.position()))
    76102                    bb += 50;
    77103            }
     104            // Give also priority to buildings with the right accessibility
    78105            let aBase = a.getMetadata(PlayerID, "base");
    79106            let bBase = b.getMetadata(PlayerID, "base");
    80107            if (wantedIndex)
     
    84111                if (!bBase || gameState.ai.HQ.getBaseByID(bBase).accessIndex != wantedIndex)
    85112                    bb += 30;
    86113            }
    87             // then, if worker, small preference for bases with less workers
     114            // Then, if workers, small preference for bases with less workers
    88115            if (workerUnit && aBase && bBase && aBase != bBase)
    89116            {
    90117                let apop = gameState.ai.HQ.getBaseByID(aBase).workers.length;
     
    96123            }
    97124            return aa - bb;
    98125        });
    99         if (this.metadata && this.metadata.base !== undefined && this.metadata.base === 0)
    100             this.metadata.base = trainers[0].getMetadata(PlayerID, "base");
    101         trainers[0].train(gameState.civ(), this.type, this.number, this.metadata, this.promotedTypes(gameState));
    102126    }
    103     else if (gameState.ai.Config.debug > 1)
    104         warn(" no trainers for this queue " + this.type);
     127
     128    if (this.metadata && this.metadata.base !== undefined && this.metadata.base === 0)
     129        this.metadata.base = this.trainers[0].getMetadata(PlayerID, "base");
     130    this.trainers[0].train(gameState.civ(), this.type, this.number, this.metadata, this.promotedTypes(gameState));
     131
    105132    this.onStart(gameState);
    106133};
    107134