Index: binaries/data/mods/public/simulation/components/Timer.js =================================================================== --- binaries/data/mods/public/simulation/components/Timer.js +++ binaries/data/mods/public/simulation/components/Timer.js @@ -20,6 +20,35 @@ }; /** + * Gives the timers belonging to a specific entity. + * + * @param {number} entity - The entity ID of the entity to return the timers for. + * + * @return {Object[]} - An array of the timers which the entity has. + */ +Timer.prototype.GetTimers = function(entity) +{ + let timers = {}; + for (let [id, timer] of this.timers) + if (timer.entity == entity) + timers[id] = timer; + return timers; +}; + +/** + * Transfers a timer from an entity to a new entity, e.g. when promoting. + * + * @param {number} timerID - The timer ID to be transfered. + * @param {number} newEnt - The entity ID of the entity to which the timer ought to be transferred. + */ +Timer.prototype.TransferTimer = function(timerID, newEnt) +{ + for (let [id, timer] of this.timers) + if (id == timerID) + timer.entity = newEnt; +}; + +/** * Returns the duration of the latest turn in milliseconds. */ Timer.prototype.GetLatestTurnLength = function() Index: binaries/data/mods/public/simulation/components/tests/test_Pack.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_Pack.js +++ binaries/data/mods/public/simulation/components/tests/test_Pack.js @@ -39,7 +39,8 @@ AddMock(SYSTEM_ENTITY, IID_Timer, { "CancelTimer": id => { timerActivated = false; return; }, - "SetInterval": (ent, iid, funcname, time, repeattime, data) => { timerActivated = true; return 7; } + "SetInterval": (ent, iid, funcname, time, repeattime, data) => { timerActivated = true; return 7; }, + "GetTimers": () => [] }); Engine.AddEntity = function(template) { Index: binaries/data/mods/public/simulation/components/tests/test_Timer.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_Timer.js +++ binaries/data/mods/public/simulation/components/tests/test_Timer.js @@ -78,3 +78,10 @@ cmpTimer.OnUpdate({ "turnLength": 3.0 }); TS_ASSERT_UNEVAL_EQUALS(fired, [["s",2500]]); + +fired = []; + +let t = cmpTimer.SetTimeout(10, IID_Test, "Callback", 1000, "t"); +cmpTimer.TransferTimer(t, 20); +cmpTimer.OnUpdate({ "turnLength": 1.0 }); +TS_ASSERT_UNEVAL_EQUALS(fired, [["t",0]]); 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 @@ -109,6 +109,7 @@ } } + TransferTimers(oldEnt, newEnt); TransferGarrisonedUnits(oldEnt, newEnt); Engine.PostMessage(oldEnt, MT_EntityRenamed, { "entity": oldEnt, "newentity": newEnt }); @@ -256,6 +257,21 @@ } } +/** + * Transfers timers from oldEnt to newEnt. + * + * @param {number} oldEnt - The entity ID of the entity to transfer the timer from. + * @param {number} newEnt - The entity ID of the entity to transfer the timer to. + */ +function TransferTimers(oldEnt, newEnt) +{ + let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + let timers = cmpTimer.GetTimers(oldEnt); + for (let timer in timers) + if (Engine.QueryInterface(newEnt, timers[timer].iid)) + cmpTimer.TransferTimer(timer, newEnt); +} + Engine.RegisterGlobal("ChangeEntityTemplate", ChangeEntityTemplate); Engine.RegisterGlobal("CanGarrisonedChangeTemplate", CanGarrisonedChangeTemplate); Engine.RegisterGlobal("ObstructionsBlockingTemplateChange", ObstructionsBlockingTemplateChange);