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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,5 +1,5 @@
dcsCommon = {}
dcsCommon.version = "2.8.10"
dcsCommon.version = "2.9.0"
--[[-- VERSION HISTORY
2.2.6 - compassPositionOfARelativeToB
- clockPositionOfARelativeToB
@ -163,7 +163,11 @@ dcsCommon.version = "2.8.10"
- new getPlayerUnit()
- new getMapName()
- new getMagDeclForPoint()
2.9.0 - createPoint() moved from cfxZones
- copyPoint() moved from cfxZones
- numberArrayFromString() moved from cfxZones
--]]--
-- dcsCommon is a library of common lua functions
@ -2520,9 +2524,7 @@ end
--env.info("=== dcsCommon vardump END")
end
end
function dcsCommon.numberUUID()
dcsCommon.simpleUUID = dcsCommon.simpleUUID + 1
return dcsCommon.simpleUUID
@ -3025,6 +3027,53 @@ function dcsCommon.getMissionName()
return mn
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)
if not verbose then verbose = false end
@ -3475,6 +3524,31 @@ function dcsCommon.iteratePlayers(callBack)
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
--

View File

@ -1,10 +1,13 @@
flareZone = {}
flareZone.version = "1.0.0"
flareZone.version = "1.1.0"
flareZone.verbose = false
flareZone.name = "flareZone"
--[[-- VERSION HISTORY
1.0.0 - initial version
1.1.0 - improvements to verbosity
- OOP
- small bugfix in doFlare assignment
--]]--
flareZone.requiredLibs = {
"dcsCommon",
@ -13,40 +16,39 @@ flareZone.requiredLibs = {
flareZone.flares = {} -- all flare zones
function flareZone.addFlareZone(theZone)
theZone.flareColor = cfxZones.getFlareColorStringFromZoneProperty(theZone, "flare", "green")
theZone.flareColor = theZone:getFlareColorStringFromZoneProperty("flare", "green")
theZone.flareColor = dcsCommon.flareColor2Num(theZone.flareColor)
if cfxZones.hasProperty(theZone, "f?") then
cfxZones.theZone.doFlare = cfxZones.getStringFromZoneProperty(theZone, "f?", "<none>")
elseif cfxZones.hasProperty(theZone, "launchFlare?") then
theZone.doFlare = cfxZones.getStringFromZoneProperty(theZone, "launchFlare?", "<none>")
if theZone:hasProperty("f?") then
theZone.doFlare = theZone:getStringFromZoneProperty("f?", "<none>")
elseif theZone:hasProperty("launchFlare?") then
theZone.doFlare = theZone:getStringFromZoneProperty( "launchFlare?", "<none>")
else
theZone.doFlare = cfxZones.getStringFromZoneProperty(theZone, "launch?", "<none>")
theZone.doFlare = theZone:getStringFromZoneProperty("launch?", "<none>")
end
theZone.lastDoFlare = trigger.misc.getUserFlag(theZone.doFlare)
-- triggerMethod
theZone.flareTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
if cfxZones.hasProperty(theZone, "flareTriggerMethod") then
theZone.flareTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "flareTriggerMethod", "change")
theZone.flareTriggerMethod = theZone:getStringFromZoneProperty("triggerMethod", "change")
if theZone:hasProperty("flareTriggerMethod") then
theZone.flareTriggerMethod = theZone:getStringFromZoneProperty("flareTriggerMethod", "change")
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'
if cfxZones.hasProperty(theZone, "azimuth") then
theZone.azimuthL, theZone.azimuthH = cfxZones.getPositiveRangeFromZoneProperty(theZone, "azimuth", 90) -- in degrees
if theZone:hasProperty("azimuth") then
theZone.azimuthL, theZone.azimuthH = theZone:getPositiveRangeFromZoneProperty("azimuth", 90) -- in degrees
end
-- theZone.azimuth = theZone.azimuth * 0.0174533 -- rads
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "altitude", 1)
if cfxZones.hasProperty(theZone, "alt") then
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "alt", 1)
elseif cfxZones.hasProperty(theZone, "flareAlt") then
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "flareAlt", 1)
elseif cfxZones.hasProperty(theZone, "agl") then
theZone.flareAlt = cfxZones.getNumberFromZoneProperty(theZone, "agl", 1)
theZone.flareAlt = theZone:getNumberFromZoneProperty("altitude", 1)
if theZone:hasProperty("alt") then
theZone.flareAlt = theZone:getNumberFromZoneProperty("alt", 1)
elseif theZone:hasProperty("flareAlt") then
theZone.flareAlt = theZone:getNumberFromZoneProperty("flareAlt", 1)
elseif theZone:hasProperty("agl") then
theZone.flareAlt = theZone:getNumberFromZoneProperty("agl", 1)
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
trigger.action.outText("+++flrZ: new flare <" .. theZone.name .. ">, color (" .. theZone.flareColor .. ")", 30)
@ -57,13 +59,17 @@ end
function flareZone.launch(theZone)
local color = theZone.flareColor
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
loc.y = loc.y + theZone.flareAlt
-- 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)
end

