mirror of
https://github.com/weyne85/DML.git
synced 2025-10-29 16:57:49 +00:00
Version 0.998
xFlags Radio Trigger messenger simplification bang! constants
This commit is contained in:
parent
2b97597e83
commit
284063b829
Binary file not shown.
Binary file not shown.
@ -62,8 +62,6 @@ cfxGroundTroops.deployedTroops = {}
|
||||
-- 1.7.5 - some troop.group hardening with isExist()
|
||||
|
||||
|
||||
|
||||
|
||||
-- an entry into the deployed troop has the following attributes
|
||||
-- - group - the group
|
||||
-- - orders: "guard" - will guard the spot and look for enemies in range
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
cfxSSBClient = {}
|
||||
cfxSSBClient.version = "2.0.2"
|
||||
cfxSSBClient.version = "2.0.3"
|
||||
cfxSSBClient.verbose = false
|
||||
cfxSSBClient.singleUse = false -- set to true to block crashed planes
|
||||
-- NOTE: singleUse (true) requires SSB to disable immediate respawn after kick
|
||||
@ -38,6 +38,8 @@ Version History
|
||||
2.0.1 - stricter verbosity: moved more comments to verbose only
|
||||
2.0.2 - health check code (initial)
|
||||
- added verbosity
|
||||
2.0.3 - getPlayerName nil-trap on cloned player planes guard
|
||||
in onEvent
|
||||
|
||||
WHAT IT IS
|
||||
SSB Client is a small script that forms the client-side counterpart to
|
||||
@ -268,7 +270,12 @@ function cfxSSBClient:onEvent(event)
|
||||
local theUnit = event.initiator -- we know this exists
|
||||
local uName = theUnit:getName()
|
||||
if not uName then return end
|
||||
-- player entered unit
|
||||
-- player entered unit?
|
||||
-- check if this is cloned impostor
|
||||
if not theUnit.getPlayerName then
|
||||
trigger.action.outText("+++SSBC: non-player client " .. uName .. " detected, ignoring.", 30)
|
||||
return
|
||||
end
|
||||
local playerName = theUnit:getPlayerName()
|
||||
if not playerName then
|
||||
return -- NPC plane
|
||||
|
||||
1863
modules/cfxZones.lua
1863
modules/cfxZones.lua
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,15 @@ changer.changers = {}
|
||||
Version History
|
||||
1.0.0 - Initial version
|
||||
|
||||
Transmogrify an incoming signal to an output signal
|
||||
- not
|
||||
- bool
|
||||
- value
|
||||
- rnd
|
||||
- count (? multiple signals, better done with xFlags)
|
||||
- min, max minmax 2,3, cap,
|
||||
|
||||
|
||||
--]]--
|
||||
|
||||
function changer.addChanger(theZone)
|
||||
@ -31,50 +40,70 @@ end
|
||||
--
|
||||
-- read zone
|
||||
--
|
||||
function wiper.createWiperWithZone(theZone)
|
||||
theZone.triggerWiperFlag = cfxZones.getStringFromZoneProperty(theZone, "wipe?", "*<none>")
|
||||
function changer.createChangerWithZone(theZone)
|
||||
theZone.triggerChangerFlag = cfxZones.getStringFromZoneProperty(theZone, "change?", "*<none>")
|
||||
-- if theZone.triggerChangerFlag then
|
||||
theZone.lastTriggerChangeValue = cfxZones.getFlagValue(theZone.triggerChangerFlag, theZone)
|
||||
-- end
|
||||
|
||||
-- triggerWiperMethod
|
||||
theZone.triggerWiperMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
|
||||
if cfxZones.hasProperty(theZone, "triggerWiperMethod") then
|
||||
theZone.triggerWiperMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerWiperMethod", "change")
|
||||
-- triggerChangerMethod
|
||||
theZone.triggerChangerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
|
||||
if cfxZones.hasProperty(theZone, "triggerChangerMethod") then
|
||||
theZone.triggerChangerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerChangerMethod", "change")
|
||||
end
|
||||
|
||||
if theZone.triggerWiperFlag then
|
||||
theZone.lastTriggerWiperValue = cfxZones.getFlagValue(theZone.triggerWiperFlag, theZone)
|
||||
end
|
||||
theZone.inEval = cfxZones.getBoolFromZoneProperty(theZone, "inEval", true) -- yes/no to pre-process, default is yes
|
||||
|
||||
|
||||
local theCat = cfxZones.getStringFromZoneProperty(theZone, "category", "static")
|
||||
if cfxZones.hasProperty(theZone, "wipeCategory") then
|
||||
theCat = cfxZones.getStringFromZoneProperty(theZone, "wipeCategory", "static")
|
||||
end
|
||||
if cfxZones.hasProperty(theZone, "wipeCat") then
|
||||
theCat = cfxZones.getStringFromZoneProperty(theZone, "wipeCat", "static")
|
||||
theZone.changeTo = cfxZones.getStringFromZoneProperty(theZone, "to", "val") -- val, not, bool
|
||||
theZone.changeTo = string.lower(theZone.changeTo)
|
||||
theZone.changeTo = dcsCommon.trim(theZone.changeTo)
|
||||
|
||||
theZone.changeOut = cfxZones.getStringFromZoneProperty(theZone, "out!", "*none")
|
||||
if cfxZones.hasProperty(theZone, "changeOut!") then
|
||||
theZone.changeOut = cfxZones.getStringFromZoneProperty(theZone, "changeOut!", "*none")
|
||||
end
|
||||
|
||||
theZone.wipeCategory = dcsCommon.string2ObjectCat(theCat)
|
||||
|
||||
if cfxZones.hasProperty(theZone, "wipeNamed") then
|
||||
theZone.wipeNamed = cfxZones.getStringFromZoneProperty(theZone, "wipeNamed", "<no name given>")
|
||||
|
||||
if dcsCommon.stringEndsWith(theZone.wipeNamed, "*") then
|
||||
theZone.wipeNamedBeginsWith = true
|
||||
theZone.wipeNamed = dcsCommon.removeEnding(theZone.wipeNamed, "*")
|
||||
end
|
||||
end
|
||||
|
||||
theZone.wipeInventory = cfxZones.getBoolFromZoneProperty(theZone, "wipeInventory", false)
|
||||
|
||||
if wiper.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++wpr: new wiper zone <".. theZone.name ..">", 30)
|
||||
if changer.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++chgr: new changer zone <".. theZone.name ..">", 30)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- MAIN ACTION
|
||||
--
|
||||
function changer.isTriggered(theZone)
|
||||
function changer.process(theZone)
|
||||
-- read the line
|
||||
local inVal = cfxZones.getFlagValue(theZone.triggerChangerFlag, theZone)
|
||||
currVal = inVal
|
||||
if theZone.inEval then
|
||||
currVal = cfxZones.evalFlagMethodImmediate(currVal, theZone.triggerChangerMethod, theZone)
|
||||
end
|
||||
|
||||
if type(currVal) == "boolean" then
|
||||
if currVal then currVal = 1 else currVal = 0 end
|
||||
end
|
||||
|
||||
local res = currVal
|
||||
local op = theZone.changeTo
|
||||
-- process and write outflag
|
||||
if op == "bool" then
|
||||
if currVal == 0 then res = 0 else res = 1 end
|
||||
elseif
|
||||
op == "not" then
|
||||
if currVal == 0 then res = 1 else res = 0 end
|
||||
end
|
||||
-- all others drop through
|
||||
|
||||
-- write out
|
||||
cfxZones.setFlagValueMult(theZone.changeOut, res, theZone)
|
||||
if changer.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++chgr: changed <" .. inVal .. "> via op=(" .. op .. ") to <" .. res .. "> for <" .. theZone.name .. ">", 10)
|
||||
end
|
||||
|
||||
-- remember last value in case we need it
|
||||
theZone.lastTriggerChangeValue = currVal -- we should never need to use this, but leave it in for now. note we save currVal, not res...
|
||||
end
|
||||
|
||||
|
||||
@ -87,8 +116,7 @@ function changer.update()
|
||||
timer.scheduleFunction(changer.update, {}, timer.getTime() + 1/changer.ups)
|
||||
|
||||
for idx, aZone in pairs(changer.changers) do
|
||||
|
||||
|
||||
changer.process(aZone)
|
||||
end
|
||||
end
|
||||
|
||||
@ -114,35 +142,35 @@ function changer.readConfigZone()
|
||||
end
|
||||
end
|
||||
|
||||
function wiper.start()
|
||||
function changer.start()
|
||||
-- lib check
|
||||
if not dcsCommon.libCheck then
|
||||
trigger.action.outText("cfx Wiper requires dcsCommon", 30)
|
||||
trigger.action.outText("cfx changer requires dcsCommon", 30)
|
||||
return false
|
||||
end
|
||||
if not dcsCommon.libCheck("cfx Wiper", wiper.requiredLibs) then
|
||||
if not dcsCommon.libCheck("cfx changer", changer.requiredLibs) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- read config
|
||||
wiper.readConfigZone()
|
||||
changer.readConfigZone()
|
||||
|
||||
-- process cloner Zones
|
||||
local attrZones = cfxZones.getZonesWithAttributeNamed("wipe?")
|
||||
local attrZones = cfxZones.getZonesWithAttributeNamed("change?")
|
||||
for k, aZone in pairs(attrZones) do
|
||||
wiper.createWiperWithZone(aZone) -- process attributes
|
||||
wiper.addWiper(aZone) -- add to list
|
||||
changer.createChangerWithZone(aZone) -- process attributes
|
||||
changer.addChanger(aZone) -- add to list
|
||||
end
|
||||
|
||||
-- start update
|
||||
wiper.update()
|
||||
changer.update()
|
||||
|
||||
trigger.action.outText("cfx Wiper v" .. wiper.version .. " started.", 30)
|
||||
trigger.action.outText("cfx Changer v" .. changer.version .. " started.", 30)
|
||||
return true
|
||||
end
|
||||
|
||||
-- let's go!
|
||||
if not wiper.start() then
|
||||
trigger.action.outText("cfx Wiper aborted: missing libraries", 30)
|
||||
wiper = nil
|
||||
if not changer.start() then
|
||||
trigger.action.outText("cfx changer aborted: missing libraries", 30)
|
||||
changer = nil
|
||||
end
|
||||
@ -69,6 +69,7 @@ dcsCommon.version = "2.5.9"
|
||||
2.5.7 - point2text(p)
|
||||
2.5.8 - string2GroupCat()
|
||||
2.5.9 - string2ObjectCat()
|
||||
2.6.0 - unified uuid, removed uuIdent
|
||||
|
||||
--]]--
|
||||
|
||||
@ -78,7 +79,8 @@ dcsCommon.version = "2.5.9"
|
||||
|
||||
dcsCommon.verbose = false -- set to true to see debug messages. Lots of them
|
||||
dcsCommon.uuidStr = "uuid-"
|
||||
|
||||
dcsCommon.simpleUUID = 76543 -- a number to start. as good as any
|
||||
|
||||
-- globals
|
||||
dcsCommon.cbID = 0 -- callback id for simple callback scheduling
|
||||
dcsCommon.troopCarriers = {"Mi-8MT", "UH-1H", "Mi-24P"} -- Ka-50 and Gazelle can't carry troops
|
||||
@ -1896,16 +1898,16 @@ dcsCommon.version = "2.5.9"
|
||||
end
|
||||
|
||||
|
||||
dcsCommon.simpleUUID = 76543 -- a number to start. as good as any
|
||||
|
||||
function dcsCommon.numberUUID()
|
||||
dcsCommon.simpleUUID = dcsCommon.simpleUUID + 1
|
||||
return dcsCommon.simpleUUID
|
||||
end
|
||||
|
||||
function dcsCommon.uuid(prefix)
|
||||
dcsCommon.uuIdent = dcsCommon.uuIdent + 1
|
||||
--dcsCommon.uuIdent = dcsCommon.uuIdent + 1
|
||||
if not prefix then prefix = dcsCommon.uuidStr end
|
||||
return prefix .. "-" .. dcsCommon.uuIdent
|
||||
return prefix .. "-" .. dcsCommon.numberUUID() -- dcsCommon.uuIdent
|
||||
end
|
||||
|
||||
function dcsCommon.event2text(id)
|
||||
@ -2194,7 +2196,7 @@ end
|
||||
-- init any variables the lib requires internally
|
||||
function dcsCommon.init()
|
||||
cbID = 0
|
||||
dcsCommon.uuIdent = 0
|
||||
--dcsCommon.uuIdent = 0
|
||||
if (dcsCommon.verbose) or true then
|
||||
trigger.action.outText("dcsCommon v" .. dcsCommon.version .. " loaded", 10)
|
||||
end
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
groupTracker = {}
|
||||
groupTracker.version = "1.1.0"
|
||||
groupTracker.version = "1.1.1"
|
||||
groupTracker.verbose = false
|
||||
groupTracker.ups = 1
|
||||
groupTracker.requiredLibs = {
|
||||
@ -14,6 +14,7 @@ groupTracker.trackers = {}
|
||||
1.1.0 - filtering added
|
||||
- array support for trackers
|
||||
- array support for trackers
|
||||
1.1.1 - corrected clone zone reference bug
|
||||
|
||||
--]]--
|
||||
|
||||
@ -199,7 +200,7 @@ function groupTracker.trackGroupsInZone(theZone)
|
||||
else
|
||||
for idy, aGroup in pairs(theGroups) do
|
||||
groupTracker.addGroupToTracker(aGroup, theTracker)
|
||||
if cloneZones.verbose or theZone.verbose then
|
||||
if groupTracker.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++gTrk-TW: added " .. theGroup:getName() .. " to tracker " .. theName, 30)
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
messenger = {}
|
||||
messenger.version = "1.2.1"
|
||||
messenger.version = "1.3.0"
|
||||
messenger.verbose = false
|
||||
messenger.requiredLibs = {
|
||||
"dcsCommon", -- always
|
||||
@ -19,7 +19,8 @@ messenger.messengers = {}
|
||||
- messageOn?
|
||||
- messageOff?
|
||||
1.2.0 - msgTriggerMethod (original Watchflag integration)
|
||||
1.2.1 - qoL: <n> = newline, <z> = zone name, <v> = value
|
||||
1.2.1 - qoL: <n> = newline, <z> = zone name, <v> = value
|
||||
1.3.0 - messenger? saves messageOut? attribute
|
||||
--]]--
|
||||
|
||||
function messenger.addMessenger(theZone)
|
||||
@ -56,6 +57,7 @@ end
|
||||
|
||||
function messenger.createMessengerWithZone(theZone)
|
||||
-- start val - a range
|
||||
|
||||
local aMessage = cfxZones.getStringFromZoneProperty(theZone, "message", "")
|
||||
theZone.message = messenger.preProcMessage(aMessage, theZone)
|
||||
|
||||
@ -76,10 +78,13 @@ function messenger.createMessengerWithZone(theZone)
|
||||
theZone.msgTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "msgTriggerMethod", "change")
|
||||
end
|
||||
|
||||
-- trigger flag f? in? messageOut?
|
||||
-- trigger flag f? in? messageOut?, add messenger?
|
||||
|
||||
if cfxZones.hasProperty(theZone, "f?") then
|
||||
theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, "f?", "none")
|
||||
end
|
||||
theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, "f?", "none")
|
||||
-- may want to add deprecated note later
|
||||
end
|
||||
|
||||
|
||||
-- can also use in? for counting. we always use triggerMessagerFlag
|
||||
if cfxZones.hasProperty(theZone, "in?") then
|
||||
@ -90,9 +95,17 @@ function messenger.createMessengerWithZone(theZone)
|
||||
theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, "messageOut?", "none")
|
||||
end
|
||||
|
||||
if theZone.triggerMessagerFlag then
|
||||
theZone.lastMessageTriggerValue = cfxZones.getFlagValue(theZone.triggerMessagerFlag, theZone)-- trigger.misc.getUserFlag(theZone.triggerMessagerFlag) -- save last value
|
||||
end
|
||||
-- try default only if no other is set
|
||||
if not theZone.triggerMessagerFlag then
|
||||
if not cfxZones.hasProperty(theZone, "messenger?") then
|
||||
trigger.action.outText("*** Note: messenger in <" .. theZone.name .. "> can't be triggered", 30)
|
||||
end
|
||||
theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, "messenger?", "none")
|
||||
end
|
||||
|
||||
-- if theZone.triggerMessagerFlag then
|
||||
theZone.lastMessageTriggerValue = cfxZones.getFlagValue(theZone.triggerMessagerFlag, theZone)-- save last value
|
||||
-- end
|
||||
|
||||
theZone.messageOff = false
|
||||
if cfxZones.hasProperty(theZone, "messageOff?") then
|
||||
@ -238,13 +251,21 @@ function messenger.start()
|
||||
-- read config
|
||||
messenger.readConfigZone()
|
||||
|
||||
-- process cloner Zones
|
||||
-- process messenger Zones
|
||||
-- old style
|
||||
local attrZones = cfxZones.getZonesWithAttributeNamed("messenger")
|
||||
for k, aZone in pairs(attrZones) do
|
||||
messenger.createMessengerWithZone(aZone) -- process attributes
|
||||
messenger.addMessenger(aZone) -- add to list
|
||||
end
|
||||
|
||||
-- new style that saves messageOut? flag by reading flags
|
||||
attrZones = cfxZones.getZonesWithAttributeNamed("messenger?")
|
||||
for k, aZone in pairs(attrZones) do
|
||||
messenger.createMessengerWithZone(aZone) -- process attributes
|
||||
messenger.addMessenger(aZone) -- add to list
|
||||
end
|
||||
|
||||
-- start update
|
||||
messenger.update()
|
||||
|
||||
|
||||
127
modules/module template.lua
Normal file
127
modules/module template.lua
Normal file
@ -0,0 +1,127 @@
|
||||
tmpl = {}
|
||||
tmpl.version = "0.0.0"
|
||||
tmpl.verbose = false
|
||||
tmpl.ups = 1
|
||||
tmpl.requiredLibs = {
|
||||
"dcsCommon", -- always
|
||||
"cfxZones", -- Zones, of course
|
||||
}
|
||||
tmpl.tmpls = {}
|
||||
|
||||
--[[--
|
||||
Version History
|
||||
|
||||
--]]--
|
||||
function tmpl.addTmpl(theZone)
|
||||
table.insert(tmpl.tmpls, theZone)
|
||||
end
|
||||
|
||||
function tmpl.getTmplByName(aName)
|
||||
for idx, aZone in pairs(tmpl.tmpls) do
|
||||
if aName == aZone.name then return aZone end
|
||||
end
|
||||
if tmpl.verbose then
|
||||
trigger.action.outText("+++tmpl: no tmpl with name <" .. aName ..">", 30)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--
|
||||
-- read zone
|
||||
--
|
||||
function tmpl.createTmplWithZone(theZone)
|
||||
-- read main trigger
|
||||
theZone.triggerTmplFlag = cfxZones.getStringFromZoneProperty(theZone, "tmpl?", "*<none>")
|
||||
theZone.lastTriggerTmplValue = cfxZones.getFlagValue(theZone.triggerTmplFlag, theZone)
|
||||
|
||||
-- TriggerMethod: common and specific synonym
|
||||
theZone.tmplTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
|
||||
if cfxZones.hasProperty(theZone, "tmplTriggerMethod") then
|
||||
theZone.tmplTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "tmplTriggerMethod", "change")
|
||||
end
|
||||
|
||||
if tmpl.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++tmpl: new tmpl zone <".. theZone.name ..">", 30)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- MAIN ACTION
|
||||
--
|
||||
function tmpl.process(theZone)
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Update
|
||||
--
|
||||
|
||||
function tmpl.update()
|
||||
-- call me in a second to poll triggers
|
||||
timer.scheduleFunction(tmpl.update, {}, timer.getTime() + 1/tmpl.ups)
|
||||
|
||||
for idx, aZone in pairs(tmpl.tmpls) do
|
||||
-- see if we are triggered
|
||||
if cfxZones.testZoneFlag(aZone, aZone.triggerTmplFlag, aZone.tmplTriggerMethod, "lastTriggerTmplValue") then
|
||||
if tmpl.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++tmpl: triggered on main? for <".. aZone.name ..">", 30)
|
||||
end
|
||||
tmpl.process(aZone)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Config & Start
|
||||
--
|
||||
function tmpl.readConfigZone()
|
||||
local theZone = cfxZones.getZoneByName("tmplConfig")
|
||||
if not theZone then
|
||||
if tmpl.verbose then
|
||||
trigger.action.outText("+++tmpl: NO config zone!", 30)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
tmpl.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
|
||||
|
||||
if tmpl.verbose then
|
||||
trigger.action.outText("+++tmpl: read config", 30)
|
||||
end
|
||||
end
|
||||
|
||||
function tmpl.start()
|
||||
-- lib check
|
||||
if not dcsCommon.libCheck then
|
||||
trigger.action.outText("cfx tmpl requires dcsCommon", 30)
|
||||
return false
|
||||
end
|
||||
if not dcsCommon.libCheck("cfx tmpl", tmpl.requiredLibs) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- read config
|
||||
tmpl.readConfigZone()
|
||||
|
||||
-- process tmpl Zones
|
||||
-- old style
|
||||
local attrZones = cfxZones.getZonesWithAttributeNamed("tmpl")
|
||||
for k, aZone in pairs(attrZones) do
|
||||
tmpl.createTmplWithZone(aZone) -- process attributes
|
||||
tmpl.addTmpl(aZone) -- add to list
|
||||
end
|
||||
|
||||
-- start update
|
||||
tmpl.update()
|
||||
|
||||
trigger.action.outText("cfx tmpl v" .. tmpl.version .. " started.", 30)
|
||||
return true
|
||||
end
|
||||
|
||||
-- let's go!
|
||||
if not tmpl.start() then
|
||||
trigger.action.outText("cfx tmpl aborted: missing libraries", 30)
|
||||
tmpl = nil
|
||||
end
|
||||
147
modules/radioTrigger.lua
Normal file
147
modules/radioTrigger.lua
Normal file
@ -0,0 +1,147 @@
|
||||
radioTrigger = {}
|
||||
radioTrigger.version = "1.0.0"
|
||||
radioTrigger.verbose = false
|
||||
radioTrigger.ups = 1
|
||||
radioTrigger.requiredLibs = {
|
||||
"dcsCommon", -- always
|
||||
"cfxZones", -- Zones, of course
|
||||
}
|
||||
radioTrigger.radioTriggers = {}
|
||||
|
||||
--[[--
|
||||
Version History
|
||||
1.0.0 - initial version
|
||||
|
||||
--]]--
|
||||
function radioTrigger.addRadioTrigger(theZone)
|
||||
table.insert(radioTrigger.radioTriggers, theZone)
|
||||
end
|
||||
|
||||
function radioTrigger.getRadioTriggerByName(aName)
|
||||
for idx, aZone in pairs(radioTrigger.radioTriggers) do
|
||||
if aName == aZone.name then return aZone end
|
||||
end
|
||||
if radioTrigger.verbose then
|
||||
trigger.action.outText("+++radioTrigger: no radioTrigger with name <" .. aName ..">", 30)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--
|
||||
-- read zone
|
||||
--
|
||||
function radioTrigger.createRadioTriggerWithZone(theZone)
|
||||
-- read main trigger
|
||||
theZone.triggerRadioFlag = cfxZones.getStringFromZoneProperty(theZone, "radio?", "*<none>")
|
||||
theZone.lastRadioTriggerValue = cfxZones.getFlagValue(theZone.triggerRadioFlag, theZone)
|
||||
|
||||
-- TriggerMethod: common and specific synonym
|
||||
theZone.radioTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
|
||||
if cfxZones.hasProperty(theZone, "radioTriggerMethod") then
|
||||
theZone.radioTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "radioTriggerMethod", "change")
|
||||
end
|
||||
|
||||
-- out method
|
||||
theZone.rtMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "inc")
|
||||
if cfxZones.hasProperty(theZone, "rtMethod") then
|
||||
theZone.rtMethod = cfxZones.getStringFromZoneProperty(theZone, "rtMethod", "inc")
|
||||
end
|
||||
|
||||
-- out flag
|
||||
theZone.rtOutFlag = cfxZones.getStringFromZoneProperty(theZone, "out!", "*<none>")
|
||||
if cfxZones.hasProperty(theZone, "rtOut!") then
|
||||
theZone.rtOutFlag = cfxZones.getStringFromZoneProperty(theZone, "rtOut!", "*<none>")
|
||||
end
|
||||
|
||||
if radioTrigger.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++rTrg: new radioTrigger zone <".. theZone.name ..">", 30)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- MAIN ACTION
|
||||
--
|
||||
function radioTrigger.process(theZone)
|
||||
-- we are triggered, simply poll the out flag
|
||||
cfxZones.pollFlag(theZone.rtOutFlag, theZone.rtMethod, theZone)
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Update
|
||||
--
|
||||
|
||||
function radioTrigger.update()
|
||||
-- call me in a second to poll triggers
|
||||
timer.scheduleFunction(radioTrigger.update, {}, timer.getTime() + 1/radioTrigger.ups)
|
||||
|
||||
for idx, aZone in pairs(radioTrigger.radioTriggers) do
|
||||
-- see if we are triggered
|
||||
local origSave = aZone.lastRadioTriggerValue
|
||||
if cfxZones.testZoneFlag(aZone, aZone.triggerRadioFlag, aZone.radioTriggerMethod, "lastRadioTriggerValue") then
|
||||
if radioTrigger.verbose or aZone.verbose then
|
||||
trigger.action.outText("+++rTrg: triggered on radio? for <".. aZone.name ..">", 30)
|
||||
end
|
||||
radioTrigger.process(aZone)
|
||||
-- now RESET both trigger and last trigger
|
||||
-- so radio can be used again
|
||||
cfxZones.setFlagValue(aZone.triggerRadioFlag, origSave, aZone)
|
||||
aZone.lastRadioTriggerValue = origSave
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Config & Start
|
||||
--
|
||||
function radioTrigger.readConfigZone()
|
||||
local theZone = cfxZones.getZoneByName("radioTriggerConfig")
|
||||
if not theZone then
|
||||
if radioTrigger.verbose then
|
||||
trigger.action.outText("+++radioTrigger: NO config zone!", 30)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
radioTrigger.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
|
||||
|
||||
if radioTrigger.verbose then
|
||||
trigger.action.outText("+++radioTrigger: read config", 30)
|
||||
end
|
||||
end
|
||||
|
||||
function radioTrigger.start()
|
||||
-- lib check
|
||||
if not dcsCommon.libCheck then
|
||||
trigger.action.outText("cfx radioTrigger requires dcsCommon", 30)
|
||||
return false
|
||||
end
|
||||
if not dcsCommon.libCheck("cfx radioTrigger", radioTrigger.requiredLibs) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- read config
|
||||
radioTrigger.readConfigZone()
|
||||
|
||||
-- process radioTrigger Zones
|
||||
-- old style
|
||||
local attrZones = cfxZones.getZonesWithAttributeNamed("radio?")
|
||||
for k, aZone in pairs(attrZones) do
|
||||
radioTrigger.createRadioTriggerWithZone(aZone) -- process attributes
|
||||
radioTrigger.addRadioTrigger(aZone) -- add to list
|
||||
end
|
||||
|
||||
-- start update
|
||||
radioTrigger.update()
|
||||
|
||||
trigger.action.outText("cfx radioTrigger v" .. radioTrigger.version .. " started.", 30)
|
||||
return true
|
||||
end
|
||||
|
||||
-- let's go!
|
||||
if not radioTrigger.start() then
|
||||
trigger.action.outText("cfx radioTrigger aborted: missing libraries", 30)
|
||||
radioTrigger = nil
|
||||
end
|
||||
@ -1,5 +1,5 @@
|
||||
xFlags = {}
|
||||
xFlags.version = "1.2.0"
|
||||
xFlags.version = "1.2.1"
|
||||
xFlags.verbose = false
|
||||
xFlags.ups = 1 -- overwritten in get config when configZone is present
|
||||
xFlags.requiredLibs = {
|
||||
@ -15,6 +15,13 @@ xFlags.requiredLibs = {
|
||||
1.1.0 - Watchflags harmonization
|
||||
1.2.0 - xDirect flag,
|
||||
- direct array support
|
||||
1.2.1 - verbosity changes
|
||||
- "most" operator
|
||||
- "half or more" operator
|
||||
- fixed reset
|
||||
- xSuccess optimizations
|
||||
- inc, dec, quoted flags
|
||||
- matchNum can carry flag
|
||||
|
||||
--]]--
|
||||
xFlags.xFlagZones = {}
|
||||
@ -25,7 +32,7 @@ end
|
||||
--
|
||||
-- create xFlag
|
||||
--
|
||||
function xFlags.reset()
|
||||
function xFlags.reset(theZone)
|
||||
for i = 1, #theZone.flagNames do
|
||||
-- since the checksum is order dependent,
|
||||
-- we must preserve the order of the array
|
||||
@ -33,7 +40,9 @@ function xFlags.reset()
|
||||
theZone.startFlagValues[i] = cfxZones.getFlagValue(flagName, theZone)
|
||||
theZone.flagResults[i] = false
|
||||
theZone.flagChecksum = theZone.flagChecksum .. "0"
|
||||
trigger.action.outText("+++xF: flag " .. flagName, 30)
|
||||
if xFlags.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++xF: zone <" .. theZone.name .. "> flag " .. flagName, 30)
|
||||
end
|
||||
end
|
||||
theZone.xHasFired = false
|
||||
end
|
||||
@ -59,16 +68,23 @@ function xFlags.createXFlagsWithZone(theZone)
|
||||
theZone.startFlagValues[i] = cfxZones.getFlagValue(flagName, theZone)
|
||||
theZone.flagResults[i] = false
|
||||
theZone.flagChecksum = theZone.flagChecksum .. "0"
|
||||
trigger.action.outText("+++xF: flag " .. flagName, 30)
|
||||
if xFlags.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++xFlag: <" .. theZone.name .. "> monitors flag " .. flagName, 30)
|
||||
end
|
||||
end
|
||||
theZone.xHasFired = false
|
||||
|
||||
theZone.xSuccess = cfxZones.getStringFromZoneProperty(theZone, "xSuccess!", "<none>")
|
||||
if cfxZones.hasProperty(theZone, "xSuccess!") then
|
||||
theZone.xSuccess = cfxZones.getStringFromZoneProperty(theZone, "xSuccess!", "<none>")
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(theZone, "out!") then
|
||||
theZone.xSuccess = cfxZones.getStringFromZoneProperty(theZone, "out!", "*<none>")
|
||||
end
|
||||
|
||||
if not theZone.xSuccess then
|
||||
theZone.xSuccess = "*<none>"
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(theZone, "xChange!") then
|
||||
theZone.xChange = cfxZones.getStringFromZoneProperty(theZone, "xChange!", "*<none>")
|
||||
end
|
||||
@ -80,12 +96,10 @@ function xFlags.createXFlagsWithZone(theZone)
|
||||
theZone.inspect = string.lower(theZone.inspect)
|
||||
theZone.inspect = dcsCommon.trim(theZone.inspect)
|
||||
|
||||
theZone.matchNum = cfxZones.getNumberFromZoneProperty(theZone, "#hits", 0)
|
||||
theZone.matchNum = cfxZones.getStringFromZoneProperty(theZone, "#hits", "1")
|
||||
|
||||
theZone.xTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "xFlagMethod", "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
|
||||
if cfxZones.hasProperty(theZone, "xTrigger") then
|
||||
theZone.xTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "xTrigger", "change")
|
||||
end
|
||||
|
||||
theZone.xTriggerMethod = string.lower(theZone.xTriggerMethod)
|
||||
theZone.xTriggerMethod = dcsCommon.trim(theZone.xTriggerMethod)
|
||||
@ -102,8 +116,31 @@ function xFlags.createXFlagsWithZone(theZone)
|
||||
|
||||
theZone.xOneShot = cfxZones.getBoolFromZoneProperty(theZone, "oneShot", true)
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
function xFlags.evaluateNumOrFlag(theAttribute, theZone)
|
||||
-- on entry, theAttribute contains a string
|
||||
-- if it's a number, we return that, if it's a
|
||||
-- string, we see if it's a quoted flag or
|
||||
-- direct flag. in any way, we fetch and return
|
||||
-- that flag's value
|
||||
local aNum = tonumber(theAttribute)
|
||||
if aNum then return aNum end
|
||||
local remainder = dcsCommon.trim(theAttribute)
|
||||
local esc = string.sub(remainder, 1, 1)
|
||||
local last = string.sub(remainder, -1)
|
||||
|
||||
if esc == "(" and last == ")" and string.len(remainder) > 2 then
|
||||
remainder = string.sub(remainder, 2, -2)
|
||||
remainder = dcsCommon.trim(remainder)
|
||||
end
|
||||
|
||||
if esc == "\"" and last == "\"" and string.len(remainder) > 2 then
|
||||
remainder = string.sub(remainder, 2, -2)
|
||||
remainder = dcsCommon.trim(remainder)
|
||||
end
|
||||
|
||||
rNum = cfxZones.getFlagValue(remainder, theZone)
|
||||
end
|
||||
|
||||
function xFlags.evaluateFlags(theZone)
|
||||
@ -122,10 +159,34 @@ function xFlags.evaluateFlags(theZone)
|
||||
local checkSum = ""
|
||||
local firstChar = string.sub(op, 1, 1)
|
||||
local remainder = string.sub(op, 2)
|
||||
remainder = dcsCommon.trim(remainder) -- remove all leading and trailing spaces
|
||||
local rNum = tonumber(remainder)
|
||||
if not rNum then
|
||||
-- interpret remainder as flag name
|
||||
-- so we can say >*killMax
|
||||
-- so we can say >*killMax or "22" with 22 a flag name
|
||||
|
||||
-- we use remainder as name for flag
|
||||
-- PROCESS ESCAPE SEQUENCES
|
||||
local esc = string.sub(remainder, 1, 1)
|
||||
local last = string.sub(remainder, -1)
|
||||
if esc == "@" then
|
||||
remainder = string.sub(remainder, 2)
|
||||
remainder = dcsCommon.trim(remainder)
|
||||
end
|
||||
|
||||
if esc == "(" and last == ")" and string.len(remainder) > 2 then
|
||||
-- note: iisues with startswith("(") ???
|
||||
remainder = string.sub(remainder, 2, -2)
|
||||
remainder = dcsCommon.trim(remainder)
|
||||
end
|
||||
if esc == "\"" and last == "\"" and string.len(remainder) > 2 then
|
||||
remainder = string.sub(remainder, 2, -2)
|
||||
remainder = dcsCommon.trim(remainder)
|
||||
end
|
||||
if cfxZones.verbose then
|
||||
trigger.action.outText("+++zne: accessing flag <" .. remainder .. ">", 30)
|
||||
end
|
||||
|
||||
rNum = cfxZones.getFlagValue(remainder, theZone)
|
||||
end
|
||||
|
||||
@ -142,14 +203,14 @@ function xFlags.evaluateFlags(theZone)
|
||||
else
|
||||
checkSum = checkSum .. "0"
|
||||
end
|
||||
elseif op == "on" or op == "yes" or op == "true" then
|
||||
elseif op == "on" or op == "yes" or op == "true" or op == "1" then
|
||||
if currVals[i] ~= 0 then
|
||||
hits = hits + 1
|
||||
checkSum = checkSum .. "X"
|
||||
else
|
||||
checkSum = checkSum .. "0"
|
||||
end
|
||||
elseif op == "off" or op == "no" or op == "false"
|
||||
elseif op == "off" or op == "no" or op == "false" or op == "0"
|
||||
then
|
||||
if currVals[i] == 0 then
|
||||
hits = hits + 1
|
||||
@ -158,6 +219,22 @@ function xFlags.evaluateFlags(theZone)
|
||||
checkSum = checkSum .. "0"
|
||||
end
|
||||
|
||||
elseif op == "inc" or op == "+1" then
|
||||
if currVals[i] == theZone.startFlagValues[i] + 1 then
|
||||
hits = hits + 1
|
||||
checkSum = checkSum .. "X"
|
||||
else
|
||||
checkSum = checkSum .. "0"
|
||||
end
|
||||
|
||||
elseif op == "dec" or op == "-1" then
|
||||
if currVals[i] == theZone.startFlagValues[i] - 1 then
|
||||
hits = hits + 1
|
||||
checkSum = checkSum .. "X"
|
||||
else
|
||||
checkSum = checkSum .. "0"
|
||||
end
|
||||
|
||||
elseif firstChar == "<" and rNum then
|
||||
if currVals[i] < rNum then
|
||||
hits = hits + 1
|
||||
@ -183,7 +260,7 @@ function xFlags.evaluateFlags(theZone)
|
||||
end
|
||||
|
||||
else
|
||||
trigger.action.outText("+++xF: unknown xTriggerMethod: <" .. op .. ">", 30)
|
||||
trigger.action.outText("+++xF: unknown xFlagMethod: <" .. op .. ">", 30)
|
||||
return 0, ""
|
||||
end
|
||||
if xFlags.verbose and lastHits ~= hits then
|
||||
@ -197,7 +274,9 @@ function xFlags.evaluateZone(theZone)
|
||||
|
||||
-- short circuit if we are done
|
||||
if theZone.xHasFired and theZone.xOneShot then return end
|
||||
|
||||
-- calculate matchNum
|
||||
local matchNum = xFlags.evaluateNumOrFlag(theZone.matchNum, theZone) -- convert or fetch
|
||||
|
||||
local hits, checkSum = xFlags.evaluateFlags(theZone)
|
||||
-- depending on inspect see what the outcome is
|
||||
-- supported any/or, all/and, moreThan, atLeast, exactly
|
||||
@ -207,21 +286,28 @@ function xFlags.evaluateZone(theZone)
|
||||
evalResult = true
|
||||
elseif (op == "and" or op == "all") and hits == #theZone.flagNames then
|
||||
evalResult = true
|
||||
elseif (op == "morethan" or op == "more than") and hits > theZone.matchNum then
|
||||
elseif (op == "morethan" or op == "more than") and hits > matchNum then
|
||||
evalResult = true
|
||||
elseif (op == "atleast" or op == "at least") and hits >= theZone.matchNum then
|
||||
elseif (op == "atleast" or op == "at least") and hits >= matchNum then
|
||||
evalResult = true
|
||||
elseif op == "exactly" and hits == theZone.matchNum then
|
||||
elseif op == "exactly" and hits == matchNum then
|
||||
evalResult = true
|
||||
elseif (op == "none" or op == "nor") and hits == 0 then
|
||||
evalResult = true
|
||||
elseif (op == "not all" or op == "notall" or op == "nand") and hits < #theZone.flagNames then
|
||||
evalResult = true
|
||||
elseif (op == "most") and hits > (#theZone.flagNames / 2) then
|
||||
evalResult = true
|
||||
elseif (op == "half" or op == "at least half" or op == "half or more") and hits >= (#theZone.flagNames / 2) then
|
||||
-- warning: 'half' means really 'at least half"
|
||||
evalResult = true
|
||||
end
|
||||
|
||||
-- add "most" to more than 50% of flagnum
|
||||
|
||||
-- now check if changed and if result true
|
||||
if checkSum ~= theZone.flagChecksum then
|
||||
if xFlags.verbose then
|
||||
if xFlags.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++xFlag: change detected for " .. theZone.name .. ": " .. theZone.flagChecksum .. "-->" ..checkSum, 30)
|
||||
end
|
||||
|
||||
@ -232,6 +318,10 @@ function xFlags.evaluateZone(theZone)
|
||||
end
|
||||
end
|
||||
theZone.flagChecksum = checkSum
|
||||
else
|
||||
if xFlags.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++xFlag: no change, checksum is |" .. checkSum .. "| for <" .. theZone.name .. ">", 10)
|
||||
end
|
||||
end
|
||||
|
||||
-- now directly set the value of evalResult (0 = false, 1 = true)
|
||||
@ -246,8 +336,8 @@ function xFlags.evaluateZone(theZone)
|
||||
|
||||
-- now see if we bang the output according to method
|
||||
if evalResult then
|
||||
if xFlags.verbose then
|
||||
trigger.action.outText("+++xFlag: success bang! on " .. theZone.xSuccess .. " for " .. theZone.name, 30)
|
||||
if xFlags.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++xFlag: success bang! on <" .. theZone.xSuccess .. "> for <" .. theZone.name .. ">", 30)
|
||||
end
|
||||
cfxZones.pollFlag(theZone.xSuccess, theZone.xMethod, theZone)
|
||||
theZone.xHasFired = true
|
||||
@ -269,8 +359,8 @@ function xFlags.update()
|
||||
local currVal = cfxZones.getFlagValue(theZone.xReset, theZone)
|
||||
if currVal ~= theZone.xLastReset then
|
||||
theZone.xLastReset = currVal
|
||||
if xFlags.verbose then
|
||||
trigger.action.outText("+++xF: reset command for " .. theZone.name, 30)
|
||||
if xFlags.verbose or theZone.verbose then
|
||||
trigger.action.outText("+++xFlag: reset command for " .. theZone.name, 30)
|
||||
end
|
||||
xFlags.reset(theZone)
|
||||
end
|
||||
@ -285,7 +375,7 @@ function xFlags.readConfigZone()
|
||||
local theZone = cfxZones.getZoneByName("xFlagsConfig")
|
||||
if not theZone then
|
||||
if xFlags.verbose then
|
||||
trigger.action.outText("***xFlg: NO config zone!", 30)
|
||||
trigger.action.outText("***xFlag: NO config zone!", 30)
|
||||
end
|
||||
return
|
||||
end
|
||||
@ -342,4 +432,9 @@ end
|
||||
if not xFlags.start() then
|
||||
trigger.action.outText("cf/x xFlags aborted: missing libraries", 30)
|
||||
xFlags = nil
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Additional features:
|
||||
- make #hits compatible to flags and numbers
|
||||
--]]--
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
tutorial & demo missions/demo - radio go go.miz
Normal file
BIN
tutorial & demo missions/demo - radio go go.miz
Normal file
Binary file not shown.
Binary file not shown.
BIN
tutorial & demo missions/demo - xFlags - Field Day.miz
Normal file
BIN
tutorial & demo missions/demo - xFlags - Field Day.miz
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user