Version 1.4.0

OOP dmlZones
radioMenu: ack and val
This commit is contained in:
Christian Franz 2023-07-27 13:48:45 +02:00
parent a231673292
commit 3117bfd80c
11 changed files with 1168 additions and 505 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
cfxSmokeZone = {} cfxSmokeZone = {}
cfxSmokeZone.version = "1.1.3" cfxSmokeZone.version = "1.2.0"
cfxSmokeZone.requiredLibs = { cfxSmokeZone.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
"cfxZones", -- Zones, of course "cfxZones", -- Zones, of course
@ -19,13 +19,14 @@ cfxSmokeZone.requiredLibs = {
1.1.1 - stopSmoke? input 1.1.1 - stopSmoke? input
1.1.2 - 'agl', 'alt' synonymous for altitude to keep in line with fireFX 1.1.2 - 'agl', 'alt' synonymous for altitude to keep in line with fireFX
1.1.3 - corrected smokeTriggerMethod in zone definition 1.1.3 - corrected smokeTriggerMethod in zone definition
1.2.0 - first OOP guinea pig.
--]]-- --]]--
cfxSmokeZone.smokeZones = {} cfxSmokeZone.smokeZones = {}
cfxSmokeZone.updateDelay = 5 * 60 -- every 5 minutes cfxSmokeZone.updateDelay = 5 * 60 -- every 5 minutes
function cfxSmokeZone.processSmokeZone(aZone) function cfxSmokeZone.processSmokeZone(aZone)
local rawVal = cfxZones.getStringFromZoneProperty(aZone, "smoke", "green") local rawVal = aZone:getStringFromZoneProperty("smoke", "green")
rawVal = rawVal:lower() rawVal = rawVal:lower()
local theColor = 0 local theColor = 0
if rawVal == "red" or rawVal == "1" then theColor = 1 end if rawVal == "red" or rawVal == "1" then theColor = 1 end
@ -37,38 +38,38 @@ function cfxSmokeZone.processSmokeZone(aZone)
end end
aZone.smokeColor = theColor aZone.smokeColor = theColor
aZone.smokeAlt = cfxZones.getNumberFromZoneProperty(aZone, "altitude", 1) aZone.smokeAlt = aZone:getNumberFromZoneProperty("altitude", 1)
if cfxZones.hasProperty(aZone, "alt") then if aZone:hasProperty("alt") then
aZone.smokeAlt = cfxZones.getNumberFromZoneProperty(aZone, "alt", 1) aZone.smokeAlt = aZone:getNumberFromZoneProperty("alt", 1)
elseif cfxZones.hasProperty(aZone, "agl") then elseif aZone:hasProperty("agl") then
aZone.smokeAlt = cfxZones.getNumberFromZoneProperty(aZone, "agl", 1) aZone.smokeAlt = aZone:getNumberFromZoneProperty("agl", 1)
end end
-- paused -- paused
aZone.paused = cfxZones.getBoolFromZoneProperty(aZone, "paused", false) aZone.paused = aZone:getBoolFromZoneProperty("paused", false)
-- f? query flags -- f? query flags
if cfxZones.hasProperty(aZone, "f?") then if aZone:hasProperty("f?") then
aZone.onFlag = cfxZones.getStringFromZoneProperty(aZone, "f?", "*<none>") aZone.onFlag = aZone:getStringFromZoneProperty("f?", "*<none>")
elseif cfxZones.hasProperty(aZone, "startSmoke?") then elseif aZone:hasProperty("startSmoke?") then
aZone.onFlag = cfxZones.getStringFromZoneProperty(aZone, "startSmoke?", "none") aZone.onFlag = aZone:getStringFromZoneProperty("startSmoke?", "none")
end end
if aZone.onFlag then if aZone.onFlag then
aZone.onFlagVal = cfxZones.getFlagValue(aZone.onFlag, aZone) -- save last value aZone.onFlagVal = aZone:getFlagValue(aZone.onFlag) -- save last value
end end
if cfxZones.hasProperty(aZone, "stopSmoke?") then if aZone:hasProperty("stopSmoke?") then
aZone.smkStopFlag = cfxZones.getStringFromZoneProperty(aZone, "stopSmoke?", "<none>") aZone.smkStopFlag = aZone:getStringFromZoneProperty("stopSmoke?", "<none>")
aZone.smkLastStopFlag = cfxZones.getFlagValue(aZone.smkStopFlag, aZone) aZone.smkLastStopFlag = aZone:getFlagValue(aZone.smkStopFlag)
end end
-- watchflags: -- watchflags:
-- triggerMethod -- triggerMethod
aZone.smokeTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, "triggerMethod", "change") aZone.smokeTriggerMethod = aZone:getStringFromZoneProperty( "triggerMethod", "change")
if cfxZones.hasProperty(aZone, "smokeTriggerMethod") then if aZone:hasProperty("smokeTriggerMethod") then
aZone.smokeTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, "smokeTriggerMethod", "change") aZone.smokeTriggerMethod = aZone:getStringFromZoneProperty( "smokeTriggerMethod", "change")
end end
end end

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
cloneZones = {} cloneZones = {}
cloneZones.version = "1.7.3" cloneZones.version = "1.8.0"
cloneZones.verbose = false cloneZones.verbose = false
cloneZones.requiredLibs = { cloneZones.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
@ -95,6 +95,9 @@ cloneZones.respawnOnGroupID = true
- forcedRespawn passes zone instead of verbose - forcedRespawn passes zone instead of verbose
1.7.2 - onPerimeter attribute 1.7.2 - onPerimeter attribute
1.7.3 - declutter option 1.7.3 - declutter option
1.8.0 - OOP cfxZones
- removed "empty+1" as planned
- upgraded config zone parsing
--]]-- --]]--
@ -155,7 +158,7 @@ end
-- --
function cloneZones.partOfGroupDataInZone(theZone, theUnits) function cloneZones.partOfGroupDataInZone(theZone, theUnits)
local zP = cfxZones.getPoint(theZone) local zP = cfxZones.getPoint(theZone)
zP = cfxZones.getDCSOrigin(theZone) -- don't use getPoint now. zP = theZone:getDCSOrigin() -- don't use getPoint now.
zP.y = 0 zP.y = 0
for idx, aUnit in pairs(theUnits) do for idx, aUnit in pairs(theUnits) do
@ -192,7 +195,7 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
theZone.myUniqueCounter = cloneZones.lclUniqueCounter -- init local counter theZone.myUniqueCounter = cloneZones.lclUniqueCounter -- init local counter
local localZones = cloneZones.allGroupsInZoneByData(theZone) local localZones = cloneZones.allGroupsInZoneByData(theZone)
local localObjects = cfxZones.allStaticsInZone(theZone, true) -- true = use DCS origin, not moved zone local localObjects = theZone:allStaticsInZone(true) -- true = use DCS origin, not moved zone
if theZone.verbose then if theZone.verbose then
trigger.action.outText("+++clnZ: building cloner <" .. theZone.name .. "> TMPL: >>>", 30) trigger.action.outText("+++clnZ: building cloner <" .. theZone.name .. "> TMPL: >>>", 30)
for idx, theGroup in pairs (localZones) do for idx, theGroup in pairs (localZones) do
@ -208,7 +211,7 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
theZone.myStatics = {} theZone.myStatics = {}
-- update: getPoint is bad if it's a moving zone. -- update: getPoint is bad if it's a moving zone.
-- use getDCSOrigin instead -- use getDCSOrigin instead
theZone.origin = cfxZones.getDCSOrigin(theZone) theZone.origin = theZone:getDCSOrigin()
-- source tells us which template to use. it can be the following: -- source tells us which template to use. it can be the following:
-- nothing (no attribute) - then we use whatever groups are in zone to -- nothing (no attribute) - then we use whatever groups are in zone to
@ -216,8 +219,8 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
-- name of another spawner that provides the template -- name of another spawner that provides the template
-- we can't simply use a group name as we lack the reference -- we can't simply use a group name as we lack the reference
-- location for delta -- location for delta
if cfxZones.hasProperty(theZone, "source") then if theZone:hasProperty("source") then
theZone.source = cfxZones.getStringFromZoneProperty(theZone, "source", "<none>") theZone.source = theZone:getStringFromZoneProperty("source", "<none>")
if theZone.source == "<none>" then theZone.source = nil end if theZone.source == "<none>" then theZone.source = nil end
end end
@ -259,95 +262,96 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
end end
-- declutter -- declutter
theZone.declutter = cfxZones.getBoolFromZoneProperty(theZone, "declutter", false) theZone.declutter = theZone:getBoolFromZoneProperty("declutter", false)
-- watchflags -- watchflags
theZone.cloneTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change") theZone.cloneTriggerMethod = theZone:getStringFromZoneProperty("triggerMethod", "change")
if cfxZones.hasProperty(theZone, "cloneTriggerMethod") then if theZone:hasProperty("cloneTriggerMethod") then
theZone.cloneTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "cloneTriggerMethod", "change") theZone.cloneTriggerMethod = theZone:getStringFromZoneProperty("cloneTriggerMethod", "change")
end end
-- f? and spawn? and other synonyms map to the same -- f? and spawn? and other synonyms map to the same
if cfxZones.hasProperty(theZone, "f?") then if theZone:hasProperty("f?") then
theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, "f?", "none") theZone.spawnFlag = theZone:getStringFromZoneProperty("f?", "none")
end end
if cfxZones.hasProperty(theZone, "in?") then if theZone:hasProperty("in?") then
theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, "in?", "none") theZone.spawnFlag = theZone:getStringFromZoneProperty("in?", "none")
end end
if cfxZones.hasProperty(theZone, "spawn?") then if theZone:hasProperty("spawn?") then
theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, "spawn?", "none") theZone.spawnFlag = theZone:getStringFromZoneProperty("spawn?", "none")
end end
if cfxZones.hasProperty(theZone, "clone?") then if theZone:hasProperty("clone?") then
theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, "clone?", "none") theZone.spawnFlag = theZone:getStringFromZoneProperty("clone?", "none")
end end
if theZone.spawnFlag then if theZone.spawnFlag then
theZone.lastSpawnValue = cfxZones.getFlagValue(theZone.spawnFlag, theZone) theZone.lastSpawnValue = theZone:getFlagValue(theZone.spawnFlag)
end end
-- deSpawn? -- deSpawn?
if cfxZones.hasProperty(theZone, "deSpawn?") then if theZone:hasProperty("deSpawn?") then
theZone.deSpawnFlag = cfxZones.getStringFromZoneProperty(theZone, "deSpawn?", "none") theZone.deSpawnFlag = theZone:getStringFromZoneProperty( "deSpawn?", "none")
end end
if cfxZones.hasProperty(theZone, "deClone?") then if theZone:hasProperty("deClone?") then
theZone.deSpawnFlag = cfxZones.getStringFromZoneProperty(theZone, "deClone?", "none") theZone.deSpawnFlag = theZone:getStringFromZoneProperty( "deClone?", "none")
end end
if cfxZones.hasProperty(theZone, "wipe?") then if theZone:hasProperty("wipe?") then
theZone.deSpawnFlag = cfxZones.getStringFromZoneProperty(theZone, "wipe?", "none") theZone.deSpawnFlag = theZone:getStringFromZoneProperty("wipe?", "none")
end end
if theZone.deSpawnFlag then if theZone.deSpawnFlag then
theZone.lastDeSpawnValue = cfxZones.getFlagValue(theZone.deSpawnFlag, theZone) theZone.lastDeSpawnValue = theZone:getFlagValue(theZone.deSpawnFlag)
end end
theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, "onStart", false) theZone.onStart = theZone:getBoolFromZoneProperty("onStart", false)
theZone.moveRoute = cfxZones.getBoolFromZoneProperty(theZone, "moveRoute", false) theZone.moveRoute = theZone:getBoolFromZoneProperty("moveRoute", false)
theZone.preWipe = cfxZones.getBoolFromZoneProperty(theZone, "preWipe", false) theZone.preWipe = theZone:getBoolFromZoneProperty("preWipe", false)
-- to be deprecated -- to be deprecated
if cfxZones.hasProperty(theZone, "empty+1") then --[[--
theZone.emptyFlag = cfxZones.getStringFromZoneProperty(theZone, "empty+1", "<None>") -- note string on number default if theZone:hasProperty("empty+1") then
theZone.emptyFlag = theZone:getStringFromZoneProperty("empty+1", "<None>") -- note string on number default
end
--]]--
if theZone:hasProperty("empty!") then
theZone.emptyBangFlag = theZone:getStringFromZoneProperty("empty!", "<None>") -- note string on number default
end end
if cfxZones.hasProperty(theZone, "empty!") then theZone.cloneMethod = theZone:getStringFromZoneProperty("cloneMethod", "inc")
theZone.emptyBangFlag = cfxZones.getStringFromZoneProperty(theZone, "empty!", "<None>") -- note string on number default if theZone:hasProperty("method") then
theZone.cloneMethod = theZone:getStringFromZoneProperty("method", "inc") -- note string on number default
end end
theZone.cloneMethod = cfxZones.getStringFromZoneProperty(theZone, "cloneMethod", "inc") if theZone:hasProperty("masterOwner") then
if cfxZones.hasProperty(theZone, "method") then theZone.masterOwner = theZone:getStringFromZoneProperty( "masterOwner", "*")
theZone.cloneMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "inc") -- note string on number default
end
if cfxZones.hasProperty(theZone, "masterOwner") then
theZone.masterOwner = cfxZones.getStringFromZoneProperty(theZone, "masterOwner", "*")
theZone.masterOwner = dcsCommon.trim(theZone.masterOwner) theZone.masterOwner = dcsCommon.trim(theZone.masterOwner)
if theZone.masterOwner == "*" then if theZone.masterOwner == "*" then
theZone.masterOwner = theZone.name theZone.masterOwner = theZone.name
if theZone.verbose then if theZone.verbose then
trigger.action.outText("+++clnZ: masterOwner for <" .. theZone.name .. "> successfully to to itself, currently owned by faction <" .. theZone.owner .. ">", 30) trigger.action.outText("+++clnZ: masterOwner for <" .. theZone.name .. "> set successfully to to itself, currently owned by faction <" .. theZone.owner .. ">", 30)
end end
end end
end end
theZone.turn = cfxZones.getNumberFromZoneProperty(theZone, "turn", 0) theZone.turn = theZone:getNumberFromZoneProperty("turn", 0)
-- interface to groupTracker -- interface to groupTracker
if cfxZones.hasProperty(theZone, "trackWith:") then if theZone:hasProperty("trackWith:") then
theZone.trackWith = cfxZones.getStringFromZoneProperty(theZone, "trackWith:", "<None>") theZone.trackWith = theZone:getStringFromZoneProperty( "trackWith:", "<None>")
--trigger.action.outText("trackwith: " .. theZone.trackWith, 30)
end end
-- interface to delicates -- interface to delicates
if cfxZones.hasProperty(theZone, "useDelicates") then if theZone:hasProperty("useDelicates") then
theZone.delicateName = dcsCommon.trim(cfxZones.getStringFromZoneProperty(theZone, "useDelicates", "<none>")) theZone.delicateName = dcsCommon.trim(theZone:getStringFromZoneProperty("useDelicates", "<none>"))
if theZone.delicateName == "*" then theZone.delicateName = theZone.name end if theZone.delicateName == "*" then theZone.delicateName = theZone.name end
if theZone.verbose then if theZone.verbose then
trigger.action.outText("+++clnZ: cloner <" .. theZone.name .."> hands off delicates to <" .. theZone.delicateName .. ">", 30) trigger.action.outText("+++clnZ: cloner <" .. theZone.name .."> hands off delicates to <" .. theZone.delicateName .. ">", 30)
@ -355,29 +359,29 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
end end
-- randomized locations on spawn -- randomized locations on spawn
theZone.rndLoc = cfxZones.getBoolFromZoneProperty(theZone, "randomizedLoc", false) theZone.rndLoc = theZone:getBoolFromZoneProperty("randomizedLoc", false)
if cfxZones.hasProperty(theZone, "rndLoc") then if theZone:hasProperty("rndLoc") then
theZone.rndLoc = cfxZones.getBoolFromZoneProperty(theZone, "rndLoc", false) theZone.rndLoc = theZone:getBoolFromZoneProperty("rndLoc", false)
end end
theZone.centerOnly = cfxZones.getBoolFromZoneProperty(theZone, "centerOnly", false) theZone.centerOnly = theZone:getBoolFromZoneProperty("centerOnly", false)
if cfxZones.hasProperty(theZone, "wholeGroups") then if theZone:hasProperty("wholeGroups") then
theZone.centerOnly = cfxZones.getBoolFromZoneProperty(theZone, "wholeGroups", false) theZone.centerOnly = theZone:getBoolFromZoneProperty( "wholeGroups", false)
end end
theZone.rndHeading = cfxZones.getBoolFromZoneProperty(theZone, "rndHeading", false) theZone.rndHeading = theZone:getBoolFromZoneProperty("rndHeading", false)
theZone.onRoad = cfxZones.getBoolFromZoneProperty(theZone, "onRoad", false) theZone.onRoad = theZone:getBoolFromZoneProperty("onRoad", false)
theZone.onPerimeter = cfxZones.getBoolFromZoneProperty(theZone, "onPerimeter", false) theZone.onPerimeter = theZone:getBoolFromZoneProperty("onPerimeter", false)
-- check for name scheme and / or identical -- check for name scheme and / or identical
if cfxZones.hasProperty(theZone, "identical") then if theZone:hasProperty("identical") then
theZone.identical = cfxZones.getBoolFromZoneProperty(theZone, "identical", false) theZone.identical = theZone:getBoolFromZoneProperty("identical", false)
if theZone.identical == false then theZone.identical = nil end if theZone.identical == false then theZone.identical = nil end
end end
if cfxZones.hasProperty(theZone, "nameScheme") then if theZone:hasProperty("nameScheme") then
theZone.nameScheme = cfxZones.getStringFromZoneProperty(theZone, "nameScheme", "<o>-<uid>") -- default to [<original name> "-" <uuid>] theZone.nameScheme = theZone:getStringFromZoneProperty( "nameScheme", "<o>-<uid>") -- default to [<original name> "-" <uuid>]
end end
if theZone.identical and theZone.nameScheme then if theZone.identical and theZone.nameScheme then
@ -981,7 +985,6 @@ function cloneZones.validateSpawnUnitData(aUnit, theZone, unitNames)
end end
end end
-- check against static objects. -- check against static objects.
local theStatic = StaticObject.getByName(aUnit.name) local theStatic = StaticObject.getByName(aUnit.name)
if theStatic and StaticObject.isExist(theStatic) then if theStatic and StaticObject.isExist(theStatic) then
@ -1073,9 +1076,9 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
trigger.action.outText("+++clnZ: spawning with template <" .. theZone.name .. "> for spawner <" .. spawnZone.name .. ">", 30) trigger.action.outText("+++clnZ: spawning with template <" .. theZone.name .. "> for spawner <" .. spawnZone.name .. ">", 30)
end end
-- theZone is the cloner with the TEMPLATE (source) -- theZone is the cloner with the TEMPLATE (source)
-- spawnZone is the spawner with SETTINGS and DESTINATION (target location) -- spawnZone is the spawner with SETTINGS and DESTINATION (target location) where the clones are poofed into existence
local newCenter = cfxZones.getPoint(spawnZone) -- includes zone following updates local newCenter = spawnZone:getPoint() -- includes zone following updates
local oCenter = cfxZones.getDCSOrigin(theZone) -- get original coords on map for cloning offsets local oCenter = theZone:getDCSOrigin() -- get original coords on map for cloning offsets
-- calculate zoneDelta, is added to all vectors -- calculate zoneDelta, is added to all vectors
local zoneDelta = dcsCommon.vSub(newCenter, theZone.origin) -- oCenter) --theZone.origin) local zoneDelta = dcsCommon.vSub(newCenter, theZone.origin) -- oCenter) --theZone.origin)
@ -1086,7 +1089,7 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
local theUnit = spawnZone.linkedUnit local theUnit = spawnZone.linkedUnit
local currHeading = dcsCommon.getUnitHeading(theUnit) local currHeading = dcsCommon.getUnitHeading(theUnit)
dHeading = currHeading - spawnZone.uHdg dHeading = currHeading - spawnZone.uHdg
rotCenter = cfxZones.getPoint(spawnZone) rotCenter = spawnZone:getPoint()
end end
local spawnedGroups = {} local spawnedGroups = {}
@ -1114,10 +1117,6 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
local theCat = cfxMX.catText2ID(cat) local theCat = cfxMX.catText2ID(cat)
rawData.CZtheCat = theCat -- save category rawData.CZtheCat = theCat -- save category
-- update their position if not spawning to exact same location
if cloneZones.verbose or theZone.verbose or spawnZone.verbose then
--trigger.action.outText("+++clnZ: tmpl delta x = <" .. math.floor(zoneDelta.x) .. ">, y = <" .. math.floor(zoneDelta.z) .. "> for tmpl <" .. theZone.name .. "> to cloner <" .. spawnZone.name .. ">", 30)
end
-- update routes when not spawning same location -- update routes when not spawning same location
cloneZones.updateLocationsInGroupData(rawData, zoneDelta, spawnZone.moveRoute, rotCenter, spawnZone.turn / 57.2958 + cloneZones.updateLocationsInGroupData(rawData, zoneDelta, spawnZone.moveRoute, rotCenter, spawnZone.turn / 57.2958 +
dHeading) dHeading)
@ -1129,18 +1128,18 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
local loc, dx, dy local loc, dx, dy
if spawnZone.onPerimeter then if spawnZone.onPerimeter then
loc, dx, dy = cfxZones.createRandomPointOnZoneBoundary(spawnZone) loc, dx, dy = spawnZone:createRandomPointOnZoneBoundary()
else else
loc, dx, dy = cfxZones.createRandomPointInZone(spawnZone) -- also supports polygonal zones loc, dx, dy = spawnZone:createRandomPointInZone() -- also supports polygonal zones
end end
for idx, aUnit in pairs(units) do for idx, aUnit in pairs(units) do
if not spawnZone.centerOnly then if not spawnZone.centerOnly then
-- *every unit's displacement is randomized -- *every unit's displacement is randomized
if spawnZone.onPerimeter then if spawnZone.onPerimeter then
loc, dx, dy = cfxZones.createRandomPointOnZoneBoundary(spawnZone) loc, dx, dy = spawnZone:createRandomPointOnZoneBoundary()
else else
loc, dx, dy = cfxZones.createRandomPointInZone(spawnZone) loc, dx, dy = spawnZone:createRandomPointInZone()
end end
aUnit.x = loc.x aUnit.x = loc.x
aUnit.y = loc.z aUnit.y = loc.z
@ -1382,9 +1381,9 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
local loc, dx, dy local loc, dx, dy
if spawnZone.onPerimeter then if spawnZone.onPerimeter then
loc, dx, dy = cfxZones.createRandomPointOnZoneBoundary(spawnZone) loc, dx, dy = spawnZone:createRandomPointOnZoneBoundary()
else else
loc, dx, dy = cfxZones.createRandomPointInZone(spawnZone) -- also supports polygonal zones loc, dx, dy = spawnZone:createRandomPointInZone() -- also supports polygonal zones
end end
rawData.x = rawData.x + dx -- might want to use loc rawData.x = rawData.x + dx -- might want to use loc
rawData.y = rawData.y + dy -- directly rawData.y = rawData.y + dy -- directly
@ -1550,7 +1549,7 @@ function cloneZones.spawnWithCloner(theZone)
-- declutter? -- declutter?
if theZone.declutter then if theZone.declutter then
cfxZones.declutterZone(theZone) theZone:declutterZone()
if theZone.verbose then if theZone.verbose then
trigger.action.outText("+++clnZ: cloner <" .. theZone.name .. "> declutter complete.", 30) trigger.action.outText("+++clnZ: cloner <" .. theZone.name .. "> declutter complete.", 30)
end end
@ -1641,7 +1640,7 @@ function cloneZones.update()
for idx, aZone in pairs(cloneZones.cloners) do for idx, aZone in pairs(cloneZones.cloners) do
-- see if deSpawn was pulled. Must run before spawn -- see if deSpawn was pulled. Must run before spawn
if aZone.deSpawnFlag then if aZone.deSpawnFlag then
local currTriggerVal = cfxZones.getFlagValue(aZone.deSpawnFlag, aZone) -- trigger.misc.getUserFlag(aZone.deSpawnFlag) local currTriggerVal = aZone:getFlagValue(aZone.deSpawnFlag) -- trigger.misc.getUserFlag(aZone.deSpawnFlag)
if currTriggerVal ~= aZone.lastDeSpawnValue then if currTriggerVal ~= aZone.lastDeSpawnValue then
if cloneZones.verbose or aZone.verbose then if cloneZones.verbose or aZone.verbose then
trigger.action.outText("+++clnZ: DEspawn triggered for <" .. aZone.name .. ">", 30) trigger.action.outText("+++clnZ: DEspawn triggered for <" .. aZone.name .. ">", 30)
@ -1652,7 +1651,7 @@ function cloneZones.update()
end end
-- see if we got spawn? command -- see if we got spawn? command
if cfxZones.testZoneFlag(aZone, aZone.spawnFlag, aZone.cloneTriggerMethod, "lastSpawnValue") then if aZone:testZoneFlag(aZone.spawnFlag, aZone.cloneTriggerMethod, "lastSpawnValue") then
if cloneZones.verbose then if cloneZones.verbose then
trigger.action.outText("+++clnZ: spawn triggered for <" .. aZone.name .. ">", 30) trigger.action.outText("+++clnZ: spawn triggered for <" .. aZone.name .. ">", 30)
end end
@ -1663,13 +1662,15 @@ function cloneZones.update()
local isEmpty = cloneZones.countLiveUnits(aZone) < 1 and aZone.hasClones local isEmpty = cloneZones.countLiveUnits(aZone) < 1 and aZone.hasClones
if isEmpty then if isEmpty then
-- see if we need to bang a flag -- see if we need to bang a flag
--[[--
if aZone.emptyFlag then if aZone.emptyFlag then
--cloneZones.pollFlag(aZone.emptyFlag) --cloneZones.pollFlag(aZone.emptyFlag)
cfxZones.pollFlag(aZone.emptyFlag, 'inc', aZone) cfxZones.pollFlag(aZone.emptyFlag, 'inc', aZone)
end end
--]]--
if aZone.emptyBangFlag then if aZone.emptyBangFlag then
cfxZones.pollFlag(aZone.emptyBangFlag, aZone.cloneMethod, aZone) aZone:pollFlag(aZone.emptyBangFlag, aZone.cloneMethod)
if cloneZones.verbose then if cloneZones.verbose then
trigger.action.outText("+++clnZ: bang! on " .. aZone.emptyBangFlag, 30) trigger.action.outText("+++clnZ: bang! on " .. aZone.emptyBangFlag, 30)
end end
@ -1950,22 +1951,22 @@ function cloneZones.readConfigZone()
if cloneZones.verbose then if cloneZones.verbose then
trigger.action.outText("+++clnZ: NO config zone!", 30) trigger.action.outText("+++clnZ: NO config zone!", 30)
end end
return theZone = cfxZones.createSimpleZone("cloneZonesConfig")
end end
if cfxZones.hasProperty(theZone, "uniqueCount") then if theZone:hasProperty("uniqueCount") then
cloneZones.uniqueCounter = cfxZones.getNumberFromZoneProperty(theZone, "uniqueCount", cloneZone.uniqueCounter) cloneZones.uniqueCounter = theZone:getNumberFromZoneProperty("uniqueCount", cloneZone.uniqueCounter)
end end
if cfxZones.hasProperty(theZone, "localCount") then if theZone:hasProperty("localCount") then
cloneZones.lclUniqueCounter = cfxZones.getNumberFromZoneProperty(theZone, "localCount", cloneZone.lclUniqueCounter) cloneZones.lclUniqueCounter = theZone:getNumberFromZoneProperty("localCount", cloneZone.lclUniqueCounter)
end end
if cfxZones.hasProperty(theZone, "globalCount") then if theZone:hasProperty("globalCount") then
cloneZones.globalCounter = cfxZones.getNumberFromZoneProperty(theZone, "globalCount", cloneZone.globalCounter) cloneZones.globalCounter = theZone:getNumberFromZoneProperty("globalCount", cloneZone.globalCounter)
end end
cloneZones.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false) cloneZones.verbose = theZone:getBoolFromZoneProperty("verbose", false)
if cloneZones.verbose then if cloneZones.verbose then
trigger.action.outText("+++clnZ: read config", 30) trigger.action.outText("+++clnZ: read config", 30)

