Line data Source code
1 : function Promotion() {} 2 : 3 1 : Promotion.prototype.Schema = 4 : "<element name='Entity'>" + 5 : "<text/>" + 6 : "</element>" + 7 : "<optional>" + 8 : "<element name='TrickleRate' a:help='Trickle of XP gained each second.'>" + 9 : "<ref name='nonNegativeDecimal'/>" + 10 : "</element>" + 11 : "</optional>" + 12 : "<element name='RequiredXp'>" + 13 : "<data type='positiveInteger'/>" + 14 : "</element>"; 15 : 16 1 : Promotion.prototype.Init = function() 17 : { 18 6 : this.currentXp = 0; 19 6 : this.ComputeTrickleRate(); 20 : }; 21 : 22 1 : Promotion.prototype.GetRequiredXp = function() 23 : { 24 30 : return ApplyValueModificationsToEntity("Promotion/RequiredXp", +this.template.RequiredXp, this.entity); 25 : }; 26 : 27 1 : Promotion.prototype.GetCurrentXp = function() 28 : { 29 13 : return this.currentXp; 30 : }; 31 : 32 1 : Promotion.prototype.GetPromotedTemplateName = function() 33 : { 34 7 : return this.template.Entity; 35 : }; 36 : 37 1 : Promotion.prototype.Promote = function(promotedTemplateName) 38 : { 39 4 : let cmpHealth = Engine.QueryInterface(this.entity, IID_Health); 40 4 : if (cmpHealth && cmpHealth.GetHitpoints() == 0) 41 : { 42 1 : this.promotedUnitEntity = INVALID_ENTITY; 43 1 : return; 44 : } 45 : 46 3 : ChangeEntityTemplate(this.entity, promotedTemplateName); 47 : }; 48 : 49 : /** 50 : * @param {number} entity - The entity ID of the entity that this unit has promoted to. 51 : */ 52 1 : Promotion.prototype.SetPromotedEntity = function(entity) 53 : { 54 3 : this.promotedUnitEntity = entity; 55 : }; 56 : 57 1 : Promotion.prototype.IncreaseXp = function(amount) 58 : { 59 : // if the unit was already promoted, but is waiting for the engine to be destroyed 60 : // transfer the gained xp to the promoted unit if applicable 61 32 : if (this.promotedUnitEntity) 62 : { 63 5 : let cmpPromotion = Engine.QueryInterface(this.promotedUnitEntity, IID_Promotion); 64 5 : if (cmpPromotion) 65 5 : cmpPromotion.IncreaseXp(amount); 66 5 : return; 67 : } 68 : 69 27 : this.currentXp += +amount; 70 27 : let requiredXp = this.GetRequiredXp(); 71 : 72 27 : if (this.currentXp >= requiredXp) 73 : { 74 4 : let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 75 4 : let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); 76 4 : if (!cmpPlayer) 77 0 : return; 78 : 79 4 : let playerID = cmpPlayer.GetPlayerID(); 80 4 : this.currentXp -= requiredXp; 81 4 : let promotedTemplateName = this.GetPromotedTemplateName(); 82 : // check if we can upgrade a second time (or even more) 83 4 : while (true) 84 : { 85 7 : let template = cmpTemplateManager.GetTemplate(promotedTemplateName); 86 7 : if (!template.Promotion) 87 0 : break; 88 7 : requiredXp = ApplyValueModificationsToTemplate("Promotion/RequiredXp", +template.Promotion.RequiredXp, playerID, template); 89 : // compare the current xp to the required xp of the promoted entity 90 7 : if (this.currentXp < requiredXp) 91 4 : break; 92 3 : this.currentXp -= requiredXp; 93 3 : promotedTemplateName = template.Promotion.Entity; 94 : } 95 4 : this.Promote(promotedTemplateName); 96 : } 97 : 98 27 : Engine.PostMessage(this.entity, MT_ExperienceChanged, {}); 99 : }; 100 : 101 1 : Promotion.prototype.ComputeTrickleRate = function() 102 : { 103 7 : this.trickleRate = ApplyValueModificationsToEntity("Promotion/TrickleRate", +(this.template.TrickleRate || 0), this.entity); 104 7 : this.CheckTrickleTimer(); 105 : }; 106 : 107 1 : Promotion.prototype.CheckTrickleTimer = function() 108 : { 109 7 : if (!this.trickleRate) 110 : { 111 5 : if (this.trickleTimer) 112 : { 113 0 : let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 114 0 : cmpTimer.CancelTimer(this.trickleTimer); 115 0 : delete this.trickleTimer; 116 : } 117 5 : return; 118 : } 119 : 120 2 : if (this.trickleTimer) 121 0 : return; 122 : 123 2 : let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 124 2 : this.trickleTimer = cmpTimer.SetInterval(this.entity, IID_Promotion, "TrickleTick", 1000, 1000, null); 125 : }; 126 : 127 1 : Promotion.prototype.TrickleTick = function() 128 : { 129 19 : this.IncreaseXp(this.trickleRate); 130 : }; 131 : 132 1 : Promotion.prototype.OnValueModification = function(msg) 133 : { 134 1 : if (msg.component != "Promotion") 135 0 : return; 136 : 137 1 : this.ComputeTrickleRate(); 138 1 : this.IncreaseXp(0); 139 : }; 140 : 141 1 : Engine.RegisterComponentType(IID_Promotion, "Promotion", Promotion);