Changeset 25040

Timestamp:
Mar 12, 2021, 9:45:39 AM (3 years ago)
Author:
Freagarach
Message:

Clean up RemoveBatch -> RemoveItem code in ProductionQueue.

  • Rename RemoveBatch to RemoveItem.
  • Refactor that function. (Don't clear the cached entities when *any* item is removed.)

Fixes the bug that the training is still blocked when a tech is the next in the queue and the blocking item is removed.

Based on a patch by: @Polakrity
Differential revision: D1843
Comments by: @Angen, @bb

Location:
ps/trunk/binaries/data/mods/public/simulation
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js

    r25038 r25040  
    118118        for (let item of queue)
    119119            if (item.unitTemplate && item.unitTemplate === template)
    120                 this.RemoveBatch(item.id);
     120                this.Remove(item.id);
    121121    };
    122122    let updateAllQueuedTemplate = (token, updateTo) => {
     
    509509
    510510/*
    511  * Removes an existing batch of units from the production queue.
     511 * Removes an queue.
    512512 * Refunds resource costs and population reservations.
    513  */
    514 ProductionQueue.prototype.RemoveBatch = function(id)
    515 {
     513 * item.player is used as this.entity's owner may have changed.
     514 */
     515ProductionQueue.prototype.RemoveItem = function(id)
     516{
     517    let itemIndex = this.queue.findIndex(item => item.id == id);
     518    if (itemIndex == -1)
     519        return;
     520
    516521    // Destroy any cached entities (those which didn't spawn for some reason).
    517     for (let ent of this.entityCache)
    518         Engine.DestroyEntity(ent);
    519 
    520     this.entityCache = [];
    521 
    522     for (let i = 0; i < this.queue.length; ++i)
    523     {
    524         // Find the item to remove.
    525         let item = this.queue[i];
    526         if (item.id != id)
    527             continue;
    528 
    529         // Update entity count in the EntityLimits component.
    530         if (item.unitTemplate)
    531         {
    532             let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
    533             let template = cmpTemplateManager.GetTemplate(item.unitTemplate);
    534             if (template.TrainingRestrictions)
    535             {
    536                 let cmpPlayerEntityLimits = QueryPlayerIDInterface(item.player, IID_EntityLimits);
    537                 if (cmpPlayerEntityLimits)
    538                     cmpPlayerEntityLimits.ChangeCount(template.TrainingRestrictions.Category, -item.count);
    539                 if (template.TrainingRestrictions.MatchLimit)
    540                     cmpPlayerEntityLimits.ChangeMatchCount(item.unitTemplate, -item.count);
    541             }
    542         }
    543 
    544         // Refund the resource cost for this batch.
    545         let totalCosts = {};
    546         let cmpStatisticsTracker = QueryPlayerIDInterface(item.player, IID_StatisticsTracker);
    547         for (let r in item.resources)
    548         {
    549             totalCosts[r] = Math.floor(item.count * item.resources[r]);
    550             if (cmpStatisticsTracker)
    551                 cmpStatisticsTracker.IncreaseResourceUsedCounter(r, -totalCosts[r]);
    552         }
    553 
    554         let cmpPlayer = QueryPlayerIDInterface(item.player);
    555         if (cmpPlayer)
    556         {
    557             cmpPlayer.AddResources(totalCosts);
    558 
    559             // Remove reserved population slots if necessary.
    560             if (item.productionStarted && item.unitTemplate)
    561                 cmpPlayer.UnReservePopulationSlots(item.population * item.count);
    562         }
    563 
    564         // Mark the research as stopped if we cancel it.
    565         if (item.technologyTemplate)
    566         {
    567             // item.player is used as this.entity's owner may be invalid (deletion, etc.)
    568             let cmpTechnologyManager = QueryPlayerIDInterface(item.player, IID_TechnologyManager);
    569             if (cmpTechnologyManager)
    570                 cmpTechnologyManager.StoppedResearch(item.technologyTemplate, true);
    571             this.SetAnimation("idle");
    572         }
    573 
    574         this.queue.splice(i, 1);
    575         Engine.PostMessage(this.entity, MT_ProductionQueueChanged, null);
    576 
    577         return;
    578     }
     522    if (itemIndex == 0 && this.entityCache.length)
     523    {
     524        for (let ent of this.entityCache)
     525            Engine.DestroyEntity(ent);
     526
     527        this.entityCache = [];
     528    }
     529
     530    let item = this.queue[itemIndex];
     531
     532    // Update entity count in the EntityLimits component.
     533    if (item.unitTemplate)
     534    {
     535        let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
     536        let template = cmpTemplateManager.GetTemplate(item.unitTemplate);
     537        if (template.TrainingRestrictions)
     538        {
     539            let cmpPlayerEntityLimits = QueryPlayerIDInterface(item.player, IID_EntityLimits);
     540            if (cmpPlayerEntityLimits)
     541                cmpPlayerEntityLimits.ChangeCount(template.TrainingRestrictions.Category, -item.count);
     542            if (template.TrainingRestrictions.MatchLimit)
     543                cmpPlayerEntityLimits.ChangeMatchCount(item.unitTemplate, -item.count);
     544        }
     545    }
     546
     547    let totalCosts = {};
     548    let cmpStatisticsTracker = QueryPlayerIDInterface(item.player, IID_StatisticsTracker);
     549    for (let resource in item.resources)
     550    {
     551        totalCosts[resource] = Math.floor(item.count * item.resources[resource]);
     552        if (cmpStatisticsTracker)
     553            cmpStatisticsTracker.IncreaseResourceUsedCounter(resource, -totalCosts[resource]);
     554    }
     555
     556    let cmpPlayer = QueryPlayerIDInterface(item.player);
     557    if (cmpPlayer)
     558    {
     559        cmpPlayer.AddResources(totalCosts);
     560        if (item.productionStarted && item.unitTemplate)
     561            cmpPlayer.UnReservePopulationSlots(item.population * item.count);
     562        if (itemIndex == 0)
     563            cmpPlayer.UnBlockTraining();
     564    }
     565
     566    if (item.technologyTemplate)
     567    {
     568        let cmpTechnologyManager = QueryPlayerIDInterface(item.player, IID_TechnologyManager);
     569        if (cmpTechnologyManager)
     570            cmpTechnologyManager.StoppedResearch(item.technologyTemplate, true);
     571        this.SetAnimation("idle");
     572    }
     573
     574    this.queue.splice(itemIndex, 1);
     575    Engine.PostMessage(this.entity, MT_ProductionQueueChanged, null);
     576
     577    if (!this.queue.length)
     578        this.StopTimer();
    579579};
    580580
     
    613613
    614614    while (this.queue.length)
    615         this.RemoveBatch(this.queue[0].id);
     615        this.Remove(this.queue[0].id);
    616616};
    617617
     
    630630ProductionQueue.prototype.OnOwnershipChanged = function(msg)
    631631{
    632     if (msg.from != INVALID_PLAYER)
    633     {
    634         // Unset flag that previous owner's training may be blocked.
    635         let cmpPlayer = QueryPlayerIDInterface(msg.from);
    636         if (cmpPlayer && this.queue.length)
    637             cmpPlayer.UnBlockTraining();
    638     }
    639632    if (msg.to != INVALID_PLAYER)
    640633        this.CalculateEntitiesMap();
     
    657650    // Reset the queue to refund any resources.
    658651    this.ResetQueue();
    659     this.StopTimer();
    660652};
    661653
     
    898890        time -= item.timeRemaining;
    899891        this.queue.shift();
    900         Engine.PostMessage(this.entity, MT_ProductionQueueChanged, {});
     892        Engine.PostMessage(this.entity, MT_ProductionQueueChanged, );
    901893    }
    902894
    903895    if (!this.queue.length)
    904     {
    905896        this.StopTimer();
    906 
    907         // Unset flag that training is blocked.
    908         // (This might happen when the player unqueues all batches.)
    909         cmpPlayer.UnBlockTraining();
    910     }
    911897};
    912898
  • ps/trunk/binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js

    r25038 r25040  
    299299
    300300    // Check that when the batch is removed the counts are subtracted again.
    301     cmpProdQueue.RemoveBatch(cmpProdQueue.GetQueue()[0].id);
     301    cmpProdQueue.Remove(cmpProdQueue.GetQueue()[0].id);
    302302    TS_ASSERT_EQUALS(cmpEntLimits.GetCounts().some_limit, 3);
    303303    TS_ASSERT_EQUALS(cmpEntLimits.GetMatchCounts().some_template, 3);
     
    407407    });
    408408
    409     ConstructComponent(SYSTEM_ENTITY, "Timer", null);
     409    ConstructComponent(SYSTEM_ENTITY, "Timer", null);
    410410
    411411    AddMock(SYSTEM_ENTITY, IID_TemplateManager, {
     
    452452    cmpProdQueue.AddBatch("some_template", "unit", 3);
    453453    TS_ASSERT_EQUALS(cmpProdQueue.GetQueue().length, 1);
    454     cmpProdQueue.ProgressTimeout(null, 0);
     454    cmp);
    455455    TS_ASSERT_EQUALS(cmpPlayerBlockSpy._called, 1);
    456456
     
    458458    TS_ASSERT_EQUALS(cmpProdQueue.GetQueue().length, 2);
    459459
    460     cmpProdQueue.RemoveBatch(1);
     460    cmpProdQueue.Remove(1);
    461461    TS_ASSERT_EQUALS(cmpProdQueue.GetQueue().length, 1);
    462     TS_ASSERT_EQUALS(cmpPlayerUnblockSpy._called, 0);
    463 
    464     cmpProdQueue.RemoveBatch(2);
     462    TS_ASSERT_EQUALS(cmpPlayerUnblockSpy._called, );
     463
     464    cmpProdQueue.Remove(2);
    465465    TS_ASSERT_EQUALS(cmpProdQueue.GetQueue().length, 0);
    466     cmpProdQueue.ProgressTimeout(null, 0);
    467     TS_ASSERT_EQUALS(cmpPlayerUnblockSpy._called, 1);
     466    cmp);
     467    TS_ASSERT_EQUALS(cmpPlayerUnblockSpy._called, );
    468468
    469469    cmpProdQueue.AddBatch("some_template", "unit", 3);
    470470    cmpProdQueue.AddBatch("some_template", "unit", 3);
    471471    cmpPlayer.TryReservePopulationSlots = () => false;
    472     cmpProdQueue.RemoveBatch(3);
    473     cmpProdQueue.ProgressTimeout(null, 0);
    474     TS_ASSERT_EQUALS(cmpPlayerUnblockSpy._called, 2);
    475 
     472    cmpProdQueue.Remove(3);
     473    );
     474    );
     475    TS_ASSERT_EQUALS(cmpPlayerUnblockSpy._called, 4);
    476476}
    477477
  • ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js

    r25024 r25040  
    376376    "stop-production": function(player, cmd, data)
    377377    {
    378         var queue = Engine.QueryInterface(cmd.entity, IID_ProductionQueue);
    379         if (queue)
    380             queue.RemoveBatch(cmd.id);
     378        ueue = Engine.QueryInterface(cmd.entity, IID_ProductionQueue);
     379        if (ueue)
     380            (cmd.id);
    381381    },
    382382
Note: See TracChangeset for help on using the changeset viewer.