diff --git a/Doc/DML Documentation.pdf b/Doc/DML Documentation.pdf index 21e47c6..b6a5df3 100644 Binary files a/Doc/DML Documentation.pdf and b/Doc/DML Documentation.pdf differ diff --git a/Doc/DML Quick Reference.pdf b/Doc/DML Quick Reference.pdf index f56d2a0..b8ea9b4 100644 Binary files a/Doc/DML Quick Reference.pdf and b/Doc/DML Quick Reference.pdf differ diff --git a/modules/RNDFlags.lua b/modules/RNDFlags.lua index bc8c9a4..29b0a40 100644 --- a/modules/RNDFlags.lua +++ b/modules/RNDFlags.lua @@ -253,6 +253,7 @@ end -- -- Load / Save data -- + function rndFlags.saveData() local theData = {} local allRND = {} @@ -354,6 +355,7 @@ function rndFlags.start() rndFlags.addRNDZone(aZone) -- remember it so we can smoke it end + -- persistence if persistence then -- sign up for persistence callbacks = {} diff --git a/modules/cfxPlayer.lua b/modules/cfxPlayer.lua index ca2029a..725b63e 100644 --- a/modules/cfxPlayer.lua +++ b/modules/cfxPlayer.lua @@ -627,11 +627,11 @@ function cfxPlayer.stop() end function cfxPlayer.init() - trigger.action.outText("cf/x player v".. cfxPlayer.version .. ": loaded", 10) + --trigger.action.outText("cf/x player v".. cfxPlayer.version .. ": loaded", 10) -- when verbose, we also add a monitor to display player event if cfxPlayer.verbose then cfxPlayer.addMonitor(cfxPlayer.defaultMonitor, {}) - trigger.action.outText("cf/x player isd verbose", 10) + trigger.action.outText("cf/x player is verbose", 10) end cfxPlayer.start() diff --git a/modules/cfxZones.lua b/modules/cfxZones.lua index e38efbd..534ecd5 100644 --- a/modules/cfxZones.lua +++ b/modules/cfxZones.lua @@ -1311,7 +1311,7 @@ function cfxZones.setFlagValue(theFlag, theValue, theZone) -- some QoL: detect "" if dcsCommon.containsString(theFlag, "") then - trigger.action.outText("+++Zone: warning - setFlag has '' flag name in zone <" .. zoneName .. ">", 30) + trigger.action.outText("+++Zone: warning - setFlag has '' flag name in zone <" .. zoneName .. ">", 30) -- if error, intended break end -- now do wildcard processing. we have alphanumeric diff --git a/modules/cloneZone.lua b/modules/cloneZone.lua index 9ba1af8..ffe218a 100644 --- a/modules/cloneZone.lua +++ b/modules/cloneZone.lua @@ -1,5 +1,5 @@ cloneZones = {} -cloneZones.version = "1.5.0" +cloneZones.version = "1.5.2" cloneZones.verbose = false cloneZones.requiredLibs = { "dcsCommon", -- always @@ -57,6 +57,9 @@ cloneZones.allCObjects = {} -- all clones objects 1.4.9 - onRoad option - rndHeading option 1.5.0 - persistence + 1.5.1 - fixed static data cloning bug (load & save) + 1.5.2 - fixed bug in trackWith: referencing wrong cloner + --]]-- @@ -281,6 +284,7 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner" -- interface to groupTracker if cfxZones.hasProperty(theZone, "trackWith:") then theZone.trackWith = cfxZones.getStringFromZoneProperty(theZone, "trackWith:", "") + --trigger.action.outText("trackwith: " .. theZone.trackWith, 30) end -- randomized locations on spawn @@ -815,10 +819,10 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone) trigger.action.outText("clnZ: MISMATCH " .. rawData.name .. " target ID " .. rawData.CZTargetID .. " does not match " .. newGroupID, 30) end - cloneZones.invokeCallbacks(theZone, "did spawn group", theGroup) + cloneZones.invokeCallbacks(spawnZone, "did spawn group", theGroup) -- interface to groupTracker - if theZone.trackWith then - cloneZones.handoffTracking(theGroup, theZone) + if spawnZone.trackWith then + cloneZones.handoffTracking(theGroup, spawnZone) end end @@ -901,7 +905,7 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone) rawData.cty = ctry -- save for persistence local theData = dcsCommon.clone(rawData) - cfxZones.allCObjects[rawData.name] = theData + cloneZones.allCObjects[rawData.name] = theData local theStatic = coalition.addStaticObject(ctry, rawData) local newStaticID = tonumber(theStatic:getID()) @@ -1302,7 +1306,7 @@ function cloneZones.loadData() if newStatic.linkUnit and unitPersistence.verbose then trigger.action.outText("+++unitPersistence: linked static <" .. oName .. "> to unit <" .. newStatic.linkUnit .. ">", 30) end - local cty = staticData.cty + local cty = newStatic.cty -- local cat = staticData.cat -- spawn new one, replacing same.named old, dead if required gStatic = coalition.addStaticObject(cty, newStatic) diff --git a/modules/delayFlags.lua b/modules/delayFlags.lua index 8bc5224..fc1cebb 100644 --- a/modules/delayFlags.lua +++ b/modules/delayFlags.lua @@ -1,5 +1,5 @@ delayFlag = {} -delayFlag.version = "1.2.2" +delayFlag.version = "1.3.0" delayFlag.verbose = false delayFlag.requiredLibs = { "dcsCommon", -- always @@ -34,6 +34,10 @@ delayFlag.flags = {} 1.2.2 - delayMethod defaults to inc - zone-local verbosity - code clean-up + 1.2.3 - pauseDelay + - continueDelay + - delayLeft + 1.3.0 - persistence --]]-- @@ -111,10 +115,28 @@ function delayFlag.createTimerWithZone(theZone) theZone.lastTriggerStopValue = cfxZones.getFlagValue(theZone.triggerStopDelay, theZone) end + -- pause and continue + if cfxZones.hasProperty(theZone, "pauseDelay?") then + theZone.triggerPauseDelay = cfxZones.getStringFromZoneProperty(theZone, "pauseDelay?", "none") + theZone.lastTriggerPauseValue = cfxZones.getFlagValue(theZone.triggerPauseDelay, theZone) + end + + if cfxZones.hasProperty(theZone, "continueDelay?") then + theZone.triggerContinueDelay = cfxZones.getStringFromZoneProperty(theZone, "continueDelay?", "none") + theZone.lastTriggerContinueValue = cfxZones.getFlagValue(theZone.triggerContinueDelay, theZone) + end + + -- timeInfo + theZone.delayTimeLeft = cfxZones.getStringFromZoneProperty(theZone, "delayLeft", "*cfxIgnored") + -- init theZone.delayRunning = false - theZone.timeLimit = -1 + theZone.delayPaused = false + theZone.timeLimit = -1 -- current trigger time as calculated relative to getTime() + theZone.timeLeft = -1 -- in seconds, always kept up to date + -- but not really used + cfxZones.setFlagValue(theZone.delayTimeLeft, -1, theZone) end @@ -145,6 +167,19 @@ function delayFlag.startDelay(theZone) end theZone.timeLimit = timer.getTime() + delay + cfxZones.setFlagValue(theZone.delayTimeLeft, delay, theZone) +end + +function delayFlag.pauseDelay(theZone) + -- we stop delay now, and calculate remaining time for + -- continue + theZone.remainingTime = theZone.timeLimit - timer.getTime() + theZone.delayPaused = true +end + +function delayFlag.continueDelay(theZone) + theZone.timeLimit = timer.getTime() + theZone.remainingTime + theZone.delayPaused = false end function delayFlag.update() @@ -154,12 +189,16 @@ function delayFlag.update() local now = timer.getTime() for idx, aZone in pairs(delayFlag.flags) do + -- calculate remaining time on the timer + local remaining = aZone.timeLimit - now + if remaining < 0 then remaining = -1 end + -- see if we need to stop if cfxZones.testZoneFlag(aZone, aZone.triggerStopDelay, aZone.delayTriggerMethod, "lastTriggerStopValue") then aZone.delayRunning = false -- simply stop. - if delayFlag.verbose or aZone.verbose then - trigger.action.outText("+++dlyF: stopped delay " .. aZone.name, 30) - end + if delayFlag.verbose or aZone.verbose then + trigger.action.outText("+++dlyF: stopped delay " .. aZone.name, 30) + end end @@ -168,30 +207,105 @@ function delayFlag.update() if aZone.delayRunning then trigger.action.outText("+++dlyF: re-starting timer " .. aZone.name, 30) else - trigger.action.outText("+++dlyF: init timer for " .. aZone.name, 30) + trigger.action.outText("+++dlyF: start timer for " .. aZone.name, 30) end end delayFlag.startDelay(aZone) -- we restart even if running + remaining = aZone.timeLimit - now -- recalc remaining end - - if aZone.delayRunning then - -- check expiry - if now > aZone.timeLimit then - -- end timer - aZone.delayRunning = false - -- poll flag + if not aZone.delayPaused then + + if aZone.delayRunning and cfxZones.testZoneFlag(aZone, aZone.triggerPauseDelay, aZone.delayTriggerMethod, "lastTriggerPauseValue") then if delayFlag.verbose or aZone.verbose then - trigger.action.outText("+++dlyF: banging on " .. aZone.delayDoneFlag, 30) + trigger.action.outText("+++dlyF: pausing timer <" .. aZone.name .. "> with <" .. remaining .. "> remaining", 30) + end + delayFlag.pauseDelay(aZone) + end + + if aZone.delayRunning then + -- check expiry + if remaining < 0 then --now > aZone.timeLimit then + -- end timer + aZone.delayRunning = false + -- poll flag + if delayFlag.verbose or aZone.verbose then + trigger.action.outText("+++dlyF: banging on " .. aZone.delayDoneFlag, 30) + end + cfxZones.pollFlag(aZone.delayDoneFlag, aZone.delayMethod, aZone) end - cfxZones.pollFlag(aZone.delayDoneFlag, aZone.delayMethod, aZone) - + end + + cfxZones.setFlagValue(aZone.delayTimeLeft, remaining, aZone) + else + -- we are paused. Check for 'continue' + if aZone.delayRunning and cfxZones.testZoneFlag(aZone, aZone.triggerContinueDelay, aZone.delayTriggerMethod, "lastTriggerContinueValue") then + if delayFlag.verbose or aZone.verbose then + trigger.action.outText("+++dlyF: continuing timer <" .. aZone.name .. "> with <" .. aZone.remainingTime .. "> seconds remaining", 30) + end + delayFlag.continueDelay(aZone) end end end end + +-- +-- LOAD / SAVE +-- +function delayFlag.saveData() + local theData = {} + local allTimers = {} + local now = timer.getTime() + for idx, theDelay in pairs(delayFlag.flags) do + local theName = theDelay.name + local timerData = {} + timerData.delayRunning = theDelay.delayRunning + timerData.delayPaused = theDelay.delayPaused + timerData.delayRemaining = theDelay.timeLimit - now + if timerData.delayRemaining < 0 then timerData.delayRemaining = -1 end + allTimers[theName] = timerData + end + theData.allTimers = allTimers + + return theData +end + +function delayFlag.loadData() + if not persistence then return end + local theData = persistence.getSavedDataForModule("delayFlag") + if not theData then + if delayFlag.verbose then + trigger.action.outText("+++dlyF Persistence: no save date received, skipping.", 30) + end + return + end + + local allTimers = theData.allTimers + if not allTimers then + if delayFlag.verbose then + trigger.action.outText("+++dlyF Persistence: no timer data, skipping", 30) + end + return + end + + local now = timer.getTime() + for theName, theData in pairs(allTimers) do + local theTimer = delayFlag.getDelayZoneByName(theName) + if theTimer then + theTimer.delayRunning = theData.delayRunning + theTimer.delayPaused = theData.delayPaused + theTimer.timeLimit = now + theData.delayRemaining + theTimer.timeLeft = theData.delayRemaining + if theTimer.verbose then + trigger.action.outText("+++dlyF loading: timer <" .. theName .. "> has time left <" .. theData.delayRemaining .. ">s, is running <" .. dcsCommon.bool2Text(theData.delayRunning) .. ">, is paused <" .. dcsCommon.bool2Text(theData.delayPaused) .. ">.", 30) + end + else + trigger.action.outText("+++dlyF: persistence: cannot synch delay <" .. theName .. ">, skipping", 40) + end + end +end -- -- START -- @@ -234,8 +348,15 @@ function delayFlag.start() delayFlag.addDelayZone(aZone) -- add to list end - -- kick onStart - --delayFlag.onStart() + -- load any saved data + if persistence then + -- sign up for persistence + callbacks = {} + callbacks.persistData = delayFlag.saveData + persistence.registerModule("delayFlag", callbacks) + -- now load my data + delayFlag.loadData() + end -- start update delayFlag.update() diff --git a/modules/groupTrackers.lua b/modules/groupTrackers.lua index da7fe33..d2874b5 100644 --- a/modules/groupTrackers.lua +++ b/modules/groupTrackers.lua @@ -1,5 +1,5 @@ groupTracker = {} -groupTracker.version = "1.1.4" +groupTracker.version = "1.2.0" groupTracker.verbose = false groupTracker.ups = 1 groupTracker.requiredLibs = { @@ -25,6 +25,9 @@ groupTracker.trackers = {} - triggerMethod - method - isDead optimization + 1.2.0 - double detection + - numUnits output + - persistence --]]-- @@ -68,12 +71,25 @@ function groupTracker.addGroupToTracker(theGroup, theTracker) end -- we have the tracker, add the group - if not theTracker.trackedGroups then theTracker.trackedGroups = {} end - table.insert(theTracker.trackedGroups, theGroup) + if not theTracker.trackedGroups then theTracker.trackedGroups = {} end - -- now bang/invoke addGroup! - if theTracker.tAddGroup then - cfxZones.pollFlag(theTracker.tAddGroup, "inc", theTracker) + local exists = false + local theName = theGroup:getName() + + for idx, aGroup in pairs(theTracker.trackedGroups) do + if Group.isExist(aGroup) then + gName = aGroup:getName() + if gName == theName then exists = true end + end + end + + if not exists then + table.insert(theTracker.trackedGroups, theGroup) + + -- now bang/invoke addGroup! + if theTracker.tAddGroup then + cfxZones.pollFlag(theTracker.tAddGroup, "inc", theTracker) + end end -- now set numGroups @@ -81,6 +97,18 @@ function groupTracker.addGroupToTracker(theGroup, theTracker) cfxZones.setFlagValue(theTracker.tNumGroups, #theTracker.trackedGroups, theTracker) end + -- count all units + local totalUnits = 0 + for idx, aGroup in pairs(theTracker.trackedGroups) do + if Group.isExist(aGroup) then + totalUnits = totalUnits + aGroup:getSize() + end + end + + -- update unit count + if theTracker.tNumUnits then + cfxZones.setFlagValue(theTracker.tNumUnits, totalUnits, theTracker) + end -- invoke callbacks end @@ -114,12 +142,17 @@ function groupTracker.removeGroupNamedFromTrackerNamed(gName, trackerName) local filteredGroups = {} local foundOne = false + local totalUnits = 0 + if not theTracker.trackedGroups then theTracker.trackedGroups = {} end for idx, aGroup in pairs(theTracker.trackedGroups) do if aGroup:getName() == gName then -- skip and remember foundOne = true else table.insert(filteredGroups, aGroup) + if Group.isExist(aGroup) then + totalUnits = totalUnits + aGroup:getSize() + end end end if (not foundOne) and (theTracker.verbose or groupTracker.verbose) then @@ -129,6 +162,10 @@ function groupTracker.removeGroupNamedFromTrackerNamed(gName, trackerName) -- remember the new, cleanded set theTracker.trackedGroups = filteredGroups + -- update number of tracked units. do it in any case + if theTracker.tNumUnits then + cfxZones.setFlagValue(theTracker.tNumUnits, totalUnits, theTracker) + end if foundOne then if theTracker.verbose or groupTracker.verbose then @@ -171,7 +208,11 @@ function groupTracker.createTrackerWithZone(theZone) theZone.tNumGroups = cfxZones.getStringFromZoneProperty(theZone, "numGroups!", "*") -- we may need to zero this flag end - + + if cfxZones.hasProperty(theZone, "numUnits") then + theZone.tNumUnits = cfxZones.getStringFromZoneProperty(theZone, "numUnits", "*") + end + if cfxZones.hasProperty(theZone, "addGroup") then theZone.tAddGroup = cfxZones.getStringFromZoneProperty(theZone, "addGroup", "*") -- we may need to zero this flag @@ -229,20 +270,14 @@ end function groupTracker.checkGroups(theZone) local filteredGroups = {} + local totalUnits = 0 + if not theZone.trackedGroups then theZone.trackedGroups = {} end for idx, theGroup in pairs(theZone.trackedGroups) do -- see if this group can be transferred local isDead = false ---[[ if theGroup.isExist and theGroup:isExist() then - local allUnits = theGroup:getUnits() - isDead = true - for idy, aUnit in pairs(allUnits) do - if aUnit:getLife() > 1 then - isDead = false -- at least one living unit - break - end - end ---]]-- + if Group.isExist(theGroup) and theGroup:getSize() > 0 then + totalUnits = totalUnits + theGroup:getSize() else isDead = true -- no longer exists end @@ -271,6 +306,11 @@ function groupTracker.checkGroups(theZone) if theZone.tNumGroups then cfxZones.setFlagValue(theZone.tNumGroups, #filteredGroups, theZone) end + + -- and update unit count if defined + if theZone.tNumUnits then + cfxZones.setFlagValue(theZone.tNumUnits, totalUnits, theZone) + end end function groupTracker.update() @@ -278,6 +318,37 @@ function groupTracker.update() timer.scheduleFunction(groupTracker.update, {}, timer.getTime() + 1/groupTracker.ups) for idx, theZone in pairs(groupTracker.trackers) do + -- first see if any groups need to be silently + -- added by name ("late bind"). Used by Persistence, can be used + -- by anyone to silently (no add event) add groups + if not theZone.trackedGroups then theZone.trackedGroups = {} end + if theZone.silentAdd then + for idx, gName in pairs (theZone.silentAdd) do + local theGroup = Group.getByName(gName) + if theGroup and Group.isExist(theGroup) then + -- make sure that we don't accidentally + -- add the same group twice + local isPresent = false + for idy, aGroup in pairs(theZone.trackedGroups) do + if Group.isExit(aGroup) and aGroup:getName(aGroup) == gName then + isPresent = true + end + end + if not isPresent then + table.insert(theZone.trackedGroups, theGroup) + else + if groupTracker.verbose or theZone.verbose then + trigger.action.outText("+++gTrk: late bind: group <" .. gName .. "> succesful during update", 30) + end + end + else + if groupTracker.verbose or theZone.verbose then + trigger.action.outText("+++gTrk: silent add: Group <" .. gName .. "> not found or dead", 30) + end + end + end + theZone.silentAdd = nil + end if theZone.destroyFlag and cfxZones.testZoneFlag(theZone, theZone.destroyFlag, theZone.trackerTriggerMethod, "lastDestroyValue") then groupTracker.destroyAllInZone(theZone) @@ -297,9 +368,61 @@ function groupTracker.update() end end +-- +-- Load and Save +-- +function groupTracker.saveData() + local theData = {} + local allTrackerData = {} + for idx, aTracker in pairs(groupTracker.trackers) do + local theName = aTracker.name + local trackerData = {} + local trackedGroups = {} + for idx, aGroup in pairs (aTracker.trackedGroups) do + if Group.isExist(aGroup) and aGroup:getSize() > 0 then + local gName = aGroup:getName() + table.insert(trackedGroups, gName) + end + end + trackerData.trackedGroups = trackedGroups + -- we may also want to save flag values butz it + -- would be better to have this done externally, globally + allTrackerData[theName] = trackerData + end + + theData.trackerData = allTrackerData + return theData +end + +function groupTracker.loadData() + if not persistence then return end + local theData = persistence.getSavedDataForModule("groupTracker") + if not theData then + if groupTracker.verbose then + trigger.action.outText("+++gTrk: no save date received, skipping.", 30) + end + return + end + + local allTrackerData = theData.trackerData + for tName, tData in pairs (allTrackerData) do + local theTracker = groupTracker.getTrackerByName(tName) + if theTracker then + -- pass to silentAdd, will be added during next update + -- we do this for a late bind, one second down the road + -- to give all modules time to load and spawn the + -- groups + theTracker.silentAdd = tData.trackedGroups + else + trigger.action.outText("+++gTrk - persistence: unable to synch tracker <" .. tName .. ">: not found", 30) + end + end +end + -- -- Config & Start -- + function groupTracker.trackGroupsInZone(theZone) local trackerName = cfxZones.getStringFromZoneProperty(theZone, "addToTracker:", "") @@ -378,9 +501,22 @@ function groupTracker.start() groupTracker.trackGroupsInZone(aZone) -- process attributes end - -- start update - groupTracker.update() - + -- update all cloners and spawned clones from file + if persistence then + -- sign up for persistence + callbacks = {} + callbacks.persistData = groupTracker.saveData + persistence.registerModule("groupTracker", callbacks) + -- now load my data + groupTracker.loadData() -- add to late link + -- update in one second so all can load + -- before we link late + timer.scheduleFunction(groupTracker.update, {}, timer.getTime() + 1/groupTracker.ups) + else + -- start update immediately + groupTracker.update() + end + trigger.action.outText("cfx Group Tracker v" .. groupTracker.version .. " started.", 30) return true end diff --git a/modules/messenger.lua b/modules/messenger.lua index c8e8b62..c910821 100644 --- a/modules/messenger.lua +++ b/modules/messenger.lua @@ -1,5 +1,5 @@ messenger = {} -messenger.version = "1.3.2" +messenger.version = "1.3.3" messenger.verbose = false messenger.requiredLibs = { "dcsCommon", -- always @@ -25,6 +25,8 @@ messenger.messengers = {} 1.3.2 - message interprets as time in HH:MM:SS of current time - can interpret , , - zone-local verbosity + 1.3.3 - mute/messageMute option to start messenger in mute + --]]-- function messenger.addMessenger(theZone) @@ -90,9 +92,10 @@ function messenger.createMessengerWithZone(theZone) theZone.clearScreen = cfxZones.getBoolFromZoneProperty(theZone, "clearScreen", false) - -- alternate version: messages: list of messages, need string parser first - theZone.duration = cfxZones.getNumberFromZoneProperty(theZone, "duration", 30) + if cfxZones.hasProperty(theZone, "messageDuration") then + theZone.duration = cfxZones.getNumberFromZoneProperty(theZone, "messageDuration", 30) + end -- msgTriggerMethod theZone.msgTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change") @@ -129,7 +132,11 @@ function messenger.createMessengerWithZone(theZone) theZone.lastMessageTriggerValue = cfxZones.getFlagValue(theZone.triggerMessagerFlag, theZone)-- save last value -- end - theZone.messageOff = false + theZone.messageOff = cfxZones.getBoolFromZoneProperty(theZone, "mute", false) --false + if cfxZones.hasProperty(theZone, "messageOff?") then + theZone.messageOff = cfxZones.getBoolFromZoneProperty(theZone, "messageMute", false) + end + if cfxZones.hasProperty(theZone, "messageOff?") then theZone.messageOffFlag = cfxZones.getStringFromZoneProperty(theZone, "messageOff?", "*none") theZone.lastMessageOff = cfxZones.getFlagValue(theZone.messageOffFlag, theZone) @@ -219,7 +226,7 @@ function messenger.update() for idx, aZone in pairs(messenger.messengers) do -- make sure to re-start before reading time limit -- new trigger code - if cfxZones.testZoneFlag(aZone, aZone.triggerMessagerFlag, aZone.msgTriggerMethod, "lastMessageTriggerValue") then + if cfxZones.testZoneFlag(aZone, aZone.triggerMessagerFlag, aZone.msgTriggerMethod, "lastMessageTriggerValue") then if messenger.verbose or aZone.verbose then trigger.action.outText("+++msgr: triggered on in? for <".. aZone.name ..">", 30) end diff --git a/modules/pulseFlags.lua b/modules/pulseFlags.lua index 9774788..10b5bef 100644 --- a/modules/pulseFlags.lua +++ b/modules/pulseFlags.lua @@ -1,5 +1,5 @@ pulseFlags = {} -pulseFlags.version = "1.2.3" +pulseFlags.version = "1.3.0" pulseFlags.verbose = false pulseFlags.requiredLibs = { "dcsCommon", -- always @@ -35,6 +35,7 @@ pulseFlags.requiredLibs = { - 1.2.2 outputMethod synonym - 1.2.3 deprecated paused/pulsePaused returned onStart, defaulting to true + - 1.3.0 persistence --]]-- @@ -44,6 +45,12 @@ function pulseFlags.addPulse(aZone) table.insert(pulseFlags.pulses, aZone) end +function pulseFlags.getPulseByName(theName) + for idx, theZone in pairs (pulseFlags.pulses) do + if theZone.name == theName then return theZone end + end + return nil +end -- -- create a pulse -- @@ -207,7 +214,9 @@ function pulseFlags.doPulse(args) -- schedule in delay time - theZone.timerID = timer.scheduleFunction(pulseFlags.doPulse, args, timer.getTime() + delay) + theZone.scheduledTime = timer.getTime() + delay + theZone.timerID = timer.scheduleFunction(pulseFlags.doPulse, args, theZone.scheduledTime) + if pulseFlags.verbose or theZone.verbose then trigger.action.outText("+++pulF: pulse <" .. theZone.name .. "> rescheduled in " .. delay, 30) end @@ -290,6 +299,71 @@ function pulseFlags.readConfigZone() end end +-- +-- LOAD / SAVE +-- +function pulseFlags.saveData() + local theData = {} + local allPulses = {} + local now = timer.getTime() + for idx, thePulse in pairs(pulseFlags.pulses) do + local theName = thePulse.name + local pulseData = {} + pulseData.pulsePaused = thePulse.pulsePaused + pulseData.pulsesLeft = thePulse.pulsesLeft + pulseData.pulsing = thePulse.pulsing + pulseData.scheduledTime = thePulse.scheduledTime - now + pulseData.hasPulsed = thePulse.hasPulsed + + allPulses[theName] = pulseData + end + theData.allPulses = allPulses + return theData +end + +function pulseFlags.loadData() + if not persistence then return end + local theData = persistence.getSavedDataForModule("pulseFlags") + if not theData then + if pulseFlags.verbose then + trigger.action.outText("+++pulF Persistence: no save date received, skipping.", 30) + end + return + end + + local allPulses = theData.allPulses + if not allPulses then + if pulseFlags.verbose then + trigger.action.outText("+++pulF Persistence: no timer data, skipping", 30) + end + return + end + + local now = timer.getTime() + for theName, theData in pairs(allPulses) do + local thePulse = pulseFlags.getPulseByName(theName) + if thePulse then + thePulse.pulsePaused = theData.pulsePaused + thePulse.pulsesLeft = theData.pulsesLeft + thePulse.scheduledTime = now + theData.scheduledTime + thePulse.hasPulsed = theData.hasPulsed + if thePulse.scheduledTime < now then thePulse.scheduledTime = now + 0.1 end + + thePulse.pulsing = theData.pulsing + if thePulse.pulsing then + local args = {thePulse} + thePulse.timerID = timer.scheduleFunction(pulseFlags.doPulse, args, thePulse.scheduledTime) + end + else + trigger.action.outText("+++pulF: persistence: cannot synch pulse <" .. theName .. ">, skipping", 40) + end + end +end + +-- +-- START +-- + function pulseFlags.start() -- lib check if not dcsCommon.libCheck then @@ -325,6 +399,16 @@ function pulseFlags.start() pulseFlags.addPulse(aZone) -- remember it so we can pulse it end + -- load any saved data + if persistence then + -- sign up for persistence + callbacks = {} + callbacks.persistData = pulseFlags.saveData + persistence.registerModule("pulseFlags", callbacks) + -- now load my data + pulseFlags.loadData() + end + -- start update in 1 second --pulseFlags.update() timer.scheduleFunction(pulseFlags.update, {}, timer.getTime() + 1) diff --git a/modules/unitZone.lua b/modules/unitZone.lua index 8685c1f..eccc0b3 100644 --- a/modules/unitZone.lua +++ b/modules/unitZone.lua @@ -14,7 +14,7 @@ unitZone.requiredLibs = { 1.2.0 - uzOn?, uzOff?, triggerMethod 1.2.1 - uzDirect 1.2.2 - uzDirectInv - 1.2.3 - better guards for enterZone!, exitZone!, chsngeZone! + 1.2.3 - better guards for enterZone!, exitZone!, changeZone! - better guards for uzOn? and uzOff? --]]--