View File

@ -1,5 +1,5 @@
dcsCommon = {} dcsCommon = {}
dcsCommon.version = "2.8.10" dcsCommon.version = "2.9.0"
--[[-- VERSION HISTORY --[[-- VERSION HISTORY
2.2.6 - compassPositionOfARelativeToB 2.2.6 - compassPositionOfARelativeToB
- clockPositionOfARelativeToB - clockPositionOfARelativeToB
@ -163,6 +163,10 @@ dcsCommon.version = "2.8.10"
- new getPlayerUnit() - new getPlayerUnit()
- new getMapName() - new getMapName()
- new getMagDeclForPoint() - new getMagDeclForPoint()
2.9.0 - createPoint() moved from cfxZones
- copyPoint() moved from cfxZones
- numberArrayFromString() moved from cfxZones
--]]-- --]]--
@ -2521,8 +2525,6 @@ end
end end
end end
function dcsCommon.numberUUID() function dcsCommon.numberUUID()
dcsCommon.simpleUUID = dcsCommon.simpleUUID + 1 dcsCommon.simpleUUID = dcsCommon.simpleUUID + 1
return dcsCommon.simpleUUID return dcsCommon.simpleUUID
@ -3025,6 +3027,53 @@ function dcsCommon.getMissionName()
return mn return mn
end end
function dcsCommon.numberArrayFromString(inString, default) -- moved from cfxZones
if not default then default = 0 end
if string.len(inString) < 1 then
trigger.action.outText("+++dcsCommon: empty numbers", 30)
return {default, }
end
local flags = {}
local rawElements = dcsCommon.splitString(inString, ",")
-- go over all elements
for idx, anElement in pairs(rawElements) do
anElement = dcsCommon.trim(anElement)
if dcsCommon.stringStartsWithDigit(anElement) and dcsCommon.containsString(anElement, "-") then
-- interpret this as a range
local theRange = dcsCommon.splitString(anElement, "-")
local lowerBound = theRange[1]
lowerBound = tonumber(lowerBound)
local upperBound = theRange[2]
upperBound = tonumber(upperBound)
if lowerBound and upperBound then
-- swap if wrong order
if lowerBound > upperBound then
local temp = upperBound
upperBound = lowerBound
lowerBound = temp
end
-- now add add numbers to flags
for f=lowerBound, upperBound do
table.insert(flags, tostring(f))
end
else
-- bounds illegal
trigger.action.outText("+++dcsCommon: ignored range <" .. anElement .. "> (range)", 30)
end
else
-- single number
f = dcsCommon.trim(anElement)
f = tonumber(f)
if f then
table.insert(flags, f)
end
end
end
if #flags < 1 then flags = {default, } end
return flags
end
function dcsCommon.flagArrayFromString(inString, verbose) function dcsCommon.flagArrayFromString(inString, verbose)
if not verbose then verbose = false end if not verbose then verbose = false end
@ -3475,6 +3524,31 @@ function dcsCommon.iteratePlayers(callBack)
end end
end end
--
-- MISC POINT CREATION
--
function dcsCommon.createPoint(x, y, z)
local newPoint = {}
newPoint.x = x
newPoint.y = y
newPoint.z = z -- works even if Z == nil
return newPoint
end
function dcsCommon.copyPoint(inPoint)
local newPoint = {}
newPoint.x = inPoint.x
newPoint.y = inPoint.y
-- handle xz only
if inPoint.z then
newPoint.z = inPoint.z
else
newPoint.z = inPoint.y
end
return newPoint
end
-- --
-- SEMAPHORES -- SEMAPHORES
-- --

