Version 0.996

QoL: multiple output flags, last-letter verification for ?, !, ":"
This commit is contained in:
Christian Franz 2022-03-31 16:08:12 +02:00
parent 6d1e992037
commit 9f54ac1917
18 changed files with 2119 additions and 103 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,9 +1,9 @@
cfxNDB = {} cfxNDB = {}
cfxNDB.version = "1.1.0" cfxNDB.version = "1.2.0"
--[[-- --[[--
cfxNDB: cfxNDB:
Copyright (c) 2021 by Christian Franz and cf/x AG Copyright (c) 2021, 2022 by Christian Franz and cf/x AG
Zone enhancement that simulates an NDB for a zone. Zone enhancement that simulates an NDB for a zone.
If zone is linked, the NDB's location is updated If zone is linked, the NDB's location is updated
@ -21,6 +21,7 @@ cfxNDB.version = "1.1.0"
- paused flag, paused handling - paused flag, paused handling
- startNDB() can accept string - startNDB() can accept string
- stopNDB() can accept string - stopNDB() can accept string
1.2.0 - DML full integration
--]]-- --]]--
@ -112,13 +113,19 @@ function cfxNDB.createNDBWithZone(theZone)
-- paused -- paused
theZone.paused = cfxZones.getBoolFromZoneProperty(theZone, "paused", false) theZone.paused = cfxZones.getBoolFromZoneProperty(theZone, "paused", false)
-- watchflags
theZone.ndbTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
if cfxZones.hasProperty(theZone, "ndbTriggerMethod") then
theZone.ndbTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "ndbTriggerMethod", "change")
end
-- on/offf query flags -- on/offf query flags
if cfxZones.hasProperty(theZone, "on?") then if cfxZones.hasProperty(theZone, "on?") then
theZone.onFlag = cfxZones.getStringFromZoneProperty(theZone, "on?", "none") theZone.onFlag = cfxZones.getStringFromZoneProperty(theZone, "on?", "none")
end end
if theZone.onFlag then if theZone.onFlag then
theZone.onFlagVal = trigger.misc.getUserFlag(theZone.onFlag) -- save last value theZone.onFlagVal = cfxZones.getFlagValue(theZone.onFlag, theZone) -- trigger.misc.getUserFlag(theZone.onFlag) -- save last value
end end
if cfxZones.hasProperty(theZone, "off?") then if cfxZones.hasProperty(theZone, "off?") then
@ -126,7 +133,7 @@ function cfxNDB.createNDBWithZone(theZone)
end end
if theZone.offFlag then if theZone.offFlag then
theZone.offFlagVal = trigger.misc.getUserFlag(theZone.offFlag) -- save last value theZone.offFlagVal = cfxZones.getFlagValue(theZone.offFlag, theZone) --trigger.misc.getUserFlag(theZone.offFlag) -- save last value
end end
-- start it -- start it
@ -158,24 +165,17 @@ function cfxNDB.update()
end end
-- now check triggers to start/stop -- now check triggers to start/stop
if theNDB.onFlagVal then if cfxZones.testZoneFlag(theNDB, theNDB.onFlag, theNDB.ndbTriggerMethod, "onFlagVal") then
-- see if this changed -- yupp, trigger start
local currTriggerVal = trigger.misc.getUserFlag(theNDB.onFlag) cfxNDB.startNDB(theNDB)
if currTriggerVal ~= theNDB.onFlagVal then
-- yupp, trigger start
cfxNDB.startNDB(theNDB)
theNDB.onFlagVal = currTriggerVal
end
end end
if theNDB.offFlagVal then
local currTriggerVal = trigger.misc.getUserFlag(theNDB.offFlag) if cfxZones.testZoneFlag(theNDB, theNDB.offFlag, theNDB.ndbTriggerMethod, "offFlagVal") then
if currTriggerVal ~= theNDB.offFlagVal then -- yupp, trigger start
-- yupp, trigger start cfxNDB.stopNDB(theNDB)
cfxNDB.stopNDB(theNDB) end
theNDB.offFlagVal = currTriggerVal
end
end
end end
end end

View File