View File

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

View File

@ -1,5 +1,5 @@
radioMenu = {}
radioMenu.version = "2.0.1"
radioMenu.version = "2.1.0"
radioMenu.verbose = false
radioMenu.ups = 1
radioMenu.requiredLibs = {
@ -10,23 +10,27 @@ radioMenu.menus = {}
--[[--
Version History
1.0.0 Initial version
1.0.1 spelling corrections
1.1.0 removeMenu
addMenu
menuVisible
2.0.0 redesign: handles multiple receivers
optional MX module
group option
type option
multiple group names
multiple types
gereric helo type
generic plane type
type works with coalition
2.0.1 corrections to installMenu(), as suggested by GumidekCZ
1.0.0 - Initial version
1.0.1 - spelling corrections
1.1.0 - removeMenu
addMenu
menuVisible
2.0.0 - redesign: handles multiple receivers
optional MX module
group option
type option
multiple group names
multiple types
gereric helo type
generic plane type
type works with coalition
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)
@ -183,8 +187,8 @@ function radioMenu.installMenu(theZone)
theZone.rootMenu[0] = missionCommands.addSubMenuForCoalition(theZone.coalition, theZone.rootName, nil)
end
if cfxZones.hasProperty(theZone, "itemA") then
local menuA = cfxZones.getStringFromZoneProperty(theZone, "itemA", "<no A submenu>")
if theZone:hasProperty("itemA") then
local menuA = theZone:getStringFromZoneProperty("itemA", "<no A submenu>")
if theZone.menuGroup or theZone.menuTypes then
theZone.menuA = {}
for idx, grp in pairs(gID) do
@ -197,8 +201,8 @@ function radioMenu.installMenu(theZone)
end
end
if cfxZones.hasProperty(theZone, "itemB") then
local menuB = cfxZones.getStringFromZoneProperty(theZone, "itemB", "<no B submenu>")
if theZone:hasProperty("itemB") then
local menuB = theZone:getStringFromZoneProperty("itemB", "<no B submenu>")
if theZone.menuGroup or theZone.menuTypes then
theZone.menuB = {}
for idx, grp in pairs(gID) do
@ -211,8 +215,8 @@ function radioMenu.installMenu(theZone)
end
end
if cfxZones.hasProperty(theZone, "itemC") then
local menuC = cfxZones.getStringFromZoneProperty(theZone, "itemC", "<no C submenu>")
if theZone:hasProperty("itemC") then
local menuC = theZone:getStringFromZoneProperty("itemC", "<no C submenu>")
if theZone.menuGroup or theZone.menuTypes then
theZone.menuC = {}
for idx, grp in pairs(gID) do
@ -225,8 +229,8 @@ function radioMenu.installMenu(theZone)
end
end
if cfxZones.hasProperty(theZone, "itemD") then
local menuD = cfxZones.getStringFromZoneProperty(theZone, "itemD", "<no D submenu>")
if theZone:hasProperty("itemD") then
local menuD = theZone:getStringFromZoneProperty("itemD", "<no D submenu>")
if theZone.menuGroup or theZone.menuTypes then
theZone.menuD = {}
for idx, grp in pairs(gID) do
@ -241,23 +245,23 @@ function radioMenu.installMenu(theZone)
end
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
if cfxZones.hasProperty(theZone, "group") then
theZone.menuGroup = cfxZones.getStringFromZoneProperty(theZone, "group", "<none>")
if theZone:hasProperty("group") then
theZone.menuGroup = theZone:getStringFromZoneProperty("group", "<none>")
theZone.menuGroup = dcsCommon.trim(theZone.menuGroup)
elseif cfxZones.hasProperty(theZone, "groups") then
theZone.menuGroup = cfxZones.getStringFromZoneProperty(theZone, "groups", "<none>")
elseif theZone:hasProperty("groups") then
theZone.menuGroup = theZone:getStringFromZoneProperty("groups", "<none>")
theZone.menuGroup = dcsCommon.trim(theZone.menuGroup)
elseif cfxZones.hasProperty(theZone, "type") then
theZone.menuTypes = cfxZones.getStringFromZoneProperty(theZone, "type", "none")
elseif cfxZones.hasProperty(theZone, "types") then
theZone.menuTypes = cfxZones.getStringFromZoneProperty(theZone, "types", "none")
elseif theZone:hasProperty("type") then
theZone.menuTypes = theZone:getStringFromZoneProperty("type", "none")
elseif theZone:hasProperty("types") then
theZone.menuTypes = theZone:getStringFromZoneProperty("types", "none")
end
theZone.menuVisible = cfxZones.getBoolFromZoneProperty(theZone, "menuVisible", true)
theZone.menuVisible = theZone:getBoolFromZoneProperty("menuVisible", true)
-- install menu if not hidden
if theZone.menuVisible then
@ -265,41 +269,62 @@ function radioMenu.createRadioMenuWithZone(theZone)
end
-- get the triggers & methods here
theZone.radioMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "inc")
if cfxZones.hasProperty(theZone, "radioMethod") then
theZone.radioMethod = cfxZones.getStringFromZoneProperty(theZone, "radioMethod", "inc")
theZone.radioMethod = theZone:getStringFromZoneProperty("method", "inc")
if theZone:hasProperty("radioMethod") then
theZone.radioMethod = theZone:getStringFromZoneProperty( "radioMethod", "inc")
end
theZone.radioTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "radioTriggerMethod", "change")
theZone.radioTriggerMethod = theZone:getStringFromZoneProperty("radioTriggerMethod", "change")
theZone.itemAChosen = cfxZones.getStringFromZoneProperty(theZone, "A!", "*<none>")
theZone.cooldownA = cfxZones.getNumberFromZoneProperty(theZone, "cooldownA", 0)
--theZone.mcdA = 0
theZone.busyA = cfxZones.getStringFromZoneProperty(theZone, "busyA", "Please stand by (<s> seconds)")
theZone.itemBChosen = cfxZones.getStringFromZoneProperty(theZone, "B!", "*<none>")
theZone.cooldownB = cfxZones.getNumberFromZoneProperty(theZone, "cooldownB", 0)
--theZone.mcdB = 0
theZone.busyB = cfxZones.getStringFromZoneProperty(theZone, "busyB", "Please stand by (<s> seconds)")
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)
-- A! to D!
theZone.itemAChosen = theZone:getStringFromZoneProperty("A!", "*<none>")
theZone.cooldownA = theZone:getNumberFromZoneProperty("cooldownA", 0)
theZone.busyA = theZone:getStringFromZoneProperty("busyA", "Please stand by (<s> seconds)")
if theZone:hasProperty("valA") then
theZone.outValA = theZone:getStringFromZoneProperty("valA", 1)
end
if theZone:hasProperty("ackA") then
theZone.ackA = theZone:getStringFromZoneProperty("ackA", "Acknowledged: A")
end
if cfxZones.hasProperty(theZone, "addMenu?") then
theZone.addMenu = cfxZones.getStringFromZoneProperty(theZone, "addMenu?", "*<none>")
theZone.lastAddMenu = cfxZones.getFlagValue(theZone.addMenu, theZone)
theZone.itemBChosen = theZone:getStringFromZoneProperty("B!", "*<none>")
theZone.cooldownB = theZone:getNumberFromZoneProperty("cooldownB", 0)
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
if radioMenu.verbose or theZone.verbose then
@ -326,6 +351,28 @@ function radioMenu.processHMS(msg, delta)
return dcsCommon.processHMS(msg, delta)
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
@ -360,20 +407,28 @@ function radioMenu.doMenuX(args)
local cd = radioMenu.cdByGID(theZone.mcdA, theZone, theGroup) --theZone.mcdA
local busy = theZone.busyA
local theFlag = theZone.itemAChosen
local outVal = theZone.outValA
local ack = theZone.ackA
-- decode A..X
if theItemIndex == "B"then
cd = radioMenu.cdByGID(theZone.mcdB, theZone, theGroup) -- theZone.mcdB
busy = theZone.busyB
theFlag = theZone.itemBChosen
outVal = theZone.outValB
ack = theZone.ackB
elseif theItemIndex == "C" then
cd = radioMenu.cdByGID(theZone.mcdC, theZone, theGroup) -- theZone.mcdC
busy = theZone.busyC
theFlag = theZone.itemCChosen
outVal = theZone.outValC
ack = theZone.ackC
elseif theItemIndex == "D" then
cd = radioMenu.cdByGID(theZone.mcdD, theZone, theGroup) -- theZone.mcdD
busy = theZone.busyD
theFlag = theZone.itemDChosen
outVal = theZone.outValD
ack = theZone.ackD
end
-- see if we are on cooldown
@ -381,8 +436,15 @@ function radioMenu.doMenuX(args)
if now < cd then
-- we are on cooldown.
local msg = radioMenu.processHMS(busy, cd - now)
radioMenu.radioOutMessage(msg, theZone)
radioMenu.radioOutMsg(msg, theGroup, theZone)
--radioMenu.radioOutMessage(msg, theZone)
return
else
-- see if we have an acknowledge
if ack then
local gid = theGroup
radioMenu.radioOutMsg(ack, gid, theZone)
end
end
-- set new cooldown -- needs own decoder A..X
@ -393,14 +455,23 @@ function radioMenu.doMenuX(args)
elseif theItemIndex == "C" then
radioMenu.setCDByGID("mcdC", theZone, theGroup, now + theZone.cooldownC)
else
radioMenu.setCDByGID("mcdC", theZone, theGroup, now + theZone.cooldownC)
radioMenu.setCDByGID("mcdD", theZone, theGroup, now + theZone.cooldownD)
end
cfxZones.pollFlag(theFlag, theZone.radioMethod, theZone)
if theZone.verbose or radioMenu.verbose then
trigger.action.outText("+++menu: banging with <" .. theZone.radioMethod .. "> on <" .. theFlag .. "> for " .. theZone.name, 30)
end
-- 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
trigger.action.outText("+++menu: banging with <" .. theZone.radioMethod .. "> on <" .. theFlag .. "> for " .. theZone.name, 30)
end
end
end
--
@ -413,7 +484,7 @@ function radioMenu.update()
-- iterate all menus
for idx, theZone in pairs(radioMenu.menus) do
if theZone.removeMenu
and cfxZones.testZoneFlag(theZone, theZone.removeMenu, theZone.radioTriggerMethod, "lastRemoveMenu")
and theZone:testZoneFlag(theZone.removeMenu, theZone.radioTriggerMethod, "lastRemoveMenu")
and theZone.menuVisible
then
if theZone.menuGroup or theZone.menuTypes then
@ -430,7 +501,7 @@ function radioMenu.update()
end
if theZone.addMenu
and cfxZones.testZoneFlag(theZone, theZone.addMenu, theZone.radioTriggerMethod, "lastAddMenu")
and theZone:testZoneFlag(theZone.addMenu, theZone.radioTriggerMethod, "lastAddMenu")
and (not theZone.menuVisible)
then
if theZone.verbose or radioMenu.verbose then
@ -453,10 +524,10 @@ function radioMenu.readConfigZone()
if radioMenu.verbose then
trigger.action.outText("+++radioMenu: NO config zone!", 30)
end
return
theZone = cfxZones.createSimpleZone("radioMenuConfig")
end
radioMenu.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
radioMenu.verbose = theZone:getBoolFromZoneProperty("verbose", false)
if radioMenu.verbose then
trigger.action.outText("+++radioMenu: read config", 30)