View File

@ -1,10 +1,13 @@
flareZone = {} flareZone = {}
flareZone.version = "1.0.0" flareZone.version = "1.1.0"
flareZone.verbose = false flareZone.verbose = false
flareZone.name = "flareZone" flareZone.name = "flareZone"
--[[-- VERSION HISTORY --[[-- VERSION HISTORY
1.0.0 - initial version 1.0.0 - initial version
1.1.0 - improvements to verbosity
- OOP
- small bugfix in doFlare assignment
--]]-- --]]--
flareZone.requiredLibs = { flareZone.requiredLibs = {
"dcsCommon", "dcsCommon",
@ -13,40 +16,39 @@ flareZone.requiredLibs = {
flareZone.flares = {} -- all flare zones flareZone.flares = {} -- all flare zones
function flareZone.addFlareZone(theZone) function flareZone.addFlareZone(theZone)
theZone.flareColor = cfxZones.getFlareColorStringFromZoneProperty(theZone, "flare", "green") theZone.flareColor = theZone:getFlareColorStringFromZoneProperty("flare", "green")
theZone.flareColor = dcsCommon.flareColor2Num(theZone.flareColor) theZone.flareColor = dcsCommon.flareColor2Num(theZone.flareColor)
if cfxZones.hasProperty(theZone, "f?") then if theZone:hasProperty("f?") then
cfxZones.theZone.doFlare = cfxZones.getStringFromZoneProperty(theZone, "f?", "<none>") theZone.doFlare = theZone:getStringFromZoneProperty("f?", "<none>")
elseif cfxZones.hasProperty(theZone, "launchFlare?") then elseif theZone:hasProperty("launchFlare?") then
theZone.doFlare = cfxZones.getStringFromZoneProperty(theZone, "launchFlare?", "<none>") theZone.doFlare = theZone:getStringFromZoneProperty( "launchFlare?", "<none>")
else else
theZone.doFlare = cfxZones.getStringFromZoneProperty(theZone, "launch?", "<none>") theZone.doFlare = theZone:getStringFromZoneProperty("launch?", "<none>")
end end
theZone.lastDoFlare = trigger.misc.getUserFlag(theZone.doFlare) theZone.lastDoFlare = trigger.misc.getUserFlag(theZone.doFlare)
-- triggerMethod -- triggerMethod
theZone.flareTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change") theZone.flareTriggerMethod = theZone:getStringFromZoneProperty("triggerMethod", "change")
if cfxZones.hasProperty(theZone, "flareTriggerMethod") then if theZone:hasProperty("flareTriggerMethod") then
theZone.flareTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "flareTriggerMethod", "change") theZone.flareTriggerMethod = theZone:getStringFromZoneProperty("flareTriggerMethod", "change")
end end
theZone.azimuthL, theZone.azimuthH = cfxZones.getPositiveRangeFromZoneProperty(theZone, "direction", 90) -- in degrees theZone.azimuthL, theZone.azimuthH = theZone:getPositiveRangeFromZoneProperty("direction", 90) -- in degrees
-- in DCS documentation, the parameter is incorrectly called 'azimuth' -- in DCS documentation, the parameter is incorrectly called 'azimuth'
if cfxZones.hasProperty(theZone, "azimuth") then if theZone:hasProperty("azimuth") then
theZone.azimuthL, theZone.azimuthH = cfxZones.getPositiveRangeFromZoneProperty(theZone, "azimuth", 90) -- in degrees theZone.azimuthL, theZone.azimuthH = theZone:getPositiveRangeFromZoneProperty("azimuth", 90) -- in degrees
end end
-- theZone.azimuth = theZone.azimuth * 0.0174533 -- rads theZone.flareAlt = theZone:getNumberFromZoneProperty("altitude", 1)
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "altitude", 1) if theZone:hasProperty("alt") then
if cfxZones.hasProperty(theZone, "alt") then theZone.flareAlt = theZone:getNumberFromZoneProperty("alt", 1)
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "alt", 1) elseif theZone:hasProperty("flareAlt") then
elseif cfxZones.hasProperty(theZone, "flareAlt") then theZone.flareAlt = theZone:getNumberFromZoneProperty("flareAlt", 1)
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "flareAlt", 1) elseif theZone:hasProperty("agl") then
elseif cfxZones.hasProperty(theZone, "agl") then theZone.flareAlt = theZone:getNumberFromZoneProperty("agl", 1)
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "agl", 1)
end end
theZone.salvoSizeL, theZone.salvoSizeH = cfxZones.getPositiveRangeFromZoneProperty(theZone, "salvo", 1) theZone.salvoSizeL, theZone.salvoSizeH = theZone:getPositiveRangeFromZoneProperty("salvo", 1)
theZone.salvoDurationL, theZone.salvoDurationH = cfxZones.getPositiveRangeFromZoneProperty(theZone, "duration", 1) theZone.salvoDurationL, theZone.salvoDurationH = theZone:getPositiveRangeFromZoneProperty("duration", 1)
if theZone.verbose or flareZone.verbose then if theZone.verbose or flareZone.verbose then
trigger.action.outText("+++flrZ: new flare <" .. theZone.name .. ">, color (" .. theZone.flareColor .. ")", 30) trigger.action.outText("+++flrZ: new flare <" .. theZone.name .. ">, color (" .. theZone.flareColor .. ")", 30)
@ -57,13 +59,17 @@ end
function flareZone.launch(theZone) function flareZone.launch(theZone)
local color = theZone.flareColor local color = theZone.flareColor
if color < 0 then color = math.random(4) - 1 end if color < 0 then color = math.random(4) - 1 end
if flareZone.verbose or theZone.verbose then
trigger.action.outText("+++flrZ: launching <" .. theZone.name .. ">, c = " .. color .. " (" .. dcsCommon.flareColor2Text(color) .. ")", 30)
end
local loc = cfxZones.getPoint(theZone, true) -- with height local loc = cfxZones.getPoint(theZone, true) -- with height
loc.y = loc.y + theZone.flareAlt loc.y = loc.y + theZone.flareAlt
-- calculate azimuth -- calculate azimuth
local azimuth = cfxZones.randomInRange(theZone.azimuthL, theZone.azimuthH) * 0.0174533 -- in rads local azimuth = cfxZones.randomInRange(theZone.azimuthL, theZone.azimuthH) -- in deg
if flareZone.verbose or theZone.verbose then
trigger.action.outText("+++flrZ: launching <" .. theZone.name .. ">, c = " .. color .. " (" .. dcsCommon.flareColor2Text(color) .. "), azi <" .. azimuth .. "> [" .. theZone.azimuthL .. "-" .. theZone.azimuthH .. "]", 30)
end
azimuth = azimuth * 0.0174533 -- in rads
trigger.action.signalFlare(loc, color, azimuth) trigger.action.signalFlare(loc, color, azimuth)
end end