@ -1,5 +1,5 @@
cfxObjectDestructDetector = {} cfxObjectDestructDetector = {}
cfxObjectDestructDetector.version = "1.1.0" cfxObjectDestructDetector.version = "1.2.0"
cfxObjectDestructDetector.requiredLibs = { cfxObjectDestructDetector.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
"cfxZones", -- Zones, of course "cfxZones", -- Zones, of course
@ -10,6 +10,7 @@ cfxObjectDestructDetector.verbose = false
1.0.0 initial version, based on parashoo, arty zones 1.0.0 initial version, based on parashoo, arty zones
1.0.1 fixed bug: trigger.MISC.getUserFlag() 1.0.1 fixed bug: trigger.MISC.getUserFlag()
1.1.0 added support for method, f! and destroyed! 1.1.0 added support for method, f! and destroyed!
1.2.0 DML / Watchflag support
Detect when an object with OBJECT ID as assigned in ME dies Detect when an object with OBJECT ID as assigned in ME dies
@ -73,13 +74,21 @@ function cfxObjectDestructDetector.processObjectDestructZone(aZone)
end end
-- new method support -- new method support
aZone.method = cfxZones.getStringFromZoneProperty(aZone, "method", "flip") aZone.oddMethod = cfxZones.getStringFromZoneProperty(aZone, "method", "flip")
if cfxZones.hasProperty(aZone, "oddMethod") then
aZone.oddMethod = cfxZones.getStringFromZoneProperty(aZone, "oddMethod", "flip")
end
if cfxZones.hasProperty(aZone, "f!") then if cfxZones.hasProperty(aZone, "f!") then
aZone.outDestroyFlag = cfxZones.getNumberFromZoneProperty(aZone, "f!", -1) aZone.outDestroyFlag = cfxZones.getStringFromZoneProperty(aZone, "f!", "*none")
end end
if cfxZones.hasProperty(aZone, "destroyed!") then if cfxZones.hasProperty(aZone, "destroyed!") then
aZone.outDestroyFlag = cfxZones.getNumberFromZoneProperty(aZone, "destroyed!", -1) aZone.outDestroyFlag = cfxZones.getStringFromZoneProperty(aZone, "destroyed!", "*none")
end
if cfxZones.hasProperty(aZone, "objectDestroyed!") then
aZone.outDestroyFlag = cfxZones.getStringFromZoneProperty(aZone, "objectDestroyed!", "*none")
end end
end end
-- --
@ -95,6 +104,7 @@ function cfxObjectDestructDetector:onEvent(event)
for idx, aZone in pairs(cfxObjectDestructDetector.objectZones) do for idx, aZone in pairs(cfxObjectDestructDetector.objectZones) do
if aZone.ID == id then if aZone.ID == id then
-- flag manipulation -- flag manipulation
-- OLD FLAG SUPPORT, SOON TO BE REMOVED
if aZone.setFlag then if aZone.setFlag then
trigger.action.setUserFlag(aZone.setFlag, 1) trigger.action.setUserFlag(aZone.setFlag, 1)
end end
@ -109,10 +119,11 @@ function cfxObjectDestructDetector:onEvent(event)
local val = trigger.misc.getUserFlag(aZone.decreaseFlag) - 1 local val = trigger.misc.getUserFlag(aZone.decreaseFlag) - 1
trigger.action.setUserFlag(aZone.decreaseFlag, val) trigger.action.setUserFlag(aZone.decreaseFlag, val)
end end
-- END OF OLD CODE, TO BE REMOVED
-- support for banging -- support for banging
if aZone.outDestroyFlag then if aZone.outDestroyFlag then
cfxZones.pollFlag(aZone.outDestroyFlag, aZone.method) cfxZones.pollFlag(aZone.outDestroyFlag, aZone.oddMethod, aZone)
end end
-- invoke callbacks -- invoke callbacks

View File

@ -1,11 +1,14 @@
cfxReconMode = {} cfxReconMode = {}
cfxReconMode.version = "1.4.1" cfxReconMode.version = "1.5.0"
cfxReconMode.verbose = false -- set to true for debug info cfxReconMode.verbose = false -- set to true for debug info
cfxReconMode.reconSound = "UI_SCI-FI_Tone_Bright_Dry_20_stereo.wav" -- to be played when somethiong discovered cfxReconMode.reconSound = "UI_SCI-FI_Tone_Bright_Dry_20_stereo.wav" -- to be played when somethiong discovered
cfxReconMode.prioList = {} -- group names that are high prio and generate special event cfxReconMode.prioList = {} -- group names that are high prio and generate special event
cfxReconMode.blackList = {} -- group names that are NEVER detected. Comma separated strings, e.g. {"Always Hidden", "Invisible Group"} cfxReconMode.blackList = {} -- group names that are NEVER detected. Comma separated strings, e.g. {"Always Hidden", "Invisible Group"}
cfxReconMode.removeWhenDestroyed = true
cfxReconMode.activeMarks = {} -- all marks and their groups, indexed by groupName
cfxReconMode.requiredLibs = { cfxReconMode.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
"cfxZones", -- Zones, of course "cfxZones", -- Zones, of course
@ -42,7 +45,9 @@ VERSION HISTORY
- recon sound - recon sound
- read all flight groups at start to get rid of the - read all flight groups at start to get rid of the
- late activation work-around - late activation work-around
1.5.0 - removeWhenDestroyed()
- autoRemove()
- readConfigZone creates default config zone so we get correct defaulting
cfxReconMode is a script that allows units to perform reconnaissance cfxReconMode is a script that allows units to perform reconnaissance
missions and, after detecting units, marks them on the map with missions and, after detecting units, marks them on the map with
@ -279,14 +284,16 @@ function cfxReconMode.removeMarkForArgs(args)
local theID = args[4] local theID = args[4]
local theName = args[5] local theName = args[5]
-- if not theGroup then return end -- only remove if it wasn't already removed.
-- if not theGroup:isExist then return end -- this method is called async *and* sync!
if cfxReconMode.activeMarks[theName] then
trigger.action.removeMark(theID)
-- invoke callbacks
cfxReconMode.invokeCallbacks("removed", theSide, theScout, theGroup, theName)
cfxReconMode.activeMarks[theName] = nil -- also remove from list of groups being checked
end
trigger.action.removeMark(theID) cfxReconMode.detectedGroups[theName] = nil -- some housekeeping.
cfxReconMode.detectedGroups[theName] = nil
-- invoke callbacks
cfxReconMode.invokeCallbacks("removed", theSide, theScout, theGroup, theName)
end end
@ -294,18 +301,23 @@ function cfxReconMode.detectedGroup(mySide, theScout, theGroup, theLoc)
-- put a mark on the map -- put a mark on the map
if cfxReconMode.applyMarks then if cfxReconMode.applyMarks then
local theID = cfxReconMode.placeMarkForUnit(theLoc, mySide, theGroup) local theID = cfxReconMode.placeMarkForUnit(theLoc, mySide, theGroup)
local gName = theGroup:getName()
local args = {mySide, theScout, theGroup, theID, gName}
cfxReconMode.activeMarks[gName] = args
-- schedule removal if desired -- schedule removal if desired
if cfxReconMode.marksFadeAfter > 0 then if cfxReconMode.marksFadeAfter > 0 then
args = {mySide, theScout, theGroup, theID, theGroup:getName()}
timer.scheduleFunction(cfxReconMode.removeMarkForArgs, args, timer.getTime() + cfxReconMode.marksFadeAfter) timer.scheduleFunction(cfxReconMode.removeMarkForArgs, args, timer.getTime() + cfxReconMode.marksFadeAfter)
end end
end end
-- say something -- say something
if cfxReconMode.announcer then if cfxReconMode.announcer then
trigger.action.outTextForCoalition(mySide, theScout:getName() .. " reports new ground contact " .. theGroup:getName(), 30) trigger.action.outTextForCoalition(mySide, theScout:getName() .. " reports new ground contact " .. theGroup:getName(), 30)
trigger.action.outText("+++recon: announced for side " .. mySide, 30)
-- play a sound -- play a sound
trigger.action.outSoundForCoalition(mySide, cfxReconMode.reconSound) trigger.action.outSoundForCoalition(mySide, cfxReconMode.reconSound)
else
--trigger.action.outText("+++recon: announcer off", 30)
end end
-- see if it was a prio target -- see if it was a prio target
@ -420,6 +432,38 @@ function cfxReconMode.updateQueues()
end end
end end
function cfxReconMode.isGroupStillAlive(gName)
local theGroup = Group.getByName(gName)
if not theGroup then return false end
if not theGroup:isExist() then return false end
local allUnits = theGroup:getUnits()
for idx, aUnit in pairs (allUnits) do
if aUnit:getLife() >= 1 then return true end
end
return false
end
function cfxReconMode.autoRemove()
-- schedule next call
timer.scheduleFunction(cfxReconMode.autoRemove, {}, timer.getTime() + 1/cfxReconMode.ups)
local toRemove = {}
-- scan all marked groups, and when they no longer exist, remove them
for idx, args in pairs (cfxReconMode.activeMarks) do
-- args = {mySide, theScout, theGroup, theID, gName}
local gName = args[5]
if not cfxReconMode.isGroupStillAlive(gName) then
-- remove mark, remove group from set
table.insert(toRemove, args)
end
end
for idx, args in pairs(toRemove) do
cfxReconMode.removeMarkForArgs(args)
trigger.action.outText("+++recn: removed mark: " .. args[5], 30)
end
end
-- event handler -- event handler
function cfxReconMode:onEvent(event) function cfxReconMode:onEvent(event)
if not event then return end if not event then return end
@ -509,10 +553,11 @@ function cfxReconMode.readConfigZone()
if cfxReconMode.verbose then if cfxReconMode.verbose then
trigger.action.outText("+++rcn: no config zone!", 30) trigger.action.outText("+++rcn: no config zone!", 30)
end end
return theZone = cfxZones.createSimpleZone("reconModeConfig")
end else
if cfxReconMode.verbose then if cfxReconMode.verbose then
trigger.action.outText("+++rcn: found config zone!", 30) trigger.action.outText("+++rcn: found config zone!", 30)
end
end end
cfxReconMode.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false) cfxReconMode.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
@ -539,10 +584,13 @@ function cfxReconMode.readConfigZone()
cfxReconMode.applyMarks = cfxZones.getBoolFromZoneProperty(theZone, "applyMarks", true) cfxReconMode.applyMarks = cfxZones.getBoolFromZoneProperty(theZone, "applyMarks", true)
cfxReconMode.announcer = cfxZones.getBoolFromZoneProperty(theZone, "announcer", true) cfxReconMode.announcer = cfxZones.getBoolFromZoneProperty(theZone, "announcer", true)
-- trigger.action.outText("recon: announcer is " .. dcsCommon.bool2Text(cfxReconMode.announcer), 30) -- announced
if cfxZones.hasProperty(theZone, "reconSound") then if cfxZones.hasProperty(theZone, "reconSound") then
cfxReconMode.reconSound = cfxZones.getStringFromZoneProperty(theZone, "reconSound", "<nosound>") cfxReconMode.reconSound = cfxZones.getStringFromZoneProperty(theZone, "reconSound", "<nosound>")
end end
cfxReconMode.removeWhenDestroyed = cfxZones.getBoolFromZoneProperty(theZone, "autoRemove", true)
end end
-- --
@ -563,7 +611,13 @@ function cfxReconMode.start()
-- start update cycle -- start update cycle
cfxReconMode.updateQueues() cfxReconMode.updateQueues()
-- if dead groups are removed from map,
-- schedule housekeeping
if cfxReconMode.removeWhenDestroyed then
cfxReconMode.autoRemove()
end
if cfxReconMode.autoRecon then if cfxReconMode.autoRecon then
-- install own event handler to detect -- install own event handler to detect
-- when a unit takes off and add it to scout -- when a unit takes off and add it to scout

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
cloneZones = {} cloneZones = {}
cloneZones.version = "1.4.0" cloneZones.version = "1.4.1"
cloneZones.verbose = false cloneZones.verbose = false
cloneZones.requiredLibs = { cloneZones.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
@ -37,6 +37,7 @@ cloneZones.uniqueCounter = 9200000 -- we start group numbering here
1.3.1 - groupTracker interface 1.3.1 - groupTracker interface
- trackWith: attribute - trackWith: attribute
1.4.0 - Watchflags 1.4.0 - Watchflags
1.4.1 - trackWith: accepts list of trackers
--]]-- --]]--
@ -548,14 +549,31 @@ function cloneZones.handoffTracking(theGroup, theZone)
return return
end end
local trackerName = theZone.trackWith local trackerName = theZone.trackWith
if trackerName == "*" then trackerName = theZone.name end --if trackerName == "*" then trackerName = theZone.name end
local theTracker = groupTracker.getTrackerByName(trackerName) -- now assemble a list of all trackers
if not theTracker then if cloneZones.verbose or theZone.verbose then
trigger.action.outText("+++clne: <" .. theZone.name .. ">: cannot find tracker named <".. trackerName .. ">", 30) trigger.action.outText("+++clne: clone pass-off: " .. trackerName, 30)
return end
local trackerNames = {}
if dcsCommon.containsString(trackerName, ',') then
trackerNames = dcsCommon.splitString(trackerName, ',')
else
table.insert(trackerNames, trackerName)
end
for idx, aTrk in pairs(trackerNames) do
local theName = dcsCommon.trim(aTrk)
if theName == "*" then theName = theZone.name end
local theTracker = groupTracker.getTrackerByName(theName)
if not theTracker then
trigger.action.outText("+++clne: <" .. theZone.name .. ">: cannot find tracker named <".. theName .. ">", 30)
else
groupTracker.addGroupToTracker(theGroup, theTracker)
if cloneZones.verbose or theZone.verbose then
trigger.action.outText("+++clne: added " .. theGroup:getName() .. " to tracker " .. theName, 30)
end
end
end end
groupTracker.addGroupToTracker(theGroup, theTracker)
end end
function cloneZones.spawnWithTemplateForZone(theZone, spawnZone) function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)