View File

@ -1,5 +1,5 @@
stopGap = {}
stopGap.version = "1.0.6"
stopGap.version = "1.0.7"
stopGap.verbose = false
stopGap.ssbEnabled = true
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.5 - triggerMethod
1.0.6 - spIgnore '-sp'
1.0.7 - migrated to OOP zones
- corrected ssbEnabled config from sbb to ssb
--]]--
stopGap.standInGroups = {}
@ -250,7 +252,8 @@ function stopGap.update()
end
-- 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
stopGap.turnOn()
end
@ -328,12 +331,12 @@ end
-- read stopGapZone
--
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
end
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
end
@ -344,17 +347,17 @@ stopGap.name = "stopGapConfig" -- cfxZones compatibility here
function stopGap.readConfigZone(theZone)
-- currently nothing to do
stopGap.verbose = theZone.verbose
stopGap.ssbEnabled = cfxZones.getBoolFromZoneProperty(theZone, "sbb", true)
stopGap.enabled = cfxZones.getBoolFromZoneProperty(theZone, "onStart", true)
if cfxZones.hasProperty(theZone, "on?") then
stopGap.turnOnFlag = cfxZones.getStringFromZoneProperty(theZone, "on?", "*<none>")
stopGap.ssbEnabled = theZone:getBoolFromZoneProperty("ssb", true)
stopGap.enabled = theZone:getBoolFromZoneProperty("onStart", true)
if theZone:hasProperty("on?") then
stopGap.turnOnFlag = theZone:getStringFromZoneProperty("on?", "*<none>")
stopGap.lastTurnOnFlag = trigger.misc.getUserFlag(stopGap.turnOnFlag)
end
if cfxZones.hasProperty(theZone, "off?") then
stopGap.turnOffFlag = cfxZones.getStringFromZoneProperty(theZone, "off?", "*<none>")
if theZone:hasProperty("off?") then
stopGap.turnOffFlag = theZone:getStringFromZoneProperty("off?", "*<none>")
stopGap.lastTurnOffFlag = trigger.misc.getUserFlag(stopGap.turnOffFlag)
end
stopGap.triggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
stopGap.triggerMethod = theZone:getStringFromZoneProperty( "triggerMethod", "change")
if stopGap.verbose then
trigger.action.outText("+++StopG: config read, verbose = YES", 30)
if stopGap.enabled then