View File

@ -1,5 +1,5 @@
messenger = {} messenger = {}
messenger.version = "2.2.1" messenger.version = "2.3.0"
messenger.verbose = false messenger.verbose = false
messenger.requiredLibs = { messenger.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
@ -67,6 +67,7 @@ messenger.messengers = {}
2.2.1 - when messenger is linked to a unit, it can use the linked 2.2.1 - when messenger is linked to a unit, it can use the linked
unit as reference point for relative wildcards. Always broadcasts to coalition. Can be used to broadcase 'eye in the sky' type information unit as reference point for relative wildcards. Always broadcasts to coalition. Can be used to broadcase 'eye in the sky' type information
- fixed verbosity bug - fixed verbosity bug
2.3.0 - cfxZones OOP switch
--]]-- --]]--
@ -138,7 +139,7 @@ function messenger.dynamicUnitProcessing(inMsg, theZone, theUnit)
local tHead = 0 local tHead = 0
if tZone then if tZone then
thePoint = cfxZones.getPoint(tZone) thePoint = tZone:getPoint()
-- if this zone follows a unit, get the master units elevaltion -- if this zone follows a unit, get the master units elevaltion
if tZone.linkedUnit and Unit.isExist(tZone.linkedUnit) then if tZone.linkedUnit and Unit.isExist(tZone.linkedUnit) then
local lU = tZone.linkedUnit local lU = tZone.linkedUnit
@ -225,90 +226,82 @@ end
function messenger.createMessengerWithZone(theZone) function messenger.createMessengerWithZone(theZone)
-- start val - a range -- start val - a range
local aMessage = cfxZones.getStringFromZoneProperty(theZone, "message", "") local aMessage = theZone:getStringFromZoneProperty("message", "")
theZone.message = aMessage -- refactoring: messenger.preProcMessage(aMessage, theZone) removed theZone.message = aMessage -- refactoring: messenger.preProcMessage(aMessage, theZone) removed
theZone.spaceBefore = cfxZones.getBoolFromZoneProperty(theZone, "spaceBefore", false) theZone.spaceBefore = theZone:getBoolFromZoneProperty("spaceBefore", false)
theZone.spaceAfter = cfxZones.getBoolFromZoneProperty(theZone, "spaceAfter", false) theZone.spaceAfter = theZone:getBoolFromZoneProperty("spaceAfter", false)
theZone.soundFile = cfxZones.getStringFromZoneProperty(theZone, "soundFile", "<none>") theZone.soundFile = theZone:getStringFromZoneProperty("soundFile", "<none>")
theZone.clearScreen = cfxZones.getBoolFromZoneProperty(theZone, "clearScreen", false) theZone.clearScreen = theZone:getBoolFromZoneProperty("clearScreen", false)
theZone.duration = cfxZones.getNumberFromZoneProperty(theZone, "duration", 30) theZone.duration = theZone:getNumberFromZoneProperty("duration", 30)
if cfxZones.hasProperty(theZone, "messageDuration") then if theZone:hasProperty("messageDuration") then
theZone.duration = cfxZones.getNumberFromZoneProperty(theZone, "messageDuration", 30) theZone.duration = theZone:getNumberFromZoneProperty( "messageDuration", 30)
end end
-- msgTriggerMethod -- msgTriggerMethod
theZone.msgTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change") theZone.msgTriggerMethod = theZone:getStringFromZoneProperty( "triggerMethod", "change")
if cfxZones.hasProperty(theZone, "msgTriggerMethod") then if theZone:hasProperty("msgTriggerMethod") then
theZone.msgTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "msgTriggerMethod", "change") theZone.msgTriggerMethod = theZone:getStringFromZoneProperty("msgTriggerMethod", "change")
end end
-- trigger flag f? in? messageOut?, add messenger? if theZone:hasProperty("f?") then
theZone.triggerMessagerFlag = theZone:getStringFromZoneProperty("f?", "none")
if cfxZones.hasProperty(theZone, "f?") then
theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, "f?", "none")
-- may want to add deprecated note later
end end
-- can also use in? for counting. we always use triggerMessagerFlag -- can also use in? for counting. we always use triggerMessagerFlag
if cfxZones.hasProperty(theZone, "in?") then if theZone:hasProperty("in?") then
theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, "in?", "none") theZone.triggerMessagerFlag = theZone:getStringFromZoneProperty("in?", "none")
end end
if cfxZones.hasProperty(theZone, "messageOut?") then if theZone:hasProperty("messageOut?") then
theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, "messageOut?", "none") theZone.triggerMessagerFlag = theZone:getStringFromZoneProperty("messageOut?", "none")
end end
-- try default only if no other is set -- try default only if no other is set
if not theZone.triggerMessagerFlag then if not theZone.triggerMessagerFlag then
if not cfxZones.hasProperty(theZone, "messenger?") then if not theZone:hasProperty("messenger?") then
trigger.action.outText("*** Note: messenger in <" .. theZone.name .. "> can't be triggered", 30) trigger.action.outText("*** Note: messenger in <" .. theZone.name .. "> can't be triggered", 30)
end end
theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, "messenger?", "none") theZone.triggerMessagerFlag = theZone:getStringFromZoneProperty( "messenger?", "none")
end end
-- if theZone.triggerMessagerFlag then theZone.lastMessageTriggerValue = theZone:getFlagValue(theZone.triggerMessagerFlag)-- save last value
theZone.lastMessageTriggerValue = cfxZones.getFlagValue(theZone.triggerMessagerFlag, theZone)-- save last value
-- end
theZone.messageOff = cfxZones.getBoolFromZoneProperty(theZone, "mute", false) --false theZone.messageOff = theZone:getBoolFromZoneProperty("mute", false) --false
if cfxZones.hasProperty(theZone, "messageMute") then if theZone:hasProperty("messageMute") then
theZone.messageOff = cfxZones.getBoolFromZoneProperty(theZone, "messageMute", false) theZone.messageOff = theZone:getBoolFromZoneProperty( "messageMute", false)
end end
-- advisory: messageOff, messageOffFlag and lastMessageOff are all distinct -- advisory: messageOff, messageOffFlag and lastMessageOff are all distinct
if theZone:hasProperty("messageOff?") then
if cfxZones.hasProperty(theZone, "messageOff?") then theZone.messageOffFlag = theZone:getStringFromZoneProperty("messageOff?", "*none")
theZone.messageOffFlag = cfxZones.getStringFromZoneProperty(theZone, "messageOff?", "*none") theZone.lastMessageOff = theZone:getFlagValue(theZone.messageOffFlag)
theZone.lastMessageOff = cfxZones.getFlagValue(theZone.messageOffFlag, theZone)
end end
if cfxZones.hasProperty(theZone, "messageOn?") then if theZone:hasProperty("messageOn?") then
theZone.messageOnFlag = cfxZones.getStringFromZoneProperty(theZone, "messageOn?", "*none") theZone.messageOnFlag = theZone:getStringFromZoneProperty( "messageOn?", "*none")
theZone.lastMessageOn = cfxZones.getFlagValue(theZone.messageOnFlag, theZone) theZone.lastMessageOn = theZone:getFlagValue(theZone.messageOnFlag)
end end
-- reveiver: coalition, group, unit -- reveiver: coalition, group, unit
if cfxZones.hasProperty(theZone, "coalition") then if theZone:hasProperty("coalition") then
theZone.msgCoalition = cfxZones.getCoalitionFromZoneProperty(theZone, "coalition", 0) theZone.msgCoalition = theZone:getCoalitionFromZoneProperty("coalition", 0)
elseif cfxZones.hasProperty(theZone, "msgCoalition") then elseif theZone:hasProperty("msgCoalition") then
theZone.msgCoalition = cfxZones.getCoalitionFromZoneProperty(theZone, "msgCoalition", 0) theZone.msgCoalition = theZone:getCoalitionFromZoneProperty("msgCoalition", 0)
end end
if cfxZones.hasProperty(theZone, "group") then if theZone:hasProperty("group") then
theZone.msgGroup = cfxZones.getStringFromZoneProperty(theZone, "group", "<none>") theZone.msgGroup = theZone:getStringFromZoneProperty("group", "<none>")
elseif cfxZones.hasProperty(theZone, "msgGroup") then elseif theZone:hasProperty("msgGroup") then
theZone.msgGroup = cfxZones.getStringFromZoneProperty(theZone, "msgGroup", "<none>") theZone.msgGroup = theZone:getStringFromZoneProperty("msgGroup", "<none>")
end end
if cfxZones.hasProperty(theZone, "unit") then if theZone:hasProperty("unit") then
theZone.msgUnit = cfxZones.getStringFromZoneProperty(theZone, "unit", "<none>") theZone.msgUnit = theZone:getStringFromZoneProperty("unit", "<none>")
elseif cfxZones.hasProperty(theZone, "msgUnit") then elseif theZone:hasProperty("msgUnit") then
theZone.msgUnit = cfxZones.getStringFromZoneProperty(theZone, "msgUnit", "<none>") theZone.msgUnit = theZone:getStringFromZoneProperty("msgUnit", "<none>")
end end
if (theZone.msgGroup and theZone.msgUnit) or if (theZone.msgGroup and theZone.msgUnit) or
@ -319,27 +312,27 @@ function messenger.createMessengerWithZone(theZone)
end end
-- flag whose value can be read: to be deprecated -- flag whose value can be read: to be deprecated
if cfxZones.hasProperty(theZone, "messageValue?") then if theZone:hasProperty("messageValue?") then
theZone.messageValue = cfxZones.getStringFromZoneProperty(theZone, "messageValue?", "<none>") theZone.messageValue = theZone:getStringFromZoneProperty( "messageValue?", "<none>")
trigger.action.outText("+++Msg: Warning - zone <" .. theZone.name .. "> uses 'messageValue' attribute. Migrate to <v:<flag> now!", 30) trigger.action.outText("+++Msg: Warning - zone <" .. theZone.name .. "> uses 'messageValue' attribute. Migrate to <v:<flag> now!", 30)
end end
-- time format for new <t: flagname> -- time format for new <t: flagname>
theZone.msgTimeFormat = cfxZones.getStringFromZoneProperty(theZone, "timeFormat", "<:h>:<:m>:<:s>") theZone.msgTimeFormat = theZone:getStringFromZoneProperty( "timeFormat", "<:h>:<:m>:<:s>")
theZone.imperialUnits = cfxZones.getBoolFromZoneProperty(theZone, "imperial", false) theZone.imperialUnits = theZone:getBoolFromZoneProperty("imperial", false)
if cfxZones.hasProperty(theZone, "imperialUnits") then if theZone:hasProperty("imperialUnits") then
theZone.imperialUnits = cfxZones.getBoolFromZoneProperty(theZone, "imperialUnits", false) theZone.imperialUnits = theZone:getBoolFromZoneProperty( "imperialUnits", false)
end end
theZone.errString = cfxZones.getStringFromZoneProperty(theZone, "error", "") theZone.errString = theZone:getStringFromZoneProperty("error", "")
if cfxZones.hasProperty(theZone, "messageError") then if theZone:hasProperty("messageError") then
theZone.errString = cfxZones.getStringFromZoneProperty(theZone, "messageError", "") theZone.errString = theZone:getStringFromZoneProperty( "messageError", "")
end end
-- possible responses for mapping -- possible responses for mapping
if cfxZones.hasProperty(theZone, "responses") then if theZone:hasProperty("responses") then
local resp = cfxZones.getStringFromZoneProperty(theZone, "responses", "none") local resp = theZone:getStringFromZoneProperty("responses", "none")
theZone.msgResponses = dcsCommon.string2Array(resp, ",") theZone.msgResponses = dcsCommon.string2Array(resp, ",")
end end
@ -359,7 +352,7 @@ function messenger.getMessage(theZone)
local zVal = "<n/a>" local zVal = "<n/a>"
if theZone.messageValue then if theZone.messageValue then
trigger.action.outText("+++Msg: Warning - zone <" .. theZone.name .. "> uses 'messageValue' attribute. Migrate to <v:<flag> now!") trigger.action.outText("+++Msg: Warning - zone <" .. theZone.name .. "> uses 'messageValue' attribute. Migrate to <v:<flag> now!")
zVal = cfxZones.getFlagValue(theZone.messageValue, theZone) zVal = theZone:getFlagValue(theZone.messageValue)
zVal = tostring(zVal) zVal = tostring(zVal)
if not zVal then zVal = "<err>" end if not zVal then zVal = "<err>" end
end end
@ -421,13 +414,13 @@ function messenger.isTriggered(theZone)
end end
trigger.action.outSoundForUnit(ID, fileName) trigger.action.outSoundForUnit(ID, fileName)
end end
elseif cfxZones.getLinkedUnit(theZone) then elseif theZone:getLinkedUnit() then
-- this only works if the zone is linked to a unit -- this only works if the zone is linked to a unit
-- and not using group or unit -- and not using group or unit
-- the linked unit is then used as reference -- the linked unit is then used as reference
-- outputs to all of same coalition as the linked -- outputs to all of same coalition as the linked
-- unit -- unit
local theUnit = cfxZones.getLinkedUnit(theZone) local theUnit = theZone:getLinkedUnit()
local ID = theUnit:getID() local ID = theUnit:getID()
local coa = theUnit:getCoalition() local coa = theUnit:getCoalition()
msg = messenger.dynamicUnitProcessing(msg, theZone, theUnit) msg = messenger.dynamicUnitProcessing(msg, theZone, theUnit)
@ -451,7 +444,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.msgTriggerMethod, "lastMessageTriggerValue") then if aZone:testZoneFlag(aZone.triggerMessagerFlag, aZone.msgTriggerMethod, "lastMessageTriggerValue") then
if messenger.verbose or aZone.verbose then if messenger.verbose or aZone.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
@ -459,14 +452,14 @@ function messenger.update()
end end
-- old trigger code -- old trigger code
if cfxZones.testZoneFlag(aZone, aZone.messageOffFlag, aZone.msgTriggerMethod, "lastMessageOff") then if aZone:testZoneFlag(aZone.messageOffFlag, aZone.msgTriggerMethod, "lastMessageOff") then
aZone.messageOff = true aZone.messageOff = true
if messenger.verbose or aZone.verbose then if messenger.verbose or aZone.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, aZone.msgTriggerMethod, "lastMessageOn") then if aZone:testZoneFlag(aZone.messageOnFlag, aZone.msgTriggerMethod, "lastMessageOn") then
aZone.messageOff = false aZone.messageOff = false
if messenger.verbose or aZone.verbose then if messenger.verbose or aZone.verbose then
trigger.action.outText("+++msg: messenger <" .. aZone.name .. "> turned ON", 30) trigger.action.outText("+++msg: messenger <" .. aZone.name .. "> turned ON", 30)
@ -487,7 +480,7 @@ function messenger.readConfigZone()
theZone = cfxZones.createSimpleZone("messengerConfig") theZone = cfxZones.createSimpleZone("messengerConfig")
end end
messenger.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false) messenger.verbose = theZone:getBoolFromZoneProperty("verbose", false)
if messenger.verbose then if messenger.verbose then
trigger.action.outText("+++msgr: read config", 30) trigger.action.outText("+++msgr: read config", 30)