View File

@ -1,5 +1,5 @@
dcsCommon = {} dcsCommon = {}
dcsCommon.version = "2.5.7" dcsCommon.version = "2.5.8"
--[[-- VERSION HISTORY --[[-- VERSION HISTORY
2.2.6 - compassPositionOfARelativeToB 2.2.6 - compassPositionOfARelativeToB
- clockPositionOfARelativeToB - clockPositionOfARelativeToB
@ -67,6 +67,7 @@ dcsCommon.version = "2.5.7"
- stringIsPositiveNumber() - stringIsPositiveNumber()
2.5.6 - corrected stringEndsWith() bug with str 2.5.6 - corrected stringEndsWith() bug with str
2.5.7 - point2text(p) 2.5.7 - point2text(p)
2.5.8 - string2GroupCat()
--]]-- --]]--
@ -1782,6 +1783,30 @@ dcsCommon.version = "2.5.7"
return t return t
end end
function dcsCommon.string2GroupCat(inString)
if not inString then return 2 end -- default ground
inString = inString:lower()
inString = dcsCommon.trim(inString)
local catNum = tonumber(inString)
if catNum then
if catNum < 0 then catNum = 0 end
if catNum > 4 then catNum = 4 end
return catNum
end
catNum = 2 -- ground default
if dcsCommon.stringStartsWith(inString, "grou") then catNum = 2 end
if dcsCommon.stringStartsWith(inString, "air") then catNum = 0 end
if dcsCommon.stringStartsWith(inString, "hel") then catNum = 1 end
if dcsCommon.stringStartsWith(inString, "shi") then catNum = 3 end
if dcsCommon.stringStartsWith(inString, "trai") then catNum = 4 end
return catNum
end
-- recursively show the contents of a variable -- recursively show the contents of a variable
function dcsCommon.dumpVar(key, value, prefix, inrecursion) function dcsCommon.dumpVar(key, value, prefix, inrecursion)
if not inrecursion then if not inrecursion then

