Index: binaries/data/mods/public/simulation/components/Promotion.js =================================================================== --- binaries/data/mods/public/simulation/components/Promotion.js +++ binaries/data/mods/public/simulation/components/Promotion.js @@ -31,65 +31,63 @@ Promotion.prototype.Promote = function(promotedTemplateName) { // If the unit is dead, don't promote it - var cmpCurrentUnitHealth = Engine.QueryInterface(this.entity, IID_Health); + let cmpCurrentUnitHealth = Engine.QueryInterface(this.entity, IID_Health); if (cmpCurrentUnitHealth.GetHitpoints() == 0) return; // Create promoted unit entity - var promotedUnitEntity = Engine.AddEntity(promotedTemplateName); + let promotedUnitEntity = Engine.AddEntity(promotedTemplateName); // Copy parameters from current entity to promoted one - var cmpCurrentUnitPosition = Engine.QueryInterface(this.entity, IID_Position); - var cmpPromotedUnitPosition = Engine.QueryInterface(promotedUnitEntity, IID_Position); + let cmpCurrentUnitPosition = Engine.QueryInterface(this.entity, IID_Position); + let cmpPromotedUnitPosition = Engine.QueryInterface(promotedUnitEntity, IID_Position); if (cmpCurrentUnitPosition.IsInWorld()) { - var pos = cmpCurrentUnitPosition.GetPosition2D(); + let pos = cmpCurrentUnitPosition.GetPosition2D(); cmpPromotedUnitPosition.JumpTo(pos.x, pos.y); } - var rot = cmpCurrentUnitPosition.GetRotation(); + let rot = cmpCurrentUnitPosition.GetRotation(); cmpPromotedUnitPosition.SetYRotation(rot.y); cmpPromotedUnitPosition.SetXZRotation(rot.x, rot.z); - var heightOffset = cmpCurrentUnitPosition.GetHeightOffset(); + let heightOffset = cmpCurrentUnitPosition.GetHeightOffset(); cmpPromotedUnitPosition.SetHeightOffset(heightOffset); - var cmpCurrentUnitOwnership = Engine.QueryInterface(this.entity, IID_Ownership); - var cmpPromotedUnitOwnership = Engine.QueryInterface(promotedUnitEntity, IID_Ownership); + let cmpCurrentUnitOwnership = Engine.QueryInterface(this.entity, IID_Ownership); + let cmpPromotedUnitOwnership = Engine.QueryInterface(promotedUnitEntity, IID_Ownership); cmpPromotedUnitOwnership.SetOwner(cmpCurrentUnitOwnership.GetOwner()); // change promoted unit health to the same percent of hitpoints as unit had before promotion - var cmpPromotedUnitHealth = Engine.QueryInterface(promotedUnitEntity, IID_Health); - var healthFraction = Math.max(0, Math.min(1, cmpCurrentUnitHealth.GetHitpoints() / cmpCurrentUnitHealth.GetMaxHitpoints())); - var promotedUnitHitpoints = cmpPromotedUnitHealth.GetMaxHitpoints() * healthFraction; + let cmpPromotedUnitHealth = Engine.QueryInterface(promotedUnitEntity, IID_Health); + let healthFraction = Math.max(0, Math.min(1, cmpCurrentUnitHealth.GetHitpoints() / cmpCurrentUnitHealth.GetMaxHitpoints())); + let promotedUnitHitpoints = cmpPromotedUnitHealth.GetMaxHitpoints() * healthFraction; cmpPromotedUnitHealth.SetHitpoints(promotedUnitHitpoints); - var cmpPromotedUnitPromotion = Engine.QueryInterface(promotedUnitEntity, IID_Promotion); + let cmpPromotedUnitPromotion = Engine.QueryInterface(promotedUnitEntity, IID_Promotion); if (cmpPromotedUnitPromotion) cmpPromotedUnitPromotion.IncreaseXp(this.currentXp); - var cmpCurrentUnitResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); - var cmpPromotedUnitResourceGatherer = Engine.QueryInterface(promotedUnitEntity, IID_ResourceGatherer); + let cmpCurrentUnitResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); + let cmpPromotedUnitResourceGatherer = Engine.QueryInterface(promotedUnitEntity, IID_ResourceGatherer); if (cmpCurrentUnitResourceGatherer && cmpPromotedUnitResourceGatherer) { - var carriedResorces = cmpCurrentUnitResourceGatherer.GetCarryingStatus(); + let carriedResorces = cmpCurrentUnitResourceGatherer.GetCarryingStatus(); cmpPromotedUnitResourceGatherer.GiveResources(carriedResorces); } - var cmpCurrentUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); - var cmpPromotedUnitAI = Engine.QueryInterface(promotedUnitEntity, IID_UnitAI); - var heldPos = cmpCurrentUnitAI.GetHeldPosition(); + let cmpCurrentUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); + let cmpPromotedUnitAI = Engine.QueryInterface(promotedUnitEntity, IID_UnitAI); + let heldPos = cmpCurrentUnitAI.GetHeldPosition(); if (heldPos) cmpPromotedUnitAI.SetHeldPosition(heldPos.x, heldPos.z); if (cmpCurrentUnitAI.GetStanceName()) cmpPromotedUnitAI.SwitchToStance(cmpCurrentUnitAI.GetStanceName()); - var orders = cmpCurrentUnitAI.GetOrders(); - if (cmpCurrentUnitPosition.IsInWorld()) // do not cheer if not visibly garrisoned - cmpPromotedUnitAI.Cheer(); + let orders = cmpCurrentUnitAI.GetOrders(); if (cmpCurrentUnitAI.IsGarrisoned()) cmpPromotedUnitAI.SetGarrisoned(); cmpPromotedUnitAI.AddOrders(orders); - var workOrders = cmpCurrentUnitAI.GetWorkOrders(); + let workOrders = cmpCurrentUnitAI.GetWorkOrders(); cmpPromotedUnitAI.SetWorkOrders(workOrders); if (cmpCurrentUnitAI.IsGuardOf()) Index: binaries/data/mods/public/simulation/components/UnitAI.js =================================================================== --- binaries/data/mods/public/simulation/components/UnitAI.js +++ binaries/data/mods/public/simulation/components/UnitAI.js @@ -1959,6 +1959,8 @@ // Return to our original position if (this.GetStance().respondHoldGround) this.WalkToHeldPosition(); + + this.Cheer(); }, // TODO: respond to target deaths immediately, rather than waiting @@ -2837,18 +2839,13 @@ "CHEERING": { "enter": function() { - // Unit is invulnerable while cheering - var cmpDamageReceiver = Engine.QueryInterface(this.entity, IID_DamageReceiver); - cmpDamageReceiver.SetInvulnerability(true); this.SelectAnimation("promotion"); - this.StartTimer(2800, 2800); + this.StartTimer(2800); return false; }, "leave": function() { this.StopTimer(); - var cmpDamageReceiver = Engine.QueryInterface(this.entity, IID_DamageReceiver); - cmpDamageReceiver.SetInvulnerability(false); }, "Timer": function(msg) { @@ -3234,8 +3231,8 @@ if (msg.to != INVALID_PLAYER && msg.from != INVALID_PLAYER) { // Switch to a virgin state to let states execute their leave handlers. - // except if garrisoned or cheering or (un)packing, in which case we only clear the order queue - if (this.isGarrisoned || this.IsPacking() || this.orderQueue[0] && this.orderQueue[0].type == "Cheering") + // except if garrisoned or or (un)packing, in which case we only clear the order queue + if (this.isGarrisoned || this.IsPacking() || this.orderQueue[0]) { this.orderQueue.length = Math.min(this.orderQueue.length, 1); Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); @@ -3505,14 +3502,8 @@ UnitAI.prototype.PushOrderFront = function(type, data) { var order = { "type": type, "data": data }; - // If current order is cheering then add new order after it - // same thing if current order if packing/unpacking - if (this.order && this.order.type == "Cheering") - { - var cheeringOrder = this.orderQueue.shift(); - this.orderQueue.unshift(cheeringOrder, order); - } - else if (this.order && this.IsPacking()) + // If current order is packing/unpacking then add new order after it + if (this.order && this.IsPacking()) { var packingOrder = this.orderQueue.shift(); this.orderQueue.unshift(packingOrder, order); @@ -3580,16 +3571,9 @@ let garrisonHolder = this.IsGarrisoned() && type != "Ungarrison" ? this.GetGarrisonHolder() : null; // Special cases of orders that shouldn't be replaced: - // 1. Cheering - we're invulnerable, add order after we finish - // 2. Packing/unpacking - we're immobile, add order after we finish (unless it's cancel) + // 1. Packing/unpacking - we're immobile, add order after we finish (unless it's cancel) // TODO: maybe a better way of doing this would be to use priority levels - if (this.order && this.order.type == "Cheering") - { - var order = { "type": type, "data": data }; - var cheeringOrder = this.orderQueue.shift(); - this.orderQueue = [cheeringOrder, order]; - } - else if (this.IsPacking() && type != "CancelPack" && type != "CancelUnpack") + if (this.IsPacking() && type != "CancelPack" && type != "CancelUnpack") { var order = { "type": type, "data": data }; var packingOrder = this.orderQueue.shift(); @@ -3683,13 +3667,7 @@ } // Clear the order queue considering special orders not to avoid - if (this.order && this.order.type == "Cheering") - { - var cheeringOrder = this.orderQueue.shift(); - this.orderQueue = [cheeringOrder]; - } - else - this.orderQueue = []; + this.orderQueue = []; this.AddOrders(this.workOrders); Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); @@ -5214,11 +5192,11 @@ }; /** - * Adds cheer order to the queue. Forced so it won't be interrupted by attacks. + * Adds cheer order to the queue. Do not force so it can be interrupted by attacks. */ UnitAI.prototype.Cheer = function() { - this.AddOrder("Cheering", { "force": true }, false); + this.AddOrder("Cheering", { "force": false }, false); }; UnitAI.prototype.Pack = function(queued)