Line data Source code
1 : function Upkeep() {} 2 : 3 1 : Upkeep.prototype.Schema = 4 : "<a:help>Controls the resource upkeep of an entity.</a:help>" + 5 : "<element name='Rates' a:help='Upkeep Rates'>" + 6 : Resources.BuildSchema("nonNegativeDecimal") + 7 : "</element>" + 8 : "<element name='Interval' a:help='Number of milliseconds must pass for the player to pay the next upkeep.'>" + 9 : "<ref name='nonNegativeDecimal'/>" + 10 : "</element>"; 11 : 12 1 : Upkeep.prototype.Init = function() 13 : { 14 1 : this.upkeepInterval = +this.template.Interval; 15 1 : this.CheckTimer(); 16 : }; 17 : 18 : /** 19 : * @return {number} - The interval between resource subtractions, in ms. 20 : */ 21 1 : Upkeep.prototype.GetInterval = function() 22 : { 23 8 : return this.upkeepInterval; 24 : }; 25 : 26 : /** 27 : * @return {Object} - The upkeep rates in the form of { "resourceName": {number} }. 28 : */ 29 1 : Upkeep.prototype.GetRates = function() 30 : { 31 3 : return this.rates; 32 : }; 33 : 34 : /** 35 : * @return {boolean} - Whether this entity has at least one non-zero amount of resources to pay. 36 : */ 37 1 : Upkeep.prototype.ComputeRates = function() 38 : { 39 13 : this.rates = {}; 40 13 : let hasUpkeep = false; 41 13 : for (let resource in this.template.Rates) 42 : { 43 26 : let rate = ApplyValueModificationsToEntity("Upkeep/Rates/" + resource, +this.template.Rates[resource], this.entity); 44 26 : if (rate) 45 : { 46 10 : this.rates[resource] = rate; 47 10 : hasUpkeep = true; 48 : } 49 : } 50 : 51 13 : return hasUpkeep; 52 : }; 53 : 54 : /** 55 : * Try to subtract the needed resources. 56 : * Data and lateness are unused. 57 : */ 58 1 : Upkeep.prototype.Pay = function(data, lateness) 59 : { 60 302 : let cmpPlayer = QueryOwnerInterface(this.entity); 61 302 : if (!cmpPlayer) 62 0 : return; 63 : 64 302 : if (!cmpPlayer.TrySubtractResources(this.rates)) 65 2 : this.HandleInsufficientUpkeep(); 66 : else 67 300 : this.HandleSufficientUpkeep(); 68 : }; 69 : 70 : /** 71 : * E.g. take a hitpoint, reduce CP. 72 : */ 73 1 : Upkeep.prototype.HandleInsufficientUpkeep = function() 74 : { 75 2 : if (this.unpayed) 76 1 : return; 77 : 78 1 : let cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity); 79 1 : if (cmpIdentity) 80 0 : cmpIdentity.SetControllable(false); 81 1 : this.unpayed = true; 82 : }; 83 : 84 : /** 85 : * Reset to the previous stage. 86 : */ 87 1 : Upkeep.prototype.HandleSufficientUpkeep = function() 88 : { 89 300 : if (!this.unpayed) 90 300 : return; 91 : 92 0 : let cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity); 93 0 : if (cmpIdentity) 94 0 : cmpIdentity.SetControllable(true); 95 0 : delete this.unpayed; 96 : }; 97 : 98 1 : Upkeep.prototype.OnValueModification = function(msg) 99 : { 100 9 : if (msg.component != "Upkeep") 101 0 : return; 102 : 103 9 : this.CheckTimer(); 104 : }; 105 : 106 : /** 107 : * Recalculate the interval and update the timer accordingly. 108 : */ 109 1 : Upkeep.prototype.CheckTimer = function() 110 : { 111 10 : if (!this.ComputeRates()) 112 : { 113 2 : if (!this.timer) 114 1 : return; 115 : 116 1 : let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 117 1 : cmpTimer.CancelTimer(this.timer); 118 1 : delete this.timer; 119 1 : return; 120 : } 121 : 122 8 : let oldUpkeepInterval = this.upkeepInterval; 123 8 : this.upkeepInterval = ApplyValueModificationsToEntity("Upkeep/Interval", +this.template.Interval, this.entity); 124 8 : if (this.upkeepInterval < 0) 125 : { 126 1 : let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 127 1 : cmpTimer.CancelTimer(this.timer); 128 1 : delete this.timer; 129 1 : return; 130 : } 131 : 132 7 : if (this.timer) 133 : { 134 4 : if (this.upkeepInterval == oldUpkeepInterval) 135 2 : return; 136 : 137 : // If the timer wasn't invalidated before (interval <= 0), just update it. 138 2 : if (oldUpkeepInterval > 0) 139 : { 140 1 : let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 141 1 : cmpTimer.UpdateRepeatTime(this.timer, this.upkeepInterval); 142 1 : return; 143 : } 144 : } 145 : 146 4 : let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 147 4 : this.timer = cmpTimer.SetInterval(this.entity, IID_Upkeep, "Pay", this.upkeepInterval, this.upkeepInterval, undefined); 148 : }; 149 : 150 1 : Engine.RegisterComponentType(IID_Upkeep, "Upkeep", Upkeep);