View File

@ -1,5 +1,5 @@
delayFlag = {} delayFlag = {}
delayFlag.version = "1.2.0" delayFlag.version = "1.2.1"
delayFlag.verbose = false delayFlag.verbose = false
delayFlag.requiredLibs = { delayFlag.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
@ -29,6 +29,8 @@ delayFlag.flags = {}
- pauseDelay? - pauseDelay?
- unpauseDelay? - unpauseDelay?
1.2.0 - Watchflags 1.2.0 - Watchflags
1.2.1 - method goes to dlyMethod
- delay done is correctly inited
--]]-- --]]--
@ -86,15 +88,18 @@ function delayFlag.createTimerWithZone(theZone)
end end
theZone.method = cfxZones.getStringFromZoneProperty(theZone, "method", "flip") theZone.delayMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "flip")
-- out flag if cfxZones.hasProperty(theZone, "delayMethod") then
if cfxZones.hasProperty(theZone, "out!") then theZone.delayMethod = cfxZones.getStringFromZoneProperty(theZone, "delayMethod", "flip")
theZone.delayDoneFlag = cfxZones.getStringFromZoneProperty(theZone, "out!", -1)
end end
-- out flag
theZone.delayDoneFlag = cfxZones.getStringFromZoneProperty(theZone, "out!", "*<none>")
if cfxZones.hasProperty(theZone, "delayDone!") then if cfxZones.hasProperty(theZone, "delayDone!") then
theZone.delayDoneFlag = cfxZones.getStringFromZoneProperty(theZone, "delayDone!", -1) theZone.delayDoneFlag = cfxZones.getStringFromZoneProperty(theZone, "delayDone!", "*<none>")
end end
-- stop the press! -- stop the press!
@ -205,10 +210,11 @@ function delayFlag.update()
-- end timer -- end timer
aZone.delayRunning = false aZone.delayRunning = false
-- poll flag -- poll flag
cfxZones.pollFlag(aZone.delayDoneFlag, aZone.method, aZone) if delayFlag.verbose or aZone.verbose then
if delayFlag.verbose then
trigger.action.outText("+++dlyF: banging on " .. aZone.delayDoneFlag, 30) trigger.action.outText("+++dlyF: banging on " .. aZone.delayDoneFlag, 30)
end end
cfxZones.pollFlag(aZone.delayDoneFlag, aZone.delayMethod, aZone)
end end
end end