View File

@ -1,8 +1,9 @@
tacan = {}
tacan.version = "1.0.0"
tacan.version = "1.1.0"
--[[--
Version History
1.0.0 - initial version
1.1.0 - OOP cfxZones
--]]--
tacan.verbose = false
@ -14,59 +15,55 @@ tacan.tacanZones = {}
function tacan.createTacanZone(theZone)
theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, "onStart", true)
local channels = cfxZones.getStringFromZoneProperty(theZone, "channel", "1")
theZone.channels = cfxZones.numberArrayFromString(channels, 1)
theZone.onStart = theZone:getBoolFromZoneProperty("onStart", true)
local channels = theZone:getStringFromZoneProperty("channel", "1")
theZone.channels = dcsCommon.numberArrayFromString(channels, 1)
if theZone.verbose or tacan.verbose then
trigger.action.outText("+++tcn: new tacan <" .. theZone.name .. "> for channels [" .. dcsCommon.array2string(theZone.channels, ", ") .. "]", 30)
end
local mode = cfxZones.getStringFromZoneProperty(theZone, "mode", "X")
local mode = theZone:getStringFromZoneProperty("mode", "X")
mode = string.upper(mode)
theZone.modes = cfxZones.flagArrayFromString(mode)
theZone.modes = dcsCommon.flagArrayFromString(mode)
if theZone.verbose or tacan.verbose then
trigger.action.outText("+++tcn: modes [" .. dcsCommon.array2string(theZone.modes, ", ") .. "]", 30)
end
theZone.coa = cfxZones.getCoalitionFromZoneProperty(theZone, "tacan", 0)
theZone.heading = cfxZones.getNumberFromZoneProperty(theZone, "heading", 0)
theZone.coa = theZone:getCoalitionFromZoneProperty("tacan", 0)
theZone.heading = theZone:getNumberFromZoneProperty("heading", 0)
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)
theZone.callsigns = cfxZones.flagArrayFromString(callsign)
theZone.callsigns = dcsCommon.flagArrayFromString(callsign)
if theZone.verbose or tacan.verbose then
trigger.action.outText("+++tcn: callsigns [" .. dcsCommon.array2string(theZone.callsigns) .. "]", 30)
end
theZone.rndLoc = cfxZones.getBoolFromZoneProperty(theZone, "rndLoc", false)
-- theZone.method = cfxZones.getStringFromZoneProperty(theZone, "method", "inc")
theZone.triggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
if cfxZones.hasProperty(theZone, "deploy?") then
theZone.deployFlag = cfxZones.getStringFromZoneProperty(theZone, "deploy?", "<none>")
theZone.lastDeployFlagValue = cfxZones.getFlagValue(theZone.deployFlag, theZone)
theZone.rndLoc = theZone:getBoolFromZoneProperty("rndLoc", false)
theZone.triggerMethod = theZone:getStringFromZoneProperty( "triggerMethod", "change")
if theZone:hasProperty("deploy?") then
theZone.deployFlag = theZone:getStringFromZoneProperty("deploy?", "<none>")
theZone.lastDeployFlagValue = theZone:getFlagValue(theZone.deployFlag)
end
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)
end
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
theZone.destroyFlag = cfxZones.getStringFromZoneProperty(theZone, "destroy?", "<none>")
theZone.lastDestroyFlagValue = cfxZones.getFlagValue(theZone.destroyFlag, theZone)
if theZone:hasProperty("destroy?") then
theZone.destroyFlag = theZone:getStringFromZoneProperty( "destroy?", "<none>")
theZone.lastDestroyFlagValue = theZone:getFlagValue(theZone.destroyFlag)
end
if cfxZones.hasProperty(theZone, "c#") then
theZone.channelOut = cfxZones.getStringFromZoneProperty(theZone, "C#", "<none>")
if theZone:hasProperty("c#") then
theZone.channelOut = theZone:getStringFromZoneProperty("C#", "<none>")
end
theZone.announcer = cfxZones.getBoolFromZoneProperty(theZone, "announcer", false)
theZone.announcer = theZone:getBoolFromZoneProperty("announcer", false)
-- interface to groupTracker
if cfxZones.hasProperty(theZone, "trackWith:") then
theZone.trackWith = cfxZones.getStringFromZoneProperty(theZone, "trackWith:", "<None>")
if theZone:hasProperty("trackWith:") then
theZone.trackWith = theZone:getStringFromZoneProperty( "trackWith:", "<None>")
end
-- see if we need to deploy now
@ -379,8 +376,8 @@ function tacan.readConfigZone()
tacan.verbose = theZone.verbose
tacan.list = cfxZones.getBoolFromZoneProperty(theZone, "list", false)
if cfxZones.hasProperty(theZone, "GUI") then
tacan.list = cfxZones.getBoolFromZoneProperty(theZone, "GUI", false)
if theZone:hasProperty("GUI") then
tacan.list = theZone:getBoolFromZoneProperty("GUI", false)
end
if tacan.verbose then