View File

@ -1,5 +1,5 @@
radioMenu = {} radioMenu = {}
radioMenu.version = "2.0.1" radioMenu.version = "2.1.0"
radioMenu.verbose = false radioMenu.verbose = false
radioMenu.ups = 1 radioMenu.ups = 1
radioMenu.requiredLibs = { radioMenu.requiredLibs = {
@ -10,12 +10,12 @@ radioMenu.menus = {}
--[[-- --[[--
Version History Version History
1.0.0 Initial version 1.0.0 - Initial version
1.0.1 spelling corrections 1.0.1 - spelling corrections
1.1.0 removeMenu 1.1.0 - removeMenu
addMenu addMenu
menuVisible menuVisible
2.0.0 redesign: handles multiple receivers 2.0.0 - redesign: handles multiple receivers
optional MX module optional MX module
group option group option
type option type option
@ -24,9 +24,13 @@ radioMenu.menus = {}
gereric helo type gereric helo type
generic plane type generic plane type
type works with coalition type works with coalition
2.0.1 corrections to installMenu(), as suggested by GumidekCZ 2.0.1 - corrections to installMenu(), as suggested by GumidekCZ
2.1.0 - valA/valB/valC/valD attributes
OOP cfxZones
corrected CD setting for "D"
ackA, ackB, ackC, ackD attributes
valA-D now define full method, not just values
full wildcard support for ack and cooldown
--]]-- --]]--
function radioMenu.addRadioMenu(theZone) function radioMenu.addRadioMenu(theZone)
@ -183,8 +187,8 @@ function radioMenu.installMenu(theZone)
theZone.rootMenu[0] = missionCommands.addSubMenuForCoalition(theZone.coalition, theZone.rootName, nil) theZone.rootMenu[0] = missionCommands.addSubMenuForCoalition(theZone.coalition, theZone.rootName, nil)
end end
if cfxZones.hasProperty(theZone, "itemA") then if theZone:hasProperty("itemA") then
local menuA = cfxZones.getStringFromZoneProperty(theZone, "itemA", "<no A submenu>") local menuA = theZone:getStringFromZoneProperty("itemA", "<no A submenu>")
if theZone.menuGroup or theZone.menuTypes then if theZone.menuGroup or theZone.menuTypes then
theZone.menuA = {} theZone.menuA = {}
for idx, grp in pairs(gID) do for idx, grp in pairs(gID) do
@ -197,8 +201,8 @@ function radioMenu.installMenu(theZone)
end end
end end
if cfxZones.hasProperty(theZone, "itemB") then if theZone:hasProperty("itemB") then
local menuB = cfxZones.getStringFromZoneProperty(theZone, "itemB", "<no B submenu>") local menuB = theZone:getStringFromZoneProperty("itemB", "<no B submenu>")
if theZone.menuGroup or theZone.menuTypes then if theZone.menuGroup or theZone.menuTypes then
theZone.menuB = {} theZone.menuB = {}
for idx, grp in pairs(gID) do for idx, grp in pairs(gID) do
@ -211,8 +215,8 @@ function radioMenu.installMenu(theZone)
end end
end end
if cfxZones.hasProperty(theZone, "itemC") then if theZone:hasProperty("itemC") then
local menuC = cfxZones.getStringFromZoneProperty(theZone, "itemC", "<no C submenu>") local menuC = theZone:getStringFromZoneProperty("itemC", "<no C submenu>")
if theZone.menuGroup or theZone.menuTypes then if theZone.menuGroup or theZone.menuTypes then
theZone.menuC = {} theZone.menuC = {}
for idx, grp in pairs(gID) do for idx, grp in pairs(gID) do
@ -225,8 +229,8 @@ function radioMenu.installMenu(theZone)
end end
end end
if cfxZones.hasProperty(theZone, "itemD") then if theZone:hasProperty("itemD") then
local menuD = cfxZones.getStringFromZoneProperty(theZone, "itemD", "<no D submenu>") local menuD = theZone:getStringFromZoneProperty("itemD", "<no D submenu>")
if theZone.menuGroup or theZone.menuTypes then if theZone.menuGroup or theZone.menuTypes then
theZone.menuD = {} theZone.menuD = {}
for idx, grp in pairs(gID) do for idx, grp in pairs(gID) do
@ -241,23 +245,23 @@ function radioMenu.installMenu(theZone)
end end
function radioMenu.createRadioMenuWithZone(theZone) function radioMenu.createRadioMenuWithZone(theZone)
theZone.rootName = cfxZones.getStringFromZoneProperty(theZone, "radioMenu", "<No Name>") theZone.rootName = theZone:getStringFromZoneProperty("radioMenu", "<No Name>")
theZone.coalition = cfxZones.getCoalitionFromZoneProperty(theZone, "coalition", 0) theZone.coalition = theZone:getCoalitionFromZoneProperty("coalition", 0)
-- groups / types -- groups / types
if cfxZones.hasProperty(theZone, "group") then if theZone:hasProperty("group") then
theZone.menuGroup = cfxZones.getStringFromZoneProperty(theZone, "group", "<none>") theZone.menuGroup = theZone:getStringFromZoneProperty("group", "<none>")
theZone.menuGroup = dcsCommon.trim(theZone.menuGroup) theZone.menuGroup = dcsCommon.trim(theZone.menuGroup)
elseif cfxZones.hasProperty(theZone, "groups") then elseif theZone:hasProperty("groups") then
theZone.menuGroup = cfxZones.getStringFromZoneProperty(theZone, "groups", "<none>") theZone.menuGroup = theZone:getStringFromZoneProperty("groups", "<none>")
theZone.menuGroup = dcsCommon.trim(theZone.menuGroup) theZone.menuGroup = dcsCommon.trim(theZone.menuGroup)
elseif cfxZones.hasProperty(theZone, "type") then elseif theZone:hasProperty("type") then
theZone.menuTypes = cfxZones.getStringFromZoneProperty(theZone, "type", "none") theZone.menuTypes = theZone:getStringFromZoneProperty("type", "none")
elseif cfxZones.hasProperty(theZone, "types") then elseif theZone:hasProperty("types") then
theZone.menuTypes = cfxZones.getStringFromZoneProperty(theZone, "types", "none") theZone.menuTypes = theZone:getStringFromZoneProperty("types", "none")
end end
theZone.menuVisible = cfxZones.getBoolFromZoneProperty(theZone, "menuVisible", true) theZone.menuVisible = theZone:getBoolFromZoneProperty("menuVisible", true)
-- install menu if not hidden -- install menu if not hidden
if theZone.menuVisible then if theZone.menuVisible then
@ -265,41 +269,62 @@ function radioMenu.createRadioMenuWithZone(theZone)
end end
-- get the triggers & methods here -- get the triggers & methods here
theZone.radioMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "inc") theZone.radioMethod = theZone:getStringFromZoneProperty("method", "inc")
if cfxZones.hasProperty(theZone, "radioMethod") then if theZone:hasProperty("radioMethod") then
theZone.radioMethod = cfxZones.getStringFromZoneProperty(theZone, "radioMethod", "inc") theZone.radioMethod = theZone:getStringFromZoneProperty( "radioMethod", "inc")
end end
theZone.radioTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "radioTriggerMethod", "change") theZone.radioTriggerMethod = theZone:getStringFromZoneProperty("radioTriggerMethod", "change")
theZone.itemAChosen = cfxZones.getStringFromZoneProperty(theZone, "A!", "*<none>") -- A! to D!
theZone.cooldownA = cfxZones.getNumberFromZoneProperty(theZone, "cooldownA", 0) theZone.itemAChosen = theZone:getStringFromZoneProperty("A!", "*<none>")
--theZone.mcdA = 0 theZone.cooldownA = theZone:getNumberFromZoneProperty("cooldownA", 0)
theZone.busyA = cfxZones.getStringFromZoneProperty(theZone, "busyA", "Please stand by (<s> seconds)") theZone.busyA = theZone:getStringFromZoneProperty("busyA", "Please stand by (<s> seconds)")
if theZone:hasProperty("valA") then
theZone.itemBChosen = cfxZones.getStringFromZoneProperty(theZone, "B!", "*<none>") theZone.outValA = theZone:getStringFromZoneProperty("valA", 1)
theZone.cooldownB = cfxZones.getNumberFromZoneProperty(theZone, "cooldownB", 0) end
--theZone.mcdB = 0 if theZone:hasProperty("ackA") then
theZone.busyB = cfxZones.getStringFromZoneProperty(theZone, "busyB", "Please stand by (<s> seconds)") theZone.ackA = theZone:getStringFromZoneProperty("ackA", "Acknowledged: A")
theZone.itemCChosen = cfxZones.getStringFromZoneProperty(theZone, "C!", "*<none>")
theZone.cooldownC = cfxZones.getNumberFromZoneProperty(theZone, "cooldownC", 0)
--theZone.mcdC = 0
theZone.busyC = cfxZones.getStringFromZoneProperty(theZone, "busyC", "Please stand by (<s> seconds)")
theZone.itemDChosen = cfxZones.getStringFromZoneProperty(theZone, "D!", "*<none>")
theZone.cooldownD = cfxZones.getNumberFromZoneProperty(theZone, "cooldownD", 0)
--theZone.mcdD = 0
theZone.busyD = cfxZones.getStringFromZoneProperty(theZone, "busyD", "Please stand by (<s> seconds)")
if cfxZones.hasProperty(theZone, "removeMenu?") then
theZone.removeMenu = cfxZones.getStringFromZoneProperty(theZone, "removeMenu?", "*<none>")
theZone.lastRemoveMenu = cfxZones.getFlagValue(theZone.removeMenu, theZone)
end end
if cfxZones.hasProperty(theZone, "addMenu?") then theZone.itemBChosen = theZone:getStringFromZoneProperty("B!", "*<none>")
theZone.addMenu = cfxZones.getStringFromZoneProperty(theZone, "addMenu?", "*<none>") theZone.cooldownB = theZone:getNumberFromZoneProperty("cooldownB", 0)
theZone.lastAddMenu = cfxZones.getFlagValue(theZone.addMenu, theZone) theZone.busyB = theZone:getStringFromZoneProperty("busyB", "Please stand by (<s> seconds)")
if theZone:hasProperty("valB") then
theZone.outValB = theZone:getStringFromZoneProperty("valB", 1)
end
if theZone:hasProperty("ackB") then
theZone.ackB = theZone:getStringFromZoneProperty("ackB", "Acknowledged: B")
end
theZone.itemCChosen = theZone:getStringFromZoneProperty("C!", "*<none>")
theZone.cooldownC = theZone:getNumberFromZoneProperty("cooldownC", 0)
theZone.busyC = theZone:getStringFromZoneProperty("busyC", "Please stand by (<s> seconds)")
if theZone:hasProperty("valC") then
theZone.outValC = theZone:getStringFromZoneProperty("valC", 1)
end
if theZone:hasProperty("ackC") then
theZone.ackC = theZone:getStringFromZoneProperty("ackC", "Acknowledged: C")
end
theZone.itemDChosen = theZone:getStringFromZoneProperty("D!", "*<none>")
theZone.cooldownD = theZone:getNumberFromZoneProperty("cooldownD", 0)
theZone.busyD = theZone:getStringFromZoneProperty("busyD", "Please stand by (<s> seconds)")
if theZone:hasProperty("valD") then
theZone.outValD = theZone:getStringFromZoneProperty("valD", 1)
end
if theZone:hasProperty("ackD") then
theZone.ackC = theZone:getStringFromZoneProperty("ackD", "Acknowledged: D")
end
if theZone:hasProperty("removeMenu?") then
theZone.removeMenu = theZone:getStringFromZoneProperty( "removeMenu?", "*<none>")
theZone.lastRemoveMenu = theZone:getFlagValue(theZone.removeMenu)
end
if theZone:hasProperty("addMenu?") then
theZone.addMenu = theZone:getStringFromZoneProperty("addMenu?", "*<none>")
theZone.lastAddMenu = theZone:getFlagValue(theZone.addMenu)
end end
if radioMenu.verbose or theZone.verbose then if radioMenu.verbose or theZone.verbose then
@ -326,6 +351,28 @@ function radioMenu.processHMS(msg, delta)
return dcsCommon.processHMS(msg, delta) return dcsCommon.processHMS(msg, delta)
end end
function radioMenu.radioOutMsg(ack, gid, theZone)
-- group processing. only if gid>0 and cfxMX
local theMsg = ack
if (gid > 0) and cfxMX then
local gName = cfxMX.cfxMX.groupNamesByID[gid]
theMsg = theMsg:gsub("<group>", gName)
end
-- for the time being, we can't support many wildcards
-- leave them in, and simply proceed
-- note that theZone is the radio Menu zone!
theMsg = cfxZones.processStringWildcards(theMsg, theZone)
c = theZone.coalition
if gid > 0 then
trigger.action.outTextForGroup(gid, theMsg, 30)
elseif c > 0 then
trigger.action.outTextForCoalition(c, theMsg, 30)
else
trigger.action.outText(theMsg, 30)
end
end
-- --
-- Menu Branching -- Menu Branching
@ -360,20 +407,28 @@ function radioMenu.doMenuX(args)
local cd = radioMenu.cdByGID(theZone.mcdA, theZone, theGroup) --theZone.mcdA local cd = radioMenu.cdByGID(theZone.mcdA, theZone, theGroup) --theZone.mcdA
local busy = theZone.busyA local busy = theZone.busyA
local theFlag = theZone.itemAChosen local theFlag = theZone.itemAChosen
local outVal = theZone.outValA
local ack = theZone.ackA
-- decode A..X -- decode A..X
if theItemIndex == "B"then if theItemIndex == "B"then
cd = radioMenu.cdByGID(theZone.mcdB, theZone, theGroup) -- theZone.mcdB cd = radioMenu.cdByGID(theZone.mcdB, theZone, theGroup) -- theZone.mcdB
busy = theZone.busyB busy = theZone.busyB
theFlag = theZone.itemBChosen theFlag = theZone.itemBChosen
outVal = theZone.outValB
ack = theZone.ackB
elseif theItemIndex == "C" then elseif theItemIndex == "C" then
cd = radioMenu.cdByGID(theZone.mcdC, theZone, theGroup) -- theZone.mcdC cd = radioMenu.cdByGID(theZone.mcdC, theZone, theGroup) -- theZone.mcdC
busy = theZone.busyC busy = theZone.busyC
theFlag = theZone.itemCChosen theFlag = theZone.itemCChosen
outVal = theZone.outValC
ack = theZone.ackC
elseif theItemIndex == "D" then elseif theItemIndex == "D" then
cd = radioMenu.cdByGID(theZone.mcdD, theZone, theGroup) -- theZone.mcdD cd = radioMenu.cdByGID(theZone.mcdD, theZone, theGroup) -- theZone.mcdD
busy = theZone.busyD busy = theZone.busyD
theFlag = theZone.itemDChosen theFlag = theZone.itemDChosen
outVal = theZone.outValD
ack = theZone.ackD
end end
-- see if we are on cooldown -- see if we are on cooldown
@ -381,8 +436,15 @@ function radioMenu.doMenuX(args)
if now < cd then if now < cd then
-- we are on cooldown. -- we are on cooldown.
local msg = radioMenu.processHMS(busy, cd - now) local msg = radioMenu.processHMS(busy, cd - now)
radioMenu.radioOutMessage(msg, theZone) radioMenu.radioOutMsg(msg, theGroup, theZone)
--radioMenu.radioOutMessage(msg, theZone)
return return
else
-- see if we have an acknowledge
if ack then
local gid = theGroup
radioMenu.radioOutMsg(ack, gid, theZone)
end
end end
-- set new cooldown -- needs own decoder A..X -- set new cooldown -- needs own decoder A..X
@ -393,13 +455,22 @@ function radioMenu.doMenuX(args)
elseif theItemIndex == "C" then elseif theItemIndex == "C" then
radioMenu.setCDByGID("mcdC", theZone, theGroup, now + theZone.cooldownC) radioMenu.setCDByGID("mcdC", theZone, theGroup, now + theZone.cooldownC)
else else
radioMenu.setCDByGID("mcdC", theZone, theGroup, now + theZone.cooldownC) radioMenu.setCDByGID("mcdD", theZone, theGroup, now + theZone.cooldownD)
end end
cfxZones.pollFlag(theFlag, theZone.radioMethod, theZone) -- poll flag, override with outVal if set
if outVal then
--outVal = "#"..outVal -- we force immediate mode
theZone:pollFlag(theFlag, outVal)
if theZone.verbose or radioMenu.verbose then
trigger.action.outText("+++menu: overriding index " .. theItemIndex .. " output method <" .. theZone.radioMethod .. "> with immediate value <" .. outVal .. ">", 30)
end
else
theZone:pollFlag(theFlag, theZone.radioMethod)
if theZone.verbose or radioMenu.verbose then if theZone.verbose or radioMenu.verbose then
trigger.action.outText("+++menu: banging with <" .. theZone.radioMethod .. "> on <" .. theFlag .. "> for " .. theZone.name, 30) trigger.action.outText("+++menu: banging with <" .. theZone.radioMethod .. "> on <" .. theFlag .. "> for " .. theZone.name, 30)
end end
end
end end
@ -413,7 +484,7 @@ function radioMenu.update()
-- iterate all menus -- iterate all menus
for idx, theZone in pairs(radioMenu.menus) do for idx, theZone in pairs(radioMenu.menus) do
if theZone.removeMenu if theZone.removeMenu
and cfxZones.testZoneFlag(theZone, theZone.removeMenu, theZone.radioTriggerMethod, "lastRemoveMenu") and theZone:testZoneFlag(theZone.removeMenu, theZone.radioTriggerMethod, "lastRemoveMenu")
and theZone.menuVisible and theZone.menuVisible
then then
if theZone.menuGroup or theZone.menuTypes then if theZone.menuGroup or theZone.menuTypes then
@ -430,7 +501,7 @@ function radioMenu.update()
end end
if theZone.addMenu if theZone.addMenu
and cfxZones.testZoneFlag(theZone, theZone.addMenu, theZone.radioTriggerMethod, "lastAddMenu") and theZone:testZoneFlag(theZone.addMenu, theZone.radioTriggerMethod, "lastAddMenu")
and (not theZone.menuVisible) and (not theZone.menuVisible)
then then
if theZone.verbose or radioMenu.verbose then if theZone.verbose or radioMenu.verbose then
@ -453,10 +524,10 @@ function radioMenu.readConfigZone()
if radioMenu.verbose then if radioMenu.verbose then
trigger.action.outText("+++radioMenu: NO config zone!", 30) trigger.action.outText("+++radioMenu: NO config zone!", 30)
end end
return theZone = cfxZones.createSimpleZone("radioMenuConfig")
end end
radioMenu.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false) radioMenu.verbose = theZone:getBoolFromZoneProperty("verbose", false)
if radioMenu.verbose then if radioMenu.verbose then
trigger.action.outText("+++radioMenu: read config", 30) trigger.action.outText("+++radioMenu: read config", 30)