View File

@ -1,5 +1,5 @@
groupTracker = {} groupTracker = {}
groupTracker.version = "1.0.0" groupTracker.version = "1.1.0"
groupTracker.verbose = false groupTracker.verbose = false
groupTracker.ups = 1 groupTracker.ups = 1
groupTracker.requiredLibs = { groupTracker.requiredLibs = {
@ -11,6 +11,9 @@ groupTracker.trackers = {}
--[[-- --[[--
Version History Version History
1.0.0 - Initial version 1.0.0 - Initial version
1.1.0 - filtering added
- array support for trackers
- array support for trackers
--]]-- --]]--
@ -37,7 +40,19 @@ end
-- adding a group to a tracker - called by other modules and API -- adding a group to a tracker - called by other modules and API
-- --
function groupTracker.addGroupToTracker(theGroup, theTracker) function groupTracker.addGroupToTracker(theGroup, theTracker)
if groupTracker.verbose then -- check if filtering is enabled for this tracker
if theTracker.groupFilter then
cat = theGroup:getCategory()
if not cat then return end -- strange, but better safe than sorry
if cat ~= theTracker.groupFilter then
if groupTracker.verbose then
trigger.action.outText("+++gTrk: Tracker <" .. theTracker.name .. "> rejected <" .. theGroup:getName() .. "> for class mismatch. Expect: " .. theTracker.groupFilter .. " received: " .. cat , 30)
end
return
end
end
if groupTracker.verbose or theTracker.verbose then
trigger.action.outText("+++gTrk: will add group <" .. theGroup:getName() .. "> to tracker " .. theTracker.name, 30) trigger.action.outText("+++gTrk: will add group <" .. theGroup:getName() .. "> to tracker " .. theTracker.name, 30)
end end
@ -96,6 +111,13 @@ function groupTracker.createTrackerWithZone(theZone)
-- we may need to zero this flag -- we may need to zero this flag
end end
if cfxZones.hasProperty(theZone, "groupFilter") then
local filterString = cfxZones.getStringFromZoneProperty(theZone, "groupFilter", "2") -- ground
theZone.groupFilter = dcsCommon.string2GroupCat(filterString)
if groupTracker.verbose or theZone.verbose then
trigger.action.outText("+++gTrck: filtering " .. theZone.groupFilter .. " in " .. theZone.name, 30)
end
end
end end
-- --
@ -121,7 +143,7 @@ function groupTracker.checkGroups(theZone)
if isDead then if isDead then
-- bang deceased -- bang deceased
if groupTracker.verbose then if groupTracker.verbose or theZone.verbose then
trigger.action.outText("+++gTrk: dead group detected in " .. theZone.name .. ", discarding.", 30) trigger.action.outText("+++gTrk: dead group detected in " .. theZone.name .. ", discarding.", 30)
end end
if theZone.tRemoveGroup then if theZone.tRemoveGroup then
@ -157,6 +179,35 @@ end
function groupTracker.trackGroupsInZone(theZone) function groupTracker.trackGroupsInZone(theZone)
local trackerName = cfxZones.getStringFromZoneProperty(theZone, "addToTracker:", "<none>") local trackerName = cfxZones.getStringFromZoneProperty(theZone, "addToTracker:", "<none>")
local theGroups = cfxZones.allGroupsInZone(theZone, nil)
-- now init array processing
local trackerNames = {}
if dcsCommon.containsString(trackerName, ',') then
trackerNames = dcsCommon.splitString(trackerName, ',')
else
table.insert(trackerNames, trackerName)
end
for idx, aTrk in pairs(trackerNames) do
local theName = dcsCommon.trim(aTrk)
if theName == "*" then theName = theZone.name end
local theTracker = groupTracker.getTrackerByName(theName)
if not theTracker then
trigger.action.outText("+++gTrk-TW: <" .. theZone.name .. ">: cannot find tracker named <".. theName .. ">", 30)
else
for idy, aGroup in pairs(theGroups) do
groupTracker.addGroupToTracker(aGroup, theTracker)
if cloneZones.verbose or theZone.verbose then
trigger.action.outText("+++gTrk-TW: added " .. theGroup:getName() .. " to tracker " .. theName, 30)
end
end
end
end
-- old code, non-array capable
--[[--
if trackerName == "*" then trackerName = theZone.name end if trackerName == "*" then trackerName = theZone.name end
local theTracker = groupTracker.getTrackerByName(trackerName) local theTracker = groupTracker.getTrackerByName(trackerName)
@ -172,7 +223,7 @@ function groupTracker.trackGroupsInZone(theZone)
end end
groupTracker.addGroupToTracker(aGroup, theTracker) groupTracker.addGroupToTracker(aGroup, theTracker)
end end
--]]--
end end
@ -215,7 +266,7 @@ function groupTracker.start()
end end
-- find and process all zones that want me to immediately add -- find and process all zones that want me to immediately add
-- units to the tracker -- units to the tracker. Must run AFTER we have gathered all trackers
local attrZones = cfxZones.getZonesWithAttributeNamed("addToTracker:") local attrZones = cfxZones.getZonesWithAttributeNamed("addToTracker:")
for k, aZone in pairs(attrZones) do for k, aZone in pairs(attrZones) do
groupTracker.trackGroupsInZone(aZone) -- process attributes groupTracker.trackGroupsInZone(aZone) -- process attributes
@ -234,9 +285,3 @@ if not groupTracker.start() then
messenger = nil messenger = nil
end end
--[[--
add a pass to immediately add units in zones with 'addToTracker'
after zone pass
add an output flag for the total number of units it watches, so when that changes, a change is instigated automatically
--]]--

View File

@ -1,5 +1,5 @@
messenger = {} messenger = {}
messenger.version = "1.2.0" messenger.version = "1.2.1"
messenger.verbose = false messenger.verbose = false
messenger.requiredLibs = { messenger.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
@ -18,8 +18,8 @@ messenger.messengers = {}
1.1.1 - firewalled coalition to msgCoalition 1.1.1 - firewalled coalition to msgCoalition
- messageOn? - messageOn?
- messageOff? - messageOff?
1.2.0 - triggerMethod (original Watchflag integration) 1.2.0 - msgTriggerMethod (original Watchflag integration)
1.2.1 - qoL: <n> = newline, <z> = zone name, <v> = value
--]]-- --]]--
function messenger.addMessenger(theZone) function messenger.addMessenger(theZone)
@ -40,9 +40,24 @@ end
-- --
-- read attributes -- read attributes
-- --
function messenger.preProcMessage(inMsg, theZone)
if not inMsg then return "<nil inMsg>" end
local formerType = type(inMsg)
if formerType ~= "string" then inMsg = tostring(inMsg) end
if not inMsg then inMsg = "<inMsg is incompatible type " .. formerType .. ">" end
local outMsg = ""
-- replace line feeds
outMsg = inMsg:gsub("<n>", "\n")
if theZone then
outMsg = outMsg:gsub("<z>", theZone.name)
end
return outMsg
end
function messenger.createMessengerWithZone(theZone) function messenger.createMessengerWithZone(theZone)
-- start val - a range -- start val - a range
theZone.message = cfxZones.getStringFromZoneProperty(theZone, "message", "") local aMessage = cfxZones.getStringFromZoneProperty(theZone, "message", "")
theZone.message = messenger.preProcMessage(aMessage, theZone)
theZone.spaceBefore = cfxZones.getBoolFromZoneProperty(theZone, "spaceBefore", false) theZone.spaceBefore = cfxZones.getBoolFromZoneProperty(theZone, "spaceBefore", false)
theZone.spaceAfter = cfxZones.getBoolFromZoneProperty(theZone, "spaceAfter", false) theZone.spaceAfter = cfxZones.getBoolFromZoneProperty(theZone, "spaceAfter", false)
@ -55,8 +70,11 @@ function messenger.createMessengerWithZone(theZone)
theZone.duration = cfxZones.getNumberFromZoneProperty(theZone, "duration", 30) theZone.duration = cfxZones.getNumberFromZoneProperty(theZone, "duration", 30)
-- triggerMethod -- msgTriggerMethod
theZone.triggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change") theZone.msgTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
if cfxZones.hasProperty(theZone, "msgTriggerMethod") then
theZone.msgTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "msgTriggerMethod", "change")
end
-- trigger flag f? in? messageOut? -- trigger flag f? in? messageOut?
if cfxZones.hasProperty(theZone, "f?") then if cfxZones.hasProperty(theZone, "f?") then
@ -124,6 +142,7 @@ function messenger.getMessage(theZone)
-- replace *zone and *value wildcards -- replace *zone and *value wildcards
msg = string.gsub(msg, "*name", zName) msg = string.gsub(msg, "*name", zName)
msg = string.gsub(msg, "*value", zVal) msg = string.gsub(msg, "*value", zVal)
msg = string.gsub(msg, "<v>", zVal)
return msg return msg
end end
@ -163,7 +182,7 @@ function messenger.update()
for idx, aZone in pairs(messenger.messengers) do for idx, aZone in pairs(messenger.messengers) do
-- make sure to re-start before reading time limit -- make sure to re-start before reading time limit
-- new trigger code -- new trigger code
if cfxZones.testZoneFlag(aZone, aZone.triggerMessagerFlag, aZone.triggerMethod, "lastMessageTriggerValue") then if cfxZones.testZoneFlag(aZone, aZone.triggerMessagerFlag, aZone.msgTriggerMethod, "lastMessageTriggerValue") then
if messenger.verbose then if messenger.verbose then
trigger.action.outText("+++msgr: triggered on in? for <".. aZone.name ..">", 30) trigger.action.outText("+++msgr: triggered on in? for <".. aZone.name ..">", 30)
end end
@ -171,14 +190,14 @@ function messenger.update()
end end
-- old trigger code -- old trigger code
if cfxZones.testZoneFlag(aZone, aZone.messageOffFlag, "change", "lastMessageOff") then if cfxZones.testZoneFlag(aZone, aZone.messageOffFlag, aZone.msgTriggerMethod, "lastMessageOff") then
aZone.messageOff = true aZone.messageOff = true
if messenger.verbose then if messenger.verbose then
trigger.action.outText("+++msg: messenger <" .. aZone.name .. "> turned ***OFF***", 30) trigger.action.outText("+++msg: messenger <" .. aZone.name .. "> turned ***OFF***", 30)
end end
end end
if cfxZones.testZoneFlag(aZone, aZone.messageOnFlag, "change", "lastMessageOn") then if cfxZones.testZoneFlag(aZone, aZone.messageOnFlag, aZone.msgTriggerMethod, "lastMessageOn") then
aZone.messageOff = false aZone.messageOff = false
if messenger.verbose then if messenger.verbose then
trigger.action.outText("+++msg: messenger <" .. aZone.name .. "> turned ON", 30) trigger.action.outText("+++msg: messenger <" .. aZone.name .. "> turned ON", 30)

