Index: binaries/data/mods/public/simulation/helpers/Transform.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Transform.js +++ binaries/data/mods/public/simulation/helpers/Transform.js @@ -80,6 +80,12 @@ } if (cmpUnitAI.IsGarrisoned()) cmpNewUnitAI.SetGarrisoned(); + if (cmpUnitAI.orderQueue.length) + { + // Reset old UnitAI to a default state. + cmpUnitAI.orderQueue = [cmpUnitAI.orderQueue[0]]; + cmpUnitAI.FinishOrder(); + } } let cmpPromotion = Engine.QueryInterface(oldEnt, IID_Promotion); Index: binaries/data/mods/public/simulation/helpers/tests/test_Transform.js =================================================================== --- /dev/null +++ binaries/data/mods/public/simulation/helpers/tests/test_Transform.js @@ -0,0 +1,72 @@ +Engine.LoadHelperScript("FSM.js"); +Engine.LoadHelperScript("Player.js"); +Engine.LoadHelperScript("Transform.js"); +Engine.LoadComponentScript("interfaces/Attack.js"); +Engine.LoadComponentScript("interfaces/BuildingAI.js"); +Engine.LoadComponentScript("interfaces/Capturable.js"); +Engine.LoadComponentScript("interfaces/Formation.js"); +Engine.LoadComponentScript("interfaces/Foundation.js"); +Engine.LoadComponentScript("interfaces/Guard.js"); +Engine.LoadComponentScript("interfaces/Heal.js"); +Engine.LoadComponentScript("interfaces/Health.js"); +Engine.LoadComponentScript("interfaces/Pack.js"); +Engine.LoadComponentScript("interfaces/Promotion.js"); +Engine.LoadComponentScript("interfaces/Repairable.js"); +Engine.LoadComponentScript("interfaces/ResourceGatherer.js"); +Engine.LoadComponentScript("interfaces/StatusEffectsReceiver.js"); +Engine.LoadComponentScript("interfaces/Timer.js"); +Engine.LoadComponentScript("interfaces/UnitAI.js"); +Engine.LoadComponentScript("UnitAI.js"); + +function test_unitai_transform() +{ + const ent = 4; + const target = 5; + + AddMock(SYSTEM_ENTITY, IID_Timer, { + "SetInterval": () => {}, + "SetTimeout": () => {} + }); + + let cmpUnitAI = ConstructComponent(ent, "UnitAI", { + "FormationController": false, + "DefaultStance": "aggressive", + }); + + cmpUnitAI.OnCreate(); + + // Setup + cmpUnitAI.CanAttack = () => true; + cmpUnitAI.TargetIsAlive = () => true; + cmpUnitAI.GetBestAttackAgainst = () => "ranged"; + cmpUnitAI.CheckTargetAttackRange = () => true; + AddMock(ent, IID_Attack, { + GetTimers: () => ({ "prepare": 1, "repeat": 10 }), + }); + // Order + cmpUnitAI.Attack(target); + TS_ASSERT_EQUALS(cmpUnitAI.GetCurrentState(), "INDIVIDUAL.COMBAT.ATTACKING"); + + // Transform + let newEnt = 6; + let mock = AddMock(newEnt, IID_UnitAI, { + SwitchToStance: () => {}, + AddOrders: () => {}, + }); + let spy = new Spy(mock, "AddOrders"); + Engine.AddEntity = () => newEnt; + Engine.RegisterGlobal("MT_EntityRenamed", "test"); + ChangeEntityTemplate(ent, {}); + + // Validate + TS_ASSERT(spy._called); + + TS_ASSERT_UNEVAL_EQUALS(spy._callargs[0][0][0], { + "type": "Attack", "data":{ + "target": target, "force": true, "allowCapture": true, attackType: "ranged" + } + }); + TS_ASSERT_EQUALS(cmpUnitAI.fsmNextState, "IDLE"); +} + +test_unitai_transform();