Ticket #1353: 1353_InconsistentGathering.B.patch

File 1353_InconsistentGathering.B.patch, 5.6 KB (added by Matt Lott, 12 years ago)

Updated based on review feedback

  • binaries/data/mods/public/simulation/components/ResourceGatherer.js

     
    187187/**
    188188 * Gather from the target entity. This should only be called after a successful range check,
    189189 * and if the target has a compatible ResourceSupply.
    190  * It should be called at a rate of once per second.
     190 * Call interval will be determined by gather rate, so always gather 1 amount when called.
    191191 */
    192192ResourceGatherer.prototype.PerformGather = function(target)
    193193{
    194     var rate = this.GetTargetGatherRate(target);
    195     if (!rate)
     194    var cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI);
     195    if (!cmpUnitAI || !cmpUnitAI.CanGather(target))
    196196        return { "exhausted": true };
    197197
     198    var gatherAmount = 1;
     199
    198200    var cmpResourceSupply = Engine.QueryInterface(target, IID_ResourceSupply);
    199201    var type = cmpResourceSupply.GetType();
    200202
     
    205207    // Find the maximum so we won't exceed our capacity
    206208    var maxGathered = this.GetCapacities()[type.generic] - this.carrying[type.generic];
    207209
    208     var status = cmpResourceSupply.TakeResources(Math.min(rate, maxGathered));
     210    var status = cmpResourceSupply.TakeResources(Math.min(gatherAmount, maxGathered));
    209211
    210212    this.carrying[type.generic] += status.amount;
    211213
     
    244246
    245247    var type = cmpResourceSupply.GetType();
    246248
     249    var rates = this.GetGatherRates();
     250
    247251    var rate;
    248     if (type.specific && this.GetGatherRates()[type.generic+"."+type.specific])
    249         rate = this.GetGatherRates()[type.generic+"."+type.specific];
     252    if (type.specific && rates[type.generic+"."+type.specific])
     253        rate = rates[type.generic+"."+type.specific];
    250254    else
    251         rate = this.GetGatherRates()[type.generic];
    252 
     255        rate = rates[type.generic];
     256   
    253257    return (rate || 0);
    254258};
    255259
  • binaries/data/mods/public/simulation/components/ResourceSupply.js

     
    5454
    5555ResourceSupply.prototype.TakeResources = function(rate)
    5656{
    57     // Internally we handle fractional resource amounts (to be accurate
    58     // over long periods of time), but want to return integers (so players
    59     // have a nice simple integer amount of resources). So return the
    60     // difference between rounded values:
     57    // 'rate' should be a non-negative integer
    6158
    6259    var old = this.amount;
    6360    this.amount = Math.max(0, old - rate);
     61    var change = old - this.amount;
    6462
    65     // (use ceil instead of floor so that we continue returning non-zero values even if 0 < amount < 1)
    66     var change = Math.ceil(old) - Math.ceil(this.amount);
    67 
    6863    // Remove entities that have been exhausted
    6964    if (this.amount == 0)
    7065        Engine.DestroyEntity(this.entity);
    7166
    7267    Engine.PostMessage(this.entity, MT_ResourceSupplyChanged, { "from": old, "to": this.amount });
    7368
    74     return { "amount": change, "exhausted": (old == 0) };
     69    return { "amount": change, "exhausted": (this.amount == 0) };
    7570};
    7671
    7772ResourceSupply.prototype.GetType = function()
  • binaries/data/mods/public/simulation/components/UnitAI.js

     
    944944
    945945            "GATHERING": {
    946946                "enter": function() {
    947                     this.StartTimer(1000, 1000);
     947                    var target = this.order.data.target;
     948                   
     949                    // Calculate timing based on gather rates
     950                    // This allows the gather rate to control how often we gather, instead of how much.
     951                    var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
     952                    var rate = cmpResourceGatherer.GetTargetGatherRate(target);
    948953
     954                    if (!rate)
     955                    {
     956                        // No rate, give up on gathering
     957                        this.FinishOrder();
     958                        return;
     959                    }
     960
     961                    // Scale timing interval based on rate, and start timer
     962                    var offset = 1000; // Should be at least longer than repeat time.  See attacking.enter.
     963                    var repeat = 1000 / rate;
     964                    this.StartTimer(offset, repeat);
     965
    949966                    // We want to start the gather animation as soon as possible,
    950967                    // but only if we're actually at the target and it's still alive
    951968                    // (else it'll look like we're chopping empty air).
    952969                    // (If it's not alive, the Timer handler will deal with sending us
    953970                    // off to a different target.)
    954                     if (this.CheckTargetRange(this.order.data.target, IID_ResourceGatherer))
     971                    if (this.CheckTargetRange(target, IID_ResourceGatherer))
    955972                    {
    956973                        var typename = "gather_" + this.order.data.type.specific;
    957974                        this.SelectAnimation(typename, false, 1.0, typename);
     
    19701987    {
    19711988        this.timer = undefined;
    19721989    }
    1973     else
    1974     {
    1975         var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    1976         this.timer = cmpTimer.SetTimeout(this.entity, IID_UnitAI, "TimerHandler", data.timerRepeat - lateness, data);
    1977     }
    19781990
    19791991    UnitFsm.ProcessMessage(this, {"type": "Timer", "data": data, "lateness": lateness});
    19801992};
     
    19922004    var data = { "timerRepeat": repeat };
    19932005
    19942006    var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    1995     this.timer = cmpTimer.SetTimeout(this.entity, IID_UnitAI, "TimerHandler", offset, data);
     2007    if (repeat === undefined)
     2008        this.timer = cmpTimer.SetTimeout(this.entity, IID_UnitAI, "TimerHandler", offset, data);
     2009    else
     2010        this.timer = cmpTimer.SetInterval(this.entity, IID_UnitAI, "TimerHandler", offset, repeat, data);
    19962011};
    19972012
    19982013/**