View File

@ -1,5 +1,5 @@
raiseFlag = {} raiseFlag = {}
raiseFlag.version = "1.2.0" raiseFlag.version = "1.2.1"
raiseFlag.verbose = false raiseFlag.verbose = false
raiseFlag.requiredLibs = { raiseFlag.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
@ -14,6 +14,7 @@ raiseFlag.flags = {}
1.0.1 - synonym "raiseFlag!" 1.0.1 - synonym "raiseFlag!"
1.1.0 - DML update 1.1.0 - DML update
1.2.0 - Watchflag update 1.2.0 - Watchflag update
1.2.1 - support for 'inc', 'dec', 'flip'
--]]-- --]]--
function raiseFlag.addRaiseFlag(theZone) function raiseFlag.addRaiseFlag(theZone)
@ -42,7 +43,8 @@ function raiseFlag.createRaiseFlagWithZone(theZone)
theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, "raiseFlag!", "<none>") -- the flag to raise theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, "raiseFlag!", "<none>") -- the flag to raise
end end
theZone.flagValue = cfxZones.getNumberFromZoneProperty(theZone, "value", 1) -- value to set to theZone.flagValue = cfxZones.getStringFromZoneProperty(theZone, "value", "inc") -- value to set to. default is command 'inc'
theZone.flagValue = theZone.flagValue:lower()
theZone.minAfterTime, theZone.maxAfterTime = cfxZones.getPositiveRangeFromZoneProperty(theZone, "afterTime", -1) theZone.minAfterTime, theZone.maxAfterTime = cfxZones.getPositiveRangeFromZoneProperty(theZone, "afterTime", -1)
@ -77,7 +79,19 @@ function raiseFlag.triggered(args)
local theZone = args.theZone local theZone = args.theZone
if theZone.raiseStopped then return end if theZone.raiseStopped then return end
-- if we get here, we aren't stopped and do the flag pull -- if we get here, we aren't stopped and do the flag pull
cfxZones.setFlagValue(theZone.raiseFlag, theZone.flagValue, theZone) local command = theZone.flagValue
command = dcsCommon.trim(command)
if command == "inc" or command == "dec" or command == "flip" then
cfxZones.pollFlag(theZone.raiseFlag, command, theZone)
if raiseFlag.verbose or theZone.verbose then
trigger.action.outText("+++rFlg - raising <" .. theZone.raiseFlag .. "> with method " .. command ,30)
end
else
cfxZones.setFlagValue(theZone.raiseFlag, theZone.flagValue, theZone)
if raiseFlag.verbose or theZone.verbose then
trigger.action.outText("+++rFlg - raising <" .. theZone.raiseFlag .. "> to value: " .. theZone.flagValue ,30)
end
end
end end
-- --
@ -163,4 +177,7 @@ end
if not raiseFlag.start() then if not raiseFlag.start() then
trigger.action.outText("cfx Raise Flag aborted: missing libraries", 30) trigger.action.outText("cfx Raise Flag aborted: missing libraries", 30)
raiseFlag = nil raiseFlag = nil
end end
-- add rnd(a,b) support to value
-- better: if value is a range, make it a random. problem: negative values are legal, so we need formula