View File

@ -1,5 +1,5 @@
stopGap = {} stopGap = {}
stopGap.version = "1.0.6" stopGap.version = "1.0.7"
stopGap.verbose = false stopGap.verbose = false
stopGap.ssbEnabled = true stopGap.ssbEnabled = true
stopGap.ignoreMe = "-sg" stopGap.ignoreMe = "-sg"
@ -40,6 +40,8 @@ stopGap.requiredLibs = {
1.0.4 - player units or groups that end in '-sg' are not stop-gapped 1.0.4 - player units or groups that end in '-sg' are not stop-gapped
1.0.5 - triggerMethod 1.0.5 - triggerMethod
1.0.6 - spIgnore '-sp' 1.0.6 - spIgnore '-sp'
1.0.7 - migrated to OOP zones
- corrected ssbEnabled config from sbb to ssb
--]]-- --]]--
stopGap.standInGroups = {} stopGap.standInGroups = {}
@ -250,7 +252,8 @@ function stopGap.update()
end end
-- check if signal for on? or off? -- check if signal for on? or off?
if stopGap.turnOn and cfxZones.testZoneFlag(stopGap, stopGap.turnOnFlag, stopGap.triggerMethod, "lastTurnOnFlag") then if stopGap.turnOn and cfxZones.testZoneFlag(stopGap, stopGap.turnOnFlag, stopGap.triggerMethod, "lastTurnOnFlag") -- warning: stopGap is NOT dmlZone, requires cfxZone invocation
then
if not stopGap.enabled then if not stopGap.enabled then
stopGap.turnOn() stopGap.turnOn()
end end
@ -328,12 +331,12 @@ end
-- read stopGapZone -- read stopGapZone
-- --
function stopGap.createStopGapZone(theZone) function stopGap.createStopGapZone(theZone)
local sg = cfxZones.getBoolFromZoneProperty(theZone, "stopGap", true) local sg = theZone:getBoolFromZoneProperty("stopGap", true)
if sg then theZone.sgIgnore = false else theZone.sgIgnore = true end if sg then theZone.sgIgnore = false else theZone.sgIgnore = true end
end end
function stopGap.createStopGapSPZone(theZone) function stopGap.createStopGapSPZone(theZone)
local sp = cfxZones.getBoolFromZoneProperty(theZone, "stopGapSP", true) local sp = theZone:getBoolFromZoneProperty("stopGapSP", true)
if sp then theZone.spIgnore = false else theZone.spIgnore = true end if sp then theZone.spIgnore = false else theZone.spIgnore = true end
end end
@ -344,17 +347,17 @@ stopGap.name = "stopGapConfig" -- cfxZones compatibility here
function stopGap.readConfigZone(theZone) function stopGap.readConfigZone(theZone)
-- currently nothing to do -- currently nothing to do
stopGap.verbose = theZone.verbose stopGap.verbose = theZone.verbose
stopGap.ssbEnabled = cfxZones.getBoolFromZoneProperty(theZone, "sbb", true) stopGap.ssbEnabled = theZone:getBoolFromZoneProperty("ssb", true)
stopGap.enabled = cfxZones.getBoolFromZoneProperty(theZone, "onStart", true) stopGap.enabled = theZone:getBoolFromZoneProperty("onStart", true)
if cfxZones.hasProperty(theZone, "on?") then if theZone:hasProperty("on?") then
stopGap.turnOnFlag = cfxZones.getStringFromZoneProperty(theZone, "on?", "*<none>") stopGap.turnOnFlag = theZone:getStringFromZoneProperty("on?", "*<none>")
stopGap.lastTurnOnFlag = trigger.misc.getUserFlag(stopGap.turnOnFlag) stopGap.lastTurnOnFlag = trigger.misc.getUserFlag(stopGap.turnOnFlag)
end end
if cfxZones.hasProperty(theZone, "off?") then if theZone:hasProperty("off?") then
stopGap.turnOffFlag = cfxZones.getStringFromZoneProperty(theZone, "off?", "*<none>") stopGap.turnOffFlag = theZone:getStringFromZoneProperty("off?", "*<none>")
stopGap.lastTurnOffFlag = trigger.misc.getUserFlag(stopGap.turnOffFlag) stopGap.lastTurnOffFlag = trigger.misc.getUserFlag(stopGap.turnOffFlag)
end end
stopGap.triggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change") stopGap.triggerMethod = theZone:getStringFromZoneProperty( "triggerMethod", "change")
if stopGap.verbose then if stopGap.verbose then
trigger.action.outText("+++StopG: config read, verbose = YES", 30) trigger.action.outText("+++StopG: config read, verbose = YES", 30)
if stopGap.enabled then if stopGap.enabled then

