Ticket #3321: 2_ResourceTrickle.patch

File 2_ResourceTrickle.patch, 6.3 KB (added by s0600204, 9 years ago)

Second patch (see ticket description)

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

    function ResourceTrickle() {}  
    22
    33ResourceTrickle.prototype.Schema =
    44    "<a:help>Controls the resource trickle ability of the unit.</a:help>" +
     5    "<a:example>" +
     6        "<Rates>" +
     7            "<food>0.5</food>" +
     8            "<stone>1.5</stone>" +
     9        "</Rates>" +
     10        "<Interval>1000</Interval>" +
     11        "<Type>global</Type>" +
     12    "</a:example>" +
    513    "<element name='Rates' a:help='Trickle Rates'>" +
    614        "<interleave>" +
    715            "<optional>" +
    ResourceTrickle.prototype.Schema =  
    2634            "</optional>" +
    2735        "</interleave>" +
    2836    "</element>" +
    29     "<element name='Interval' a:help='Number of miliseconds must pass for the player to gain the next trickle.'>" +
     37    "<element name='Interval' a:help='Number of milliseconds of game time that must pass for the player to gain the next trickle.'>" +
    3038        "<ref name='nonNegativeDecimal'/>" +
    31     "</element>";
     39    "</element>" +
     40    "<optional>" +
     41        "<element name='Type' a:help='Type of trickle.'>" +
     42            "<choice>" +
     43                "<value a:help='Trickle is at a continuous rate throughout the game. Default value'>global</value>" +
     44                "<value a:help='Trickle rate is governed by the percentage of world controlled as defined by territory borders'>territory</value>" +
     45                "<value a:help='Trickle rate is per garrisoned unit'>garrison</value>" +
     46            "</choice>" +
     47        "</element>" +
     48    "</optional>";
    3249
    3350ResourceTrickle.prototype.Init = function()
    3451{
    35     // Call the timer
    36     var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    37     cmpTimer.SetInterval(this.entity, IID_ResourceTrickle, "Trickle", this.GetTimer(), this.GetTimer(), undefined)
     52    // Set type
     53    this.trickleType = this.template.Type || "global";
     54    this.interval = +this.template.Interval;
     55   
     56    // Cache rates and interval
     57    this.OnValueModification({"component":"ResourceTrickle"});
     58   
     59    // Check the timer
     60    this.CheckTimer();
    3861};
    3962
    40 ResourceTrickle.prototype.GetTimer = function()
     63/**
     64 * Fetches the interval period between timer calls
     65 */
     66ResourceTrickle.prototype.GetInterval = function()
    4167{
    42     var interval = +this.template.Interval;
    43     return interval;
     68    return this.interval;
    4469};
    4570
    46 ResourceTrickle.prototype.GetRates = function()
     71/**
     72 * Checks the timer, and starts/stops it if neccesary. By passing true to this function, the timer can be restarted.
     73 */
     74ResourceTrickle.prototype.CheckTimer = function(restart = false)
    4775{
    48     var rates = {};
    49     for (var resource in this.template.Rates)
    50         rates[resource] = ApplyValueModificationsToEntity("ResourceTrickle/Rates/"+resource, +this.template.Rates[resource], this.entity);
     76    var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder);
     77    var garrisonCount = (cmpGarrisonHolder) ? cmpGarrisonHolder.GetEntities().length : -1;
     78   
     79    if (!this.timer)
     80    {
     81        if (this.trickleType !== "garrison" || garrisonCount > 0)
     82        {
     83            var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     84            this.timer = cmpTimer.SetInterval(this.entity, IID_ResourceTrickle, "PerformTrickle", this.GetInterval(), this.GetInterval(), undefined);
     85        }
     86    }
     87    else if (this.trickleType == "garrison" && garrisonCount <= 0)
     88    {
     89        var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     90        cmpTimer.CancelTimer(this.timer);
     91        this.timer = undefined;
     92    }
     93    else if (restart === true)
     94    {
     95        var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     96        cmpTimer.CancelTimer(this.timer);
     97        this.timer = cmpTimer.SetInterval(this.entity, IID_ResourceTrickle, "PerformTrickle", this.GetInterval(), this.GetInterval(), undefined);
     98    }
     99};
    51100
    52     return rates;
     101/**
     102 * Listener for Garrison changes. Modifies the trickle rates if the trickle type is "garrison"
     103 */
     104ResourceTrickle.prototype.OnGarrisonedUnitsChanged = function(msg)
     105{
     106    if (this.trickleType !== "garrison")
     107        return;
     108   
     109    this.OnValueModification({"component":"ResourceTrickle"});
     110    var garrisonCount = Engine.QueryInterface(this.entity, IID_GarrisonHolder).GetEntities().length;
     111    for (let res in this.rates)
     112        this.rates[res] *= garrisonCount;
     113   
     114    this.CheckTimer();
    53115};
    54116
    55 // Do the actual work here
    56 ResourceTrickle.prototype.Trickle = function(data, lateness)
     117/**
     118 * Listener for Territory Changes. Modifies the trickle rates if the trickle type is "territory"
     119 */
     120ResourceTrickle.prototype.OnTerritoriesChanged = function(msg)
    57121{
     122    if (this.trickleType !== "territory")
     123        return;
     124
     125    this.OnValueModification({"component":"ResourceTrickle"});
     126
    58127    var cmpPlayer = QueryOwnerInterface(this.entity);
    59     if (!cmpPlayer)
     128    var cmpTerritoryManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TerritoryManager);
     129    if (!cmpPlayer || !cmpTerritoryManager)
    60130        return;
    61131
    62     var rates = this.GetRates();
    63     for (var resource in rates)
    64         cmpPlayer.AddResource(resource, rates[resource]);
     132    var percentage = cmpTerritoryManager.GetTerritoryPercentage(cmpPlayer.GetPlayerID());
     133    for (let res in this.rates)
     134        this.rates[res] *= percentage/100;
     135
     136    this.CheckTimer();
     137}
     138
     139/**
     140 * Listener for Value Modification changes. Permits adjustment of rates and the interval period via technology or auras
     141 */
     142ResourceTrickle.prototype.OnValueModification = function(msg)
     143{
     144    if (msg.component != "ResourceTrickle")
     145        return;
     146   
     147    this.rates = {};
     148    for (let res in this.template.Rates)
     149    {
     150        let rate = +this.template.Rates[res];
     151        this.rates[res] = ApplyValueModificationsToEntity("ResourceTrickle/Rates/"+res, rate, this.entity);
     152    }
     153   
     154    var oldInterval = this.interval;
     155    this.interval = ApplyValueModificationsToEntity("ResourceTrickle/Interval", +this.template.Interval, this.entity);
     156    if (this.interval !== oldInterval)
     157        this.CheckTimer(true); // if interval has been changed, restart the timer
     158};
     159
     160/**
     161 * Fetch the Trickle Rates, with any modifications applied
     162 */
     163ResourceTrickle.prototype.GetRates = function()
     164{
     165    return this.rates;
     166};
     167
     168/**
     169 * Trickle Resources as defined by template.
     170 */
     171ResourceTrickle.prototype.PerformTrickle = function(data, lateness)
     172{
     173    var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
     174    if (cmpPlayer)
     175        cmpPlayer.AddResources(this.GetRates());
    65176};
    66177
    67178Engine.RegisterComponentType(IID_ResourceTrickle, "ResourceTrickle", ResourceTrickle);