View File

@ -1,11 +1,19 @@
unitZone={} unitZone={}
unitZone.version = "1.0.0" unitZone.version = "1.1.0"
unitZone.verbose = false unitZone.verbose = false
unitZone.ups = 1 unitZone.ups = 1
unitZone.requiredLibs = { unitZone.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
"cfxZones", -- Zones, of course "cfxZones", -- Zones, of course
} }
--[[--
Version History
1.0.0 - Initial Version
1.1.0 - DML flag integration
- method/uzMethod
--]]--
unitZone.unitZones = {} unitZone.unitZones = {}
function unitZone.addUnitZone(theZone) function unitZone.addUnitZone(theZone)
@ -62,7 +70,17 @@ function unitZone.createUnitZone(theZone)
-- coalition -- coalition
theZone.uzCoalition = cfxZones.getCoalitionFromZoneProperty(theZone, "coalition", 0) -- 0 = all theZone.uzCoalition = cfxZones.getCoalitionFromZoneProperty(theZone, "coalition", 0) -- 0 = all
if cfxZones.hasProperty(theZone, "uzCoalition") then if cfxZones.hasProperty(theZone, "uzCoalition") then
cfxZones.uzCoalition = cfxZones.getCoalitionFromZoneProperty(theZone, "uzCoalition", 0) theZone.uzCoalition = cfxZones.getCoalitionFromZoneProperty(theZone, "uzCoalition", 0)
end
if unitZone.verbose then
trigger.action.outText("+++uZne: set coa " .. theZone.uzCoalition .. " for <" .. theZone.name .. ">", 30)
end
-- DML M;ethod
theZone.uzMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "inc")
if cfxZones.hasProperty(theZone, "uzMethod") then
theZone.uzMethod = cfxZones.getStringFromZoneProperty(theZone, "uzMethod", "inc")
end end
theZone.enterZone = cfxZones.getStringFromZoneProperty(theZone, "enterZone!", "<none>") theZone.enterZone = cfxZones.getStringFromZoneProperty(theZone, "enterZone!", "<none>")
@ -184,16 +202,16 @@ end
-- --
function unitZone.bangState(theZone, newState) function unitZone.bangState(theZone, newState)
cfxZones.pollFlag(theZone.changeZone, "inc", theZone) cfxZones.pollFlag(theZone.changeZone, theZone.uzMethod, theZone)
if newState then if newState then
cfxZones.pollFlag(theZone.enterZone, "inc", theZone) cfxZones.pollFlag(theZone.enterZone, theZone.uzMethod, theZone)
if unitZone.verbose then if unitZone.verbose then
trigger.action.outText("+++uZone: banging enter! on <" .. theZone.enterZone .. "> for " .. theZone.name, 30) trigger.action.outText("+++uZone: banging enter! with <" .. theZone.uzMethod .. "> on <" .. theZone.enterZone .. "> for " .. theZone.name, 30)
end end
else else
cfxZones.pollFlag(theZone.exitZone, "inc", theZone) cfxZones.pollFlag(theZone.exitZone, theZone.uzMethod, theZone)
if unitZone.verbose then if unitZone.verbose then
trigger.action.outText("+++uZone: banging exit! on <" .. theZone.exitZone .. "> for " .. theZone.name, 30) trigger.action.outText("+++uZone: banging exit! with <" .. theZone.uzMethod .. "> on <" .. theZone.exitZone .. "> for " .. theZone.name, 30)
end end
end end
end end