View File

@ -1,8 +1,9 @@
tacan = {} tacan = {}
tacan.version = "1.0.0" tacan.version = "1.1.0"
--[[-- --[[--
Version History Version History
1.0.0 - initial version 1.0.0 - initial version
1.1.0 - OOP cfxZones
--]]-- --]]--
tacan.verbose = false tacan.verbose = false
@ -14,59 +15,55 @@ tacan.tacanZones = {}
function tacan.createTacanZone(theZone) function tacan.createTacanZone(theZone)
theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, "onStart", true) theZone.onStart = theZone:getBoolFromZoneProperty("onStart", true)
local channels = cfxZones.getStringFromZoneProperty(theZone, "channel", "1") local channels = theZone:getStringFromZoneProperty("channel", "1")
theZone.channels = cfxZones.numberArrayFromString(channels, 1) theZone.channels = dcsCommon.numberArrayFromString(channels, 1)
if theZone.verbose or tacan.verbose then if theZone.verbose or tacan.verbose then
trigger.action.outText("+++tcn: new tacan <" .. theZone.name .. "> for channels [" .. dcsCommon.array2string(theZone.channels, ", ") .. "]", 30) trigger.action.outText("+++tcn: new tacan <" .. theZone.name .. "> for channels [" .. dcsCommon.array2string(theZone.channels, ", ") .. "]", 30)
end end
local mode = cfxZones.getStringFromZoneProperty(theZone, "mode", "X") local mode = theZone:getStringFromZoneProperty("mode", "X")
mode = string.upper(mode) mode = string.upper(mode)
theZone.modes = cfxZones.flagArrayFromString(mode) theZone.modes = dcsCommon.flagArrayFromString(mode)
if theZone.verbose or tacan.verbose then if theZone.verbose or tacan.verbose then
trigger.action.outText("+++tcn: modes [" .. dcsCommon.array2string(theZone.modes, ", ") .. "]", 30) trigger.action.outText("+++tcn: modes [" .. dcsCommon.array2string(theZone.modes, ", ") .. "]", 30)
end end
theZone.coa = theZone:getCoalitionFromZoneProperty("tacan", 0)
theZone.coa = cfxZones.getCoalitionFromZoneProperty(theZone, "tacan", 0) theZone.heading = theZone:getNumberFromZoneProperty("heading", 0)
theZone.heading = cfxZones.getNumberFromZoneProperty(theZone, "heading", 0)
theZone.heading = theZone.heading * 0.0174533 -- convert to rads theZone.heading = theZone.heading * 0.0174533 -- convert to rads
local callsign = cfxZones.getStringFromZoneProperty(theZone, "callsign", "TXN") local callsign = theZone:getStringFromZoneProperty("callsign", "TXN")
callsign = string.upper(callsign) callsign = string.upper(callsign)
theZone.callsigns = cfxZones.flagArrayFromString(callsign) theZone.callsigns = dcsCommon.flagArrayFromString(callsign)
if theZone.verbose or tacan.verbose then if theZone.verbose or tacan.verbose then
trigger.action.outText("+++tcn: callsigns [" .. dcsCommon.array2string(theZone.callsigns) .. "]", 30) trigger.action.outText("+++tcn: callsigns [" .. dcsCommon.array2string(theZone.callsigns) .. "]", 30)
end end
theZone.rndLoc = theZone:getBoolFromZoneProperty("rndLoc", false)
theZone.rndLoc = cfxZones.getBoolFromZoneProperty(theZone, "rndLoc", false) theZone.triggerMethod = theZone:getStringFromZoneProperty( "triggerMethod", "change")
-- theZone.method = cfxZones.getStringFromZoneProperty(theZone, "method", "inc") if theZone:hasProperty("deploy?") then
theZone.triggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change") theZone.deployFlag = theZone:getStringFromZoneProperty("deploy?", "<none>")
if cfxZones.hasProperty(theZone, "deploy?") then theZone.lastDeployFlagValue = theZone:getFlagValue(theZone.deployFlag)
theZone.deployFlag = cfxZones.getStringFromZoneProperty(theZone, "deploy?", "<none>")
theZone.lastDeployFlagValue = cfxZones.getFlagValue(theZone.deployFlag, theZone)
end end
if (not theZone.deployFlag) and (not theZone.onStart) then if (not theZone.deployFlag) and (not theZone.onStart) then
trigger.action.outText("+++tacan: WARNING: tacan zone <> is late activation and has no activation flag, will never activate.", 30) trigger.action.outText("+++tacan: WARNING: tacan zone <> is late activation and has no activation flag, will never activate.", 30)
end end
theZone.spawnedTACANS = {} -- for GC and List theZone.spawnedTACANS = {} -- for GC and List
theZone.preWipe = cfxZones.getBoolFromZoneProperty(theZone, "preWipe", true) theZone.preWipe = theZone:getBoolFromZoneProperty("preWipe", true)
if cfxZones.hasProperty(theZone, "destroy?") then if theZone:hasProperty("destroy?") then
theZone.destroyFlag = cfxZones.getStringFromZoneProperty(theZone, "destroy?", "<none>") theZone.destroyFlag = theZone:getStringFromZoneProperty( "destroy?", "<none>")
theZone.lastDestroyFlagValue = cfxZones.getFlagValue(theZone.destroyFlag, theZone) theZone.lastDestroyFlagValue = theZone:getFlagValue(theZone.destroyFlag)
end end
if cfxZones.hasProperty(theZone, "c#") then if theZone:hasProperty("c#") then
theZone.channelOut = cfxZones.getStringFromZoneProperty(theZone, "C#", "<none>") theZone.channelOut = theZone:getStringFromZoneProperty("C#", "<none>")
end end
theZone.announcer = cfxZones.getBoolFromZoneProperty(theZone, "announcer", false) theZone.announcer = theZone:getBoolFromZoneProperty("announcer", false)
-- interface to groupTracker -- interface to groupTracker
if cfxZones.hasProperty(theZone, "trackWith:") then if theZone:hasProperty("trackWith:") then
theZone.trackWith = cfxZones.getStringFromZoneProperty(theZone, "trackWith:", "<None>") theZone.trackWith = theZone:getStringFromZoneProperty( "trackWith:", "<None>")
end end
-- see if we need to deploy now -- see if we need to deploy now
@ -379,8 +376,8 @@ function tacan.readConfigZone()
tacan.verbose = theZone.verbose tacan.verbose = theZone.verbose
tacan.list = cfxZones.getBoolFromZoneProperty(theZone, "list", false) tacan.list = cfxZones.getBoolFromZoneProperty(theZone, "list", false)
if cfxZones.hasProperty(theZone, "GUI") then if theZone:hasProperty("GUI") then
tacan.list = cfxZones.getBoolFromZoneProperty(theZone, "GUI", false) tacan.list = theZone:getBoolFromZoneProperty("GUI", false)
end end
if tacan.verbose then if tacan.verbose then