Version 2.3.5

WHpersistence
This commit is contained in:
Christian Franz
2024-10-24 08:37:44 +02:00
parent a70fadc550
commit 0c1eb53a89
13 changed files with 450 additions and 286 deletions

View File

@@ -1,107 +1,144 @@
raiseFlag = {}
raiseFlag.version = "2.0.0"
raiseFlag.verbose = false
raiseFlag.version = "3.0.0"
raiseFlag.requiredLibs = {
"dcsCommon", -- always
"cfxZones", -- Zones, of course
}
raiseFlag.flags = {}
raiseFlag.flags = {} -- my minions
--[[--
Raise A Flag module -- (c) 2022-23 by Christian Franz and cf/x AG
(c) 2022-23 by Christian Franz and cf/x AG
Version History
1.0.0 - initial release
1.0.1 - synonym "raiseFlag!"
1.1.0 - DML update
1.2.0 - Watchflag update
1.2.1 - support for 'inc', 'dec', 'flip'
2.0.0 - dmlZones
- full method support
- full DML upgrade
- method attribute (synonym to 'value')
3.0.0 - switched to polling
- remains# attribute
- support for persistence
- zone-individual verbosity
- code cleanup, removed deprecated attributes
--]]--
function raiseFlag.addRaiseFlag(theZone)
table.insert(raiseFlag.flags, theZone)
raiseFlag.flags[theZone.name] = theZone
end
function raiseFlag.getRaiseFlagByName(aName)
for idx, aZone in pairs(raiseFlag.flags) do
if aName == aZone.name then return aZone end
end
if raiseFlag.verbose then
trigger.action.outText("+++rFlg: no raiseFlag with name <" .. aName ..">", 30)
end
return nil
end
--
-- read attributes
--
function raiseFlag.createRaiseFlagWithZone(theZone)
-- get flag from faiseFlag itself
if theZone:hasProperty("raiseFlag") then
theZone.raiseFlag = theZone:getStringFromZoneProperty("raiseFlag", "<none>") -- the flag to raise
else
theZone.raiseFlag = theZone:getStringFromZoneProperty("raiseFlag!", "<none>") -- the flag to raise
end
-- pre-method DML raiseFlag is now upgraded to method.
-- flagValue now carries the method
if theZone:hasProperty("value") then -- backward compatibility
theZone.flagValue = theZone:getStringFromZoneProperty("value", "inc") -- value to set to. default is command 'inc'
else
theZone.flagValue = theZone:getStringFromZoneProperty("method", "inc")
end
theZone.raiseFlag = theZone:getStringFromZoneProperty("raiseFlag!", "<none>") -- the flag to raise
theZone.flagValue = theZone:getStringFromZoneProperty("method", "inc")
theZone.flagValue = theZone.flagValue:lower()
theZone.minAfterTime, theZone.maxAfterTime = theZone:getPositiveRangeFromZoneProperty("afterTime", -1)
theZone.raiseTriggerMethod = theZone:getStringFromZoneProperty( "triggerMethod", "change")
if theZone:hasProperty("raiseTriggerMethod") then
theZone.raiseTriggerMethod = theZone:getStringFromZoneProperty("raiseTriggerMethod", "change")
end
if theZone:hasProperty("stopFlag?") then
theZone.triggerStopFlag = theZone:getStringFromZoneProperty( "stopFlag?", "none")
theZone.lastTriggerStopValue = theZone:getFlagValue(theZone.triggerStopFlag) -- save last value
end
theZone.scheduleID = nil
if theZone:hasProperty("timeLeft#") then
theZone.timeLeft = theZone:getStringFromZoneProperty("timeLeft#", "none")
end
theZone.raiseStopped = false
-- now simply schedule for invocation
local args = {}
args.theZone = theZone
if theZone.minAfterTime < 1 then
timer.scheduleFunction(raiseFlag.triggered, args, timer.getTime() + 0.5)
theZone.deadLine = -1 -- will always trigger
else
local delay = cfxZones.randomDelayFromPositiveRange(theZone.minAfterTime, theZone.maxAfterTime)
timer.scheduleFunction(raiseFlag.triggered, args, timer.getTime() + delay)
theZone.deadLine = timer.getTime() + delay
end
end
function raiseFlag.triggered(args)
local theZone = args.theZone
if theZone.raiseStopped then return end
-- if we get here, we aren't stopped and do the flag pull
function raiseFlag.triggered(theZone)
if theZone.raiseStopped then return end -- should be filtered
local command = theZone.flagValue
theZone:pollFlag(theZone.raiseFlag, command)
if raiseFlag.verbose or theZone.verbose then
trigger.action.outText("+++rFlg - raising <" .. theZone.raiseFlag .. "> with method '" .. command .. "'" ,30)
trigger.action.outText("+++rFlg - raising <" .. theZone.raiseFlag .. "> with method '" .. command .. "'" .. " for zone <" .. theZone.name .. ">" ,30)
end
end
--
-- update
--
function raiseFlag.update()
-- call me in a second to poll triggers
timer.scheduleFunction(raiseFlag.update, {}, timer.getTime() + 1)
for idx, aZone in pairs(raiseFlag.flags) do
-- make sure to re-start before reading time limit
if aZone:testZoneFlag(aZone.triggerStopFlag, aZone.raiseTriggerMethod, "lastTriggerStopValue") then
theZone.raiseStopped = true -- we are done, no flag!
function raiseFlag.update(firstUpdate)
local now = timer.getTime()
timer.scheduleFunction(raiseFlag.update, false, now + 1) -- we always beat on .5 offset!
local filtered = {}
for zName, theZone in pairs(raiseFlag.flags) do
-- see if this timer has run out
if theZone.deadLine < now then
if theZone.verbose then
trigger.action.outText("+++rFlg: will raise flag <" .. theZone.name .. ">", 30)
end
raiseFlag.triggered(theZone)
if theZone.timeLeft then theZone:setFlagValue(theZone.timeLeft, 0) end
theZone.raiseStopped = true -- will filter
elseif theZone.timeLeft then
local rem = theZone.deadLine - now
theZone:setFlagValue(theZone.timeLeft, rem)
if theZone.verbose then
trigger.action.outText("+++rFlg: time left on <" .. theZone.name .. ">:" .. math.floor(rem) .. " secs", 30)
end
end
if theZone:testZoneFlag(theZone.triggerStopFlag, theZone.raiseTriggerMethod, "lastTriggerStopValue") then
theZone.raiseStopped = true -- filter
end
if not theZone.raiseStopped then
filtered[theZone.name] = theZone
end
end
raiseFlag.flags = filtered
end
--
-- load / save (game data)
--
function raiseFlag.saveData()
local theData = {}
local theFlags = {}
local now = timer.getTime()
for name, theZone in pairs (raiseFlag.flags) do
-- note: we only process existing!
theFlags[name] = theZone.deadLine - now
end
-- save current deadlines
theData.theFlags = theFlags
return theData, raiseFlag.sharedData -- second val currently nil
end
function raiseFlag.loadData()
if not persistence then return end
local shared = nil
local theData = persistence.getSavedDataForModule("raiseFlag")
if (not theData) then
if raiseFlag.verbose then
trigger.action.outText("+++rFlg: no save date received, skipping.", 30)
end
return
end
local theFlags = theData.theFlags
-- filter and reset timers
local filtered = {}
local now = timer.getTime()
for name, deadLine in pairs(theFlags) do
local theZone = raiseFlag.flags[name]
if theZone then
theZone.deadLine = now + deadLine
filtered[name] = theZone
if theZone.verbose then
trigger.action.outText("+++rFlg: (persistence) reset zone <" .. name .. "> to <" .. theZone.deadLine .. "> (<" .. deadLine .. ">)", 30)
end
else
trigger.action.outText("+++rFlag: (persistence) filtered <" .. name .. ">, does not exist in miz.", 30)
end
end
for name, theZone in pairs(raiseFlag.flags) do
if not filtered[name] and theZone.verbose then
trigger.action.outText("+++rFlg: (persistence) filtered spent/non-saved <" .. name .. ">.", 30)
end
end
raiseFlag.flags = filtered
end
--
-- config & go!
--
@@ -117,39 +154,30 @@ function raiseFlag.readConfigZone()
end
function raiseFlag.start()
-- lib check
if not dcsCommon.libCheck then
trigger.action.outText("cfx raise flag requires dcsCommon", 30)
return false
end
if not dcsCommon.libCheck("cfx Raise Flag", raiseFlag.requiredLibs) then
return false
end
-- read config
if not dcsCommon.libCheck("cfx Raise Flag", raiseFlag.requiredLibs)then return false end
raiseFlag.readConfigZone()
-- process raise Flags Zones
local attrZones = cfxZones.getZonesWithAttributeNamed("raiseFlag")
for k, aZone in pairs(attrZones) do
raiseFlag.createRaiseFlagWithZone(aZone) -- process attributes
raiseFlag.addRaiseFlag(aZone) -- add to list
end
-- try synonym
attrZones = cfxZones.getZonesWithAttributeNamed("raiseFlag!")
for k, aZone in pairs(attrZones) do
raiseFlag.createRaiseFlagWithZone(aZone) -- process attributes
raiseFlag.addRaiseFlag(aZone) -- add to list
end
-- start update
raiseFlag.update()
if persistence then
callbacks = {}
callbacks.persistData = raiseFlag.saveData
persistence.registerModule("raiseFlag", callbacks)
-- now load my data
raiseFlag.loadData()
end
-- start update at 0.5 secs mark
timer.scheduleFunction(raiseFlag.update, true, timer.getTime() + 0.5)
trigger.action.outText("cfx raiseFlag v" .. raiseFlag.version .. " started.", 30)
return true
end
-- let's go!
if not raiseFlag.start() then
trigger.action.outText("cfx Raise Flag aborted: missing libraries", 30)
raiseFlag = nil