View File

@ -1,7 +1,7 @@
xFlags = {} xFlags = {}
xFlags.version = "1.0.1" xFlags.version = "1.0.1"
xFlags.verbose = false xFlags.verbose = false
xFlags.ups = 1 -- overwritten in get config! xFlags.ups = 1 -- overwritten in get config when configZone is present
xFlags.requiredLibs = { xFlags.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
"cfxZones", -- Zones, of course "cfxZones", -- Zones, of course
@ -12,7 +12,8 @@ xFlags.requiredLibs = {
Version History Version History
1.0.0 - Initial version 1.0.0 - Initial version
1.0.1 - allow flags names for ops as well 1.0.1 - allow flags names for ops as well
modelled on cfxZones.testFlagByMethodForZone() 1.1.0 - Watchflags harmonization
--]]-- --]]--
xFlags.xFlagZones = {} xFlags.xFlagZones = {}
@ -75,9 +76,13 @@ function xFlags.createXFlagsWithZone(theZone)
theZone.matchNum = cfxZones.getNumberFromZoneProperty(theZone, "#hits", 0) theZone.matchNum = cfxZones.getNumberFromZoneProperty(theZone, "#hits", 0)
theZone.lookFor = cfxZones.getStringFromZoneProperty(theZone, "lookFor", "change") -- (<>=[number or reference flag], off, on, yes, no, true, false, change theZone.xTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "xTriggerMethod", "change") -- (<>=[number or reference flag], off, on, yes, no, true, false, change
theZone.lookFor = string.lower(theZone.lookFor) if cfxZones.hasProperty(theZone, "xTrigger") then
theZone.lookFor = dcsCommon.trim(theZone.lookFor) theZone.xTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "xTrigger", "change")
end
theZone.xTriggerMethod = string.lower(theZone.xTriggerMethod)
theZone.xTriggerMethod = dcsCommon.trim(theZone.xTriggerMethod)
if cfxZones.hasProperty(theZone, "xReset?") then if cfxZones.hasProperty(theZone, "xReset?") then
theZone.xReset = cfxZones.getStringFromZoneProperty(theZone, "xReset?", "<none>") theZone.xReset = cfxZones.getStringFromZoneProperty(theZone, "xReset?", "<none>")
@ -104,7 +109,7 @@ function xFlags.evaluateFlags(theZone)
end end
-- now perform comparison flag by flag -- now perform comparison flag by flag
local op = theZone.lookFor local op = theZone.xTriggerMethod
local hits = 0 local hits = 0
local checkSum = "" local checkSum = ""
local firstChar = string.sub(op, 1, 1) local firstChar = string.sub(op, 1, 1)
@ -116,6 +121,9 @@ function xFlags.evaluateFlags(theZone)
rNum = cfxZones.getFlagValue(remainder, theZone) rNum = cfxZones.getFlagValue(remainder, theZone)
end end
-- this mimics cfxZones.testFlagByMethodForZone method (and is
-- that method's genesis), but is different enough not to invoke that
-- method
for i = 1, #theZone.flagNames do for i = 1, #theZone.flagNames do
local lastHits = hits local lastHits = hits
if op == "change" then if op == "change" then
@ -167,7 +175,7 @@ function xFlags.evaluateFlags(theZone)
end end
else else
trigger.action.outText("+++xF: unknown lookFor: <" .. op .. ">", 30) trigger.action.outText("+++xF: unknown xTriggerMethod: <" .. op .. ">", 30)
return 0, "" return 0, ""
end end
if xFlags.verbose and lastHits ~= hits then if xFlags.verbose and lastHits ~= hits then