mirror of
https://github.com/weyne85/DML.git
synced 2025-10-29 16:57:49 +00:00
Version 0.96
rndZone, pulseZone
This commit is contained in:
parent
bcf319b0df
commit
46193f0ba3
Binary file not shown.
@ -1,17 +1,21 @@
|
||||
FARPZones = {}
|
||||
FARPZones.version = "1.0.2"
|
||||
FARPZones.version = "1.1.0"
|
||||
FARPZones.verbose = false
|
||||
--[[--
|
||||
Version History
|
||||
1.0.0 - Initial Version
|
||||
1.0.1 - support "none" as defender types
|
||||
- default types for defenders to none
|
||||
1.0.2 - hiddenRed, hiddenBlue, hiddenGrey
|
||||
1.1.0 - config zone
|
||||
- rFormation attribute added
|
||||
- verbose flag
|
||||
- verbose cleanup ("FZ: something happened")
|
||||
|
||||
--]]--
|
||||
|
||||
FARPZones.requiredLibs = {
|
||||
"dcsCommon", -- common is of course needed for everything
|
||||
-- pretty stupid to check for this since we
|
||||
-- need common to invoke the check, but anyway
|
||||
"dcsCommon",
|
||||
"cfxZones", -- Zones, of course
|
||||
-- "cfxCommander", -- to make troops do stuff
|
||||
-- "cfxGroundTroops", -- generic when dropping troops
|
||||
@ -134,25 +138,29 @@ function FARPZones.createFARPFromZone(aZone)
|
||||
aZone,
|
||||
"rPhiHDef",
|
||||
3)
|
||||
-- trigger.action.outText("*** DEF rPhi are " .. rPhi[1] .. " and " .. rPhi[2], 30)
|
||||
--trigger.action.outText("*** DEF rPhi are " .. rPhi[1] .. " and " .. rPhi[2] .. " heading " .. rPhi[3], 30)
|
||||
-- get r and phi for facilities
|
||||
-- create a new defenderzone for this
|
||||
local r = rPhi[1]
|
||||
local phi = rPhi[2] * 0.0174533 -- 1 degree = 0.0174533 rad
|
||||
local dx = aZone.point.x + r * math.cos(phi)
|
||||
local dz = aZone.point.z + r * math.sin(phi)
|
||||
theFarp.defZone = cfxZones.createSimpleZone(aZone.name .. "-Def", {x=dx, y = 0, z=dz}, 100)
|
||||
local formRad = cfxZones.getNumberFromZoneProperty(aZone, "rFormation", 100)
|
||||
|
||||
theFarp.defZone = cfxZones.createSimpleZone(aZone.name .. "-Def", {x=dx, y = 0, z=dz}, formRad)
|
||||
theFarp.defHeading = rPhi[3]
|
||||
|
||||
rPhi = {}
|
||||
rPhi = cfxZones.getVectorFromZoneProperty(
|
||||
aZone,
|
||||
"rPhiHRes",
|
||||
3) -- optional, will reterurn {0,0} else
|
||||
-- trigger.action.outText("*** RES rPhi are " .. rPhi[1] .. " and " .. rPhi[2] .. " heading " .. rPhi[3], 30)
|
||||
3)
|
||||
--trigger.action.outText("*** RES rPhi are " .. rPhi[1] .. " and " .. rPhi[2] .. " heading " .. rPhi[3], 30)
|
||||
r = rPhi[1]
|
||||
phi = rPhi[2] * 0.0174533 -- 1 degree = 0.0174533 rad
|
||||
dx = aZone.point.x + r * math.cos(phi)
|
||||
dz = aZone.point.z + r * math.sin(phi)
|
||||
|
||||
theFarp.resZone = cfxZones.createSimpleZone(aZone.name .. "-Res", {x=dx, y = 0, z=dz}, 50)
|
||||
theFarp.resHeading = rPhi[3]
|
||||
|
||||
@ -307,7 +315,10 @@ function FARPZones.produceVehicles(theFarp)
|
||||
table.insert(unitTypes, "Soldier M4") -- make it one m4 trooper as fallback
|
||||
end
|
||||
|
||||
-- trigger.action.outText("*** ENTER produce vehicles, will produce " .. theTypes , 30)
|
||||
if FARPZones.verbose then
|
||||
trigger.action.outText("*** ENTER produce DEF vehicles, will produce " .. theTypes , 30)
|
||||
end
|
||||
|
||||
local theCoalition = theFarp.owner
|
||||
|
||||
if theTypes ~= "none" then
|
||||
@ -364,12 +375,14 @@ function FARPZones.somethingHappened(event)
|
||||
local theUnit = event.initiator
|
||||
local ID = event.id
|
||||
|
||||
trigger.action.outText("FZ: something happened", 30)
|
||||
--trigger.action.outText("FZ: something happened", 30)
|
||||
local aFarp = event.place
|
||||
local zonedFarp = FARPZones.getFARPZoneForFARP(aFarp)
|
||||
|
||||
if not zonedFarp then
|
||||
if FARPZones.verbose then
|
||||
trigger.action.outText("Hand change, NOT INTERESTING", 30)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
@ -380,9 +393,7 @@ function FARPZones.somethingHappened(event)
|
||||
trigger.action.outSound("Quest Snare 3.wav")
|
||||
zonedFarp.owner = newOwner
|
||||
zonedFarp.zone.owner = newOwner
|
||||
-- better: sound winm and lose to different sides
|
||||
-- update color in map
|
||||
-- FARPZones.drawFarp(zonedFarp)
|
||||
FARPZones.drawFARPCircleInMap(zonedFarp)
|
||||
|
||||
-- remove all existing resources immediately,
|
||||
@ -406,6 +417,23 @@ end
|
||||
--
|
||||
-- Start
|
||||
--
|
||||
function FARPZones.readConfig()
|
||||
local theZone = cfxZones.getZoneByName("farpZonesConfig")
|
||||
if not theZone then
|
||||
if FARPZones.verbose then
|
||||
trigger.action.outText("***frpZ: NO config zone!", 30)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
FARPZones.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
|
||||
|
||||
FARPZones.spinUpDelay = cfxZones.getNumberFromZoneProperty(theZone, "spinUpDelay", 30)
|
||||
|
||||
if FARPZones.verbose then
|
||||
trigger.action.outText("***frpZ: read config", 30)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function FARPZones.start()
|
||||
@ -417,6 +445,9 @@ function FARPZones.start()
|
||||
|
||||
FARPZones.startingUp = true
|
||||
|
||||
-- read config zone
|
||||
FARPZones.readConfig()
|
||||
|
||||
-- install callbacks for FARP-relevant events
|
||||
dcsCommon.addEventHandler(FARPZones.somethingHappened,
|
||||
FARPZones.preProcessor,
|
||||
@ -427,10 +458,11 @@ function FARPZones.start()
|
||||
for k, aZone in pairs(theZones) do
|
||||
local aFARP = FARPZones.createFARPFromZone(aZone) -- read attributes from DCS
|
||||
FARPZones.addFARPZone(aFARP) -- add to managed zones
|
||||
-- FARPZones.drawFarp(aFARP)
|
||||
FARPZones.drawFARPCircleInMap(aFARP) -- mark in map
|
||||
FARPZones.produceVehicles(aFARP) -- allocate initial vehicles
|
||||
--trigger.action.outText("processed FARP " .. aZone.name .. " now owned by " .. aZone.owner, 30)
|
||||
if FARPZones.verbose then
|
||||
trigger.action.outText("processed FARP <" .. aZone.name .. "> now owned by " .. aZone.owner, 30)
|
||||
end
|
||||
end
|
||||
|
||||
FARPZones.startingUp = false
|
||||
|
||||
350
modules/RNDFlags.lua
Normal file
350
modules/RNDFlags.lua
Normal file
@ -0,0 +1,350 @@
|
||||
rndFlags = {}
|
||||
rndFlags.version = "1.0.0"
|
||||
rndFlags.verbose = false
|
||||
rndFlags.requiredLibs = {
|
||||
"dcsCommon", -- always
|
||||
"cfxZones", -- Zones, of course
|
||||
}
|
||||
--[[
|
||||
Random Flags: DML module to select flags at random
|
||||
and then change them
|
||||
|
||||
Copyright 2022 by Christian Franz and cf/x
|
||||
|
||||
Version History
|
||||
1.0.0 - Initial Version
|
||||
|
||||
--]]
|
||||
rndFlags.rndGen = {}
|
||||
|
||||
function rndFlags.addRNDZone(aZone)
|
||||
table.insert(rndFlags.rndGen, aZone)
|
||||
end
|
||||
|
||||
function rndFlags.flagArrayFromString(inString)
|
||||
if string.len(inString) < 1 then
|
||||
trigger.action.outText("+++RND: empty flags", 30)
|
||||
return {}
|
||||
end
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("+++RND: processing <" .. inString .. ">", 30)
|
||||
end
|
||||
|
||||
local flags = {}
|
||||
local rawElements = dcsCommon.splitString(inString, ",")
|
||||
|
||||
for idx, anElement in pairs(rawElements) do
|
||||
if 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, f)
|
||||
--trigger.action.outText("+++RND: added <" .. f .. "> (range)", 30)
|
||||
end
|
||||
else
|
||||
-- bounds illegal
|
||||
trigger.action.outText("+++RND: ignored range <" .. anElement .. "> (range)", 30)
|
||||
end
|
||||
else
|
||||
-- single number
|
||||
f = tonumber(anElement)
|
||||
if f then
|
||||
table.insert(flags, f)
|
||||
--trigger.action.outText("+++RND: added <" .. f .. "> (single)", 30)
|
||||
else
|
||||
trigger.action.outText("+++RND: ignored element <" .. anElement .. "> (single)", 30)
|
||||
end
|
||||
end
|
||||
end
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("+++RND: <" .. #flags .. "> flags total", 30)
|
||||
end
|
||||
return flags
|
||||
end
|
||||
|
||||
--
|
||||
-- create rnd gen from zone
|
||||
--
|
||||
function rndFlags.createRNDWithZone(theZone)
|
||||
local flags = cfxZones.getStringFromZoneProperty(theZone, "flags!", "")
|
||||
if flags == "" then
|
||||
-- let's try alternate spelling without "!"
|
||||
flags = cfxZones.getStringFromZoneProperty(theZone, "flags", "")
|
||||
end
|
||||
-- now build the flag array from strings
|
||||
local theFlags = rndFlags.flagArrayFromString(flags)
|
||||
theZone.myFlags = theFlags
|
||||
|
||||
|
||||
theZone.pollSizeMin, theZone.pollSize = cfxZones.getPositiveRangeFromZoneProperty(theZone, "pollSize", 1)
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("+++RND: pollSize is <" .. theZone.pollSizeMin .. ", " .. theZone.pollSize .. ">", 30)
|
||||
end
|
||||
|
||||
|
||||
theZone.remove = cfxZones.getBoolFromZoneProperty(theZone, "remove", false)
|
||||
|
||||
-- trigger flag
|
||||
if cfxZones.hasProperty(theZone, "f?") then
|
||||
theZone.triggerFlag = cfxZones.getStringFromZoneProperty(theZone, "f?", "none")
|
||||
end
|
||||
|
||||
if theZone.triggerFlag then
|
||||
theZone.lastTriggerValue = trigger.misc.getUserFlag(theZone.triggerFlag) -- save last value
|
||||
end
|
||||
|
||||
theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, "onStart", false)
|
||||
|
||||
if not theZone.onStart and not theZone.triggerFlag then
|
||||
theZone.onStart = true
|
||||
end
|
||||
|
||||
theZone.method = cfxZones.getStringFromZoneProperty(theZone, "method", "on")
|
||||
|
||||
theZone.reshuffle = cfxZones.getBoolFromZoneProperty(theZone, "reshuffle", false)
|
||||
if theZone.reshuffle then
|
||||
-- create a backup copy we can reshuffle from
|
||||
theZone.flagStore = dcsCommon.copyArray(theFlags)
|
||||
end
|
||||
|
||||
--theZone.rndPollSize = cfxZones.getBoolFromZoneProperty(theZone, "rndPollSize", false)
|
||||
|
||||
-- done flag
|
||||
if cfxZones.hasProperty(theZone, "done+1") then
|
||||
theZone.doneFlag = cfxZones.getStringFromZoneProperty(theZone, "done+1", "none")
|
||||
end
|
||||
end
|
||||
|
||||
function rndFlags.reshuffle(theZone)
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("+++RND: reshuffling zone " .. theZone.name, 30)
|
||||
end
|
||||
theZone.myFlags = dcsCommon.copyArray(theZone.flagStore)
|
||||
end
|
||||
|
||||
--
|
||||
-- fire RND
|
||||
--
|
||||
function rndFlags.pollFlag(theFlag, method)
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("+++RND: polling flag " .. theFlag .. " with " .. method, 30)
|
||||
end
|
||||
|
||||
method = method:lower()
|
||||
local currVal = trigger.misc.getUserFlag(theFlag)
|
||||
if method == "inc" or method == "f+1" then
|
||||
trigger.action.setUserFlag(theFlag, currVal + 1)
|
||||
|
||||
elseif method == "dec" or method == "f-1" then
|
||||
trigger.action.setUserFlag(theFlag, currVal - 1)
|
||||
|
||||
elseif method == "off" or method == "f=0" then
|
||||
trigger.action.setUserFlag(theFlag, 0)
|
||||
|
||||
elseif method == "flip" or method == "xor" then
|
||||
if currVal ~= 0 then
|
||||
trigger.action.setUserFlag(theFlag, 0)
|
||||
else
|
||||
trigger.action.setUserFlag(theFlag, 1)
|
||||
end
|
||||
|
||||
else
|
||||
if method ~= "on" and method ~= "f=1" then
|
||||
trigger.action.outText("+++RND: unknown method <" .. method .. "> - using 'on'", 30)
|
||||
end
|
||||
-- default: on.
|
||||
trigger.action.setUserFlag(theFlag, 1)
|
||||
end
|
||||
|
||||
local newVal = trigger.misc.getUserFlag(theFlag)
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("+++RND: flag <" .. theFlag .. "> changed from " .. currVal .. " to " .. newVal, 30)
|
||||
end
|
||||
end
|
||||
|
||||
function rndFlags.fire(theZone)
|
||||
-- fire this rnd
|
||||
-- create a local copy of all flags
|
||||
if theZone.reshuffle and #theZone.myFlags < 1 then
|
||||
rndFlags.reshuffle(theZone)
|
||||
end
|
||||
|
||||
local availableFlags = dcsCommon.copyArray(theZone.myFlags)--{}
|
||||
-- for idx, aFlag in pairs(theZone.myFlags) do
|
||||
-- table.insert(availableFlags, aFlag)
|
||||
-- end
|
||||
|
||||
-- do this pollSize times
|
||||
local pollSize = theZone.pollSize
|
||||
local pollSizeMin = theZone.pollSizeMin
|
||||
|
||||
if pollSize ~= pollSizeMin then
|
||||
-- pick random in range , say 3-7 --> 5 items!
|
||||
pollSize = (pollSize - pollSizeMin) + 1 -- 7-3 + 1
|
||||
pollSize = dcsCommon.smallRandom(pollSize) - 1 --> 0-4
|
||||
-- trigger.action.outText("+++RND: RAW pollsize " .. pollSize, 30)
|
||||
pollSize = pollSize + pollSizeMin
|
||||
-- trigger.action.outText("+++RND: adj pollsize " .. pollSize, 30)
|
||||
if pollSize > theZone.pollSize then pollSize = theZone.pollSize end
|
||||
if pollSize < 1 then pollSize = 1 end
|
||||
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("+++RND: RND " .. theZone.name .. " range " .. pollSizeMin .. "-" .. theZone.pollSize .. ": selected " .. pollSize, 30)
|
||||
end
|
||||
end
|
||||
|
||||
if #availableFlags < 1 then
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("+++RND: RND " .. theZone.name .. " ran out of flags. aborting fire", 30)
|
||||
end
|
||||
|
||||
if theZone.doneFlag then
|
||||
local currVal = trigger.misc.getUserFlag(theZone.doneFlag)
|
||||
trigger.action.setUserFlag(theZone.doneFlag, currVal + 1)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("+++RND: firing RND " .. theZone.name .. " with pollsize " .. pollSize .. " on " .. #availableFlags .. " set size", 30)
|
||||
end
|
||||
|
||||
for i=1, pollSize do
|
||||
-- check there are still flags left
|
||||
if #availableFlags < 1 then
|
||||
trigger.action.outText("+++RND: no flags left in " .. theZone.name .. " in index " .. i, 30)
|
||||
theZone.myFlags = {}
|
||||
if theZone.reshuffle then
|
||||
rndFlags.reshuffle(theZone)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- select a flag, enforce uniqueness
|
||||
local theFlagIndex = dcsCommon.smallRandom(#availableFlags)
|
||||
|
||||
-- poll this flag and remove from available
|
||||
local theFlag = table.remove(availableFlags,theFlagIndex)
|
||||
|
||||
rndFlags.pollFlag(theFlag, theZone.method)
|
||||
|
||||
end
|
||||
|
||||
-- remove if requested
|
||||
if theZone.remove then
|
||||
theZone.myFlags = availableFlags
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- update
|
||||
--
|
||||
function rndFlags.update()
|
||||
-- call me in a second to poll triggers
|
||||
timer.scheduleFunction(rndFlags.update, {}, timer.getTime() + 1)
|
||||
|
||||
for idx, aZone in pairs(rndFlags.rndGen) do
|
||||
if aZone.triggerFlag then
|
||||
local currTriggerVal = trigger.misc.getUserFlag(aZone.triggerFlag)
|
||||
if currTriggerVal ~= aZone.lastTriggerValue
|
||||
then
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("+++RND: triggering " .. aZone.name, 30)
|
||||
end
|
||||
rndFlags.fire(aZone)
|
||||
aZone.lastTriggerValue = currTriggerVal
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- start cycle: force all onStart to fire
|
||||
--
|
||||
function rndFlags.startCycle()
|
||||
for idx, theZone in pairs(rndFlags.rndGen) do
|
||||
if theZone.onStart then
|
||||
trigger.action.outText("+++RND: starting " .. theZone.name, 30)
|
||||
rndFlags.fire(theZone)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- start module and read config
|
||||
--
|
||||
function rndFlags.readConfigZone()
|
||||
-- note: must match exactly!!!!
|
||||
local theZone = cfxZones.getZoneByName("rndFlagsConfig")
|
||||
if not theZone then
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("***RND: NO config zone!", 30)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
rndFlags.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
|
||||
|
||||
if rndFlags.verbose then
|
||||
trigger.action.outText("***RND: read config", 30)
|
||||
end
|
||||
end
|
||||
|
||||
function rndFlags.start()
|
||||
-- lib check
|
||||
if not dcsCommon.libCheck then
|
||||
trigger.action.outText("RNDFlags requires dcsCommon", 30)
|
||||
return false
|
||||
end
|
||||
if not dcsCommon.libCheck("cfx Random Flags",
|
||||
rndFlags.requiredLibs) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- read config
|
||||
rndFlags.readConfigZone()
|
||||
|
||||
-- process RND Zones
|
||||
local attrZones = cfxZones.getZonesWithAttributeNamed("RND")
|
||||
|
||||
-- now create an rnd gen for each one and add them
|
||||
-- to our watchlist
|
||||
for k, aZone in pairs(attrZones) do
|
||||
rndFlags.createRNDWithZone(aZone) -- process attribute and add to zone
|
||||
rndFlags.addRNDZone(aZone) -- remember it so we can smoke it
|
||||
end
|
||||
|
||||
-- start cycle
|
||||
timer.scheduleFunction(rndFlags.startCycle, {}, timer.getTime() + 0.25)
|
||||
|
||||
-- start update
|
||||
timer.scheduleFunction(rndFlags.update, {}, timer.getTime() + 1)
|
||||
|
||||
trigger.action.outText("cfx random Flags v" .. rndFlags.version .. " started.", 30)
|
||||
return true
|
||||
end
|
||||
|
||||
-- let's go!
|
||||
if not rndFlags.start() then
|
||||
trigger.action.outText("cf/x RND Flags aborted: missing libraries", 30)
|
||||
rndFlags = nil
|
||||
end
|
||||
|
||||
--[[
|
||||
pulser / repeat until
|
||||
--]]
|
||||
@ -1,5 +1,5 @@
|
||||
cargoSuper = {}
|
||||
cargoSuper.version = "1.1.0"
|
||||
cargoSuper.version = "1.1.1"
|
||||
--[[--
|
||||
version history
|
||||
1.0.0 - initial version
|
||||
@ -13,6 +13,7 @@ version history
|
||||
- getAllCategoriesFor alias for getAllCargos
|
||||
- getManifestForCategory alias for getManifestFor
|
||||
- removeAllMassFor()
|
||||
1.1.1 - deleteMassObject corrected index bug
|
||||
|
||||
CargoSuper manages weigth for a logical named unit. Weight can be added
|
||||
to arbitrary categories like 'passengers', 'cargo' or "whatever". In order
|
||||
@ -68,7 +69,7 @@ function cargoSuper.deleteMassObject(massObject)
|
||||
else
|
||||
theName = massObject.name
|
||||
end
|
||||
cargoSuper.massObjects[massName] = nil
|
||||
cargoSuper.massObjects[theName] = nil -- 1.1.1 corrected to theName from massName
|
||||
end
|
||||
|
||||
function cargoSuper.addMassObjectTo(name, category, theMassObject)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
cfxNDB = {}
|
||||
cfxNDB.version = "1.0.0"
|
||||
cfxNDB.version = "1.1.0"
|
||||
|
||||
--[[--
|
||||
cfxNDB:
|
||||
@ -12,10 +12,20 @@ cfxNDB.version = "1.0.0"
|
||||
correctly if it's longer than the module's refresh and
|
||||
an even multiple of module's refresh, else it will be
|
||||
refreshed at the next module update cycle
|
||||
|
||||
VERSION HISTORY
|
||||
1.0.0 - initial version
|
||||
1.1.0 - on? flag
|
||||
- off? flag
|
||||
- ups at 1, decoupled update from refresh
|
||||
- paused flag, paused handling
|
||||
- startNDB() can accept string
|
||||
- stopNDB() can accept string
|
||||
|
||||
--]]--
|
||||
|
||||
cfxNDB.verbose = false
|
||||
cfxNDB.ups = 10 -- every 10 seconds
|
||||
cfxNDB.ups = 1 -- once every 1 second
|
||||
cfxNDB.requiredLibs = {
|
||||
"dcsCommon",
|
||||
"cfxZones",
|
||||
@ -30,6 +40,18 @@ cfxNDB.ndbs = {} -- all ndbs
|
||||
--
|
||||
|
||||
function cfxNDB.startNDB(theNDB)
|
||||
if type(theNDB) == "string" then
|
||||
theNDB = cfxZones.getZoneByName(theNDB)
|
||||
end
|
||||
|
||||
if not theNDB.freq then
|
||||
-- this zone is not an NDB. Exit
|
||||
if cfxNDB.verbose then
|
||||
trigger.action.outText("+++ndb: start() -- " .. theNDB.name .. " is not a cfxNDB.", 30)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
theNDB.ndbRefreshTime = timer.getTime() + theNDB.ndbRefresh -- only used in linkedUnit, but set up anyway
|
||||
-- generate new ID
|
||||
theNDB.ndbID = dcsCommon.uuid("ndb")
|
||||
@ -47,10 +69,31 @@ function cfxNDB.startNDB(theNDB)
|
||||
end
|
||||
trigger.action.outText("+++ndb: started " .. theNDB.name .. dsc .. " at " .. theNDB.freq/1000000 .. "mod " .. modulation .. " with w=" .. theNDB.power .. " s=<" .. fileName .. ">", 30)
|
||||
end
|
||||
theNDB.paused = false
|
||||
|
||||
if cfxNDB.verbose then
|
||||
trigger.action.outText("+++ndb: " .. theNDB.name .. " started", 30)
|
||||
end
|
||||
end
|
||||
|
||||
function cfxNDB.stopNDB(theNDB)
|
||||
if type(theNDB) == "string" then
|
||||
theNDB = cfxZones.getZoneByName(theNDB)
|
||||
end
|
||||
|
||||
if not theNDB.freq then
|
||||
-- this zone is not an NDB. Exit
|
||||
if cfxNDB.verbose then
|
||||
trigger.action.outText("+++ndb: stop() -- " .. theNDB.name .. " is not a cfxNDB.", 30)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
trigger.action.stopRadioTransmission(theNDB.ndbID)
|
||||
theNDB.paused = true
|
||||
if cfxNDB.verbose then
|
||||
trigger.action.outText("+++ndb: " .. theNDB.name .. " stopped", 30)
|
||||
end
|
||||
end
|
||||
|
||||
function cfxNDB.createNDBWithZone(theZone)
|
||||
@ -65,8 +108,31 @@ function cfxNDB.createNDBWithZone(theZone)
|
||||
-- when LARGER than module's refresh.
|
||||
theZone.ndbRefresh = cfxZones.getNumberFromZoneProperty(theZone, "ndbRefresh", cfxNDB.refresh) -- only used if linked
|
||||
theZone.ndbRefreshTime = timer.getTime() + theZone.ndbRefresh -- only used with linkedUnit, but set up nonetheless
|
||||
|
||||
-- paused
|
||||
theZone.paused = cfxZones.getBoolFromZoneProperty(theZone, "paused", false)
|
||||
|
||||
-- on/offf query flags
|
||||
if cfxZones.hasProperty(theZone, "on?") then
|
||||
theZone.onFlag = cfxZones.getStringFromZoneProperty(theZone, "on?", "none")
|
||||
end
|
||||
|
||||
if theZone.onFlag then
|
||||
theZone.onFlagVal = trigger.misc.getUserFlag(theZone.onFlag) -- save last value
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(theZone, "off?") then
|
||||
theZone.offFlag = cfxZones.getStringFromZoneProperty(theZone, "off?", "none")
|
||||
end
|
||||
|
||||
if theZone.offFlag then
|
||||
theZone.offFlagVal = trigger.misc.getUserFlag(theZone.offFlag) -- save last value
|
||||
end
|
||||
|
||||
-- start it
|
||||
if not theZone.paused then
|
||||
cfxNDB.startNDB(theZone)
|
||||
end
|
||||
|
||||
-- add it to my watchlist
|
||||
table.insert(cfxNDB.ndbs, theZone)
|
||||
@ -84,9 +150,30 @@ function cfxNDB.update()
|
||||
-- moving with the linked unit
|
||||
if theNDB.linkedUnit then
|
||||
-- yupp, need to update
|
||||
if now > theNDB.ndbRefreshTime then
|
||||
cfxNDB.stopNDB(theNDB)
|
||||
if (not theNDB.paused) and
|
||||
(now > theNDB.ndbRefreshTime) then
|
||||
cfxNDB.stopNDB(theNDB) -- also pauses
|
||||
cfxNDB.startNDB(theNDB) -- turns off pause
|
||||
end
|
||||
end
|
||||
|
||||
-- now check triggers to start/stop
|
||||
if theNDB.onFlagVal then
|
||||
-- see if this changed
|
||||
local currTriggerVal = trigger.misc.getUserFlag(theNDB.onFlag)
|
||||
if currTriggerVal ~= theNDB.onFlagVal then
|
||||
-- yupp, trigger start
|
||||
cfxNDB.startNDB(theNDB)
|
||||
theNDB.onFlagVal = currTriggerVal
|
||||
end
|
||||
end
|
||||
|
||||
if theNDB.offFlagVal then
|
||||
local currTriggerVal = trigger.misc.getUserFlag(theNDB.offFlag)
|
||||
if currTriggerVal ~= theNDB.offFlagVal then
|
||||
-- yupp, trigger start
|
||||
cfxNDB.stopNDB(theNDB)
|
||||
theNDB.offFlagVal = currTriggerVal
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
cfxObjectSpawnZones = {}
|
||||
cfxObjectSpawnZones.version = "1.1.3"
|
||||
cfxObjectSpawnZones.version = "1.1.4"
|
||||
cfxObjectSpawnZones.requiredLibs = {
|
||||
"dcsCommon", -- common is of course needed for everything
|
||||
-- pretty stupid to check for this since we
|
||||
@ -22,6 +22,7 @@ cfxObjectSpawnZones.ups = 1
|
||||
-- 1.1.2 - autoRemove option re-installed
|
||||
-- - added possibility to autoUnlink
|
||||
-- 1.1.3 - ME-triggered flag via f? and triggerFlag
|
||||
-- 1.1.4 - activate?, pause? attributes
|
||||
|
||||
-- Object spawn zones have the following major uses:
|
||||
-- - dynamically spawn cargo
|
||||
@ -84,6 +85,16 @@ function cfxObjectSpawnZones.createSpawner(inZone)
|
||||
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(inZone, "activate?") then
|
||||
theSpawner.activateFlag = cfxZones.getStringFromZoneProperty(inZone, "activate?", "none")
|
||||
theSpawner.lastActivateValue = trigger.misc.getUserFlag(theSpawner.activateFlag)
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(inZone, "pause?") then
|
||||
theSpawner.pauseFlag = cfxZones.getStringFromZoneProperty(inZone, "pause?", "none")
|
||||
theSpawner.lastPauseValue = trigger.misc.getUserFlag(theSpawner.pauseFlag)
|
||||
end
|
||||
|
||||
--theSpawner.types = cfxZones.getZoneProperty(inZone, "types")
|
||||
theSpawner.types = cfxZones.getStringFromZoneProperty(inZone, "types", "White_Tyre")
|
||||
local n = cfxZones.getNumberFromZoneProperty(inZone, "count", 1) -- DO NOT CONFUSE WITH OWN PROPERTY COUNT for unique names!!!
|
||||
@ -410,6 +421,15 @@ function cfxObjectSpawnZones.update()
|
||||
|
||||
local needsSpawn = cfxObjectSpawnZones.needsSpawning(spawner)
|
||||
-- check if perhaps our watchtrigger causes spawn
|
||||
if spawner.pauseFlag then
|
||||
local currTriggerVal = trigger.misc.getUserFlag(spawner.pauseFlag)
|
||||
if currTriggerVal ~= spawner.lastPauseValue then
|
||||
spawner.paused = true
|
||||
needsSpawn = false
|
||||
spawner.lastPauseValue = currTriggerVal
|
||||
end
|
||||
end
|
||||
|
||||
if spawner.triggerFlag then
|
||||
local currTriggerVal = trigger.misc.getUserFlag(spawner.triggerFlag)
|
||||
if currTriggerVal ~= spawner.lastTriggerValue then
|
||||
@ -418,6 +438,17 @@ function cfxObjectSpawnZones.update()
|
||||
end
|
||||
end
|
||||
|
||||
if spawner.activateFlag then
|
||||
local currTriggerVal = trigger.misc.getUserFlag(spawner.activateFlag)
|
||||
if currTriggerVal ~= spawner.lastActivateValue then
|
||||
spawner.paused = false
|
||||
spawner.lastActivateValue = currTriggerVal
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
if needsSpawn then
|
||||
cfxObjectSpawnZones.spawnWithSpawner(spawner)
|
||||
if spawner.maxSpawns > 0 then
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
cfxSmokeZone = {}
|
||||
cfxSmokeZone.version = "1.0.2"
|
||||
cfxSmokeZone.version = "1.0.3"
|
||||
cfxSmokeZone.requiredLibs = {
|
||||
"dcsCommon", -- always
|
||||
"cfxZones", -- Zones, of course
|
||||
@ -9,6 +9,9 @@ cfxSmokeZone.requiredLibs = {
|
||||
1.0.0 - initial version
|
||||
1.0.1 - added removeSmokeZone
|
||||
1.0.2 - added altitude
|
||||
1.0.3 - added paused attribute
|
||||
- added f? attribute --> onFlag
|
||||
- broke out startSmoke
|
||||
|
||||
SMOKE ZONES *** EXTENDS ZONES ***
|
||||
keeps 'eternal' smoke up for any zone that has the
|
||||
@ -34,27 +37,61 @@ function cfxSmokeZone.processSmokeZone(aZone)
|
||||
|
||||
aZone.smokeColor = theColor
|
||||
aZone.smokeAlt = cfxZones.getNumberFromZoneProperty(aZone, "altitude", 1)
|
||||
|
||||
-- paused
|
||||
aZone.paused = cfxZones.getBoolFromZoneProperty(aZone, "paused", false)
|
||||
|
||||
-- f? query flags
|
||||
if cfxZones.hasProperty(aZone, "f?") then
|
||||
aZone.onFlag = cfxZones.getStringFromZoneProperty(aZone, "f?", "none")
|
||||
end
|
||||
|
||||
if aZone.onFlag then
|
||||
aZone.onFlagVal = trigger.misc.getUserFlag(aZone.onFlag) -- save last value
|
||||
end
|
||||
end
|
||||
|
||||
function cfxSmokeZone.addSmokeZone(aZone)
|
||||
table.insert(cfxSmokeZone.smokeZones, aZone)
|
||||
end
|
||||
|
||||
function cfxSmokeZone.addSmokeZoneWithColor(aZone, aColor, anAltitude)
|
||||
function cfxSmokeZone.addSmokeZoneWithColor(aZone, aColor, anAltitude, paused, onFlag)
|
||||
if not aColor then aColor = 0 end -- default green
|
||||
if not anAltitude then anAltitude = 5 end
|
||||
if not aZone then return end
|
||||
if not paused then paused = false end
|
||||
|
||||
aZone.smokeColor = aColor
|
||||
aZone.smokeAlt = anAltitude
|
||||
aZone.paused = paused
|
||||
|
||||
if onFlag then
|
||||
aZone.onFlag = onFlag
|
||||
aZone.onFlagVal = trigger.misc.getUserFlag(onFlag)
|
||||
end
|
||||
|
||||
cfxSmokeZone.addSmokeZone(aZone) -- add to update loop
|
||||
cfxZones.markZoneWithSmoke(aZone, 0, 0, aZone.smokeColor, aZone.smokeAlt) -- smoke on!
|
||||
if not paused then
|
||||
cfxSmokeZone.startSmoke(aZone)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function cfxSmokeZone.removeSmokeZone(aZone)
|
||||
if not aZone then return end
|
||||
function cfxSmokeZone.startSmoke(aZone)
|
||||
if type(aZone) == "string" then
|
||||
aZone = cfxZones.getZoneByName(aZone)
|
||||
end
|
||||
if not aZone then return end
|
||||
if not aZone.smokeColor then return end
|
||||
aZone.paused = false
|
||||
cfxZones.markZoneWithSmoke(aZone, 0, 0, aZone.smokeColor, aZone.smokeAlt)
|
||||
end
|
||||
|
||||
function cfxSmokeZone.removeSmokeZone(aZone)
|
||||
if type(aZone) == "string" then
|
||||
aZone = cfxZones.getZoneByName(aZone)
|
||||
end
|
||||
if not aZone then return end
|
||||
|
||||
-- now create new table
|
||||
local filtered = {}
|
||||
@ -73,8 +110,25 @@ function cfxSmokeZone.update()
|
||||
|
||||
-- re-smoke all zones after delay
|
||||
for idx, aZone in pairs(cfxSmokeZone.smokeZones) do
|
||||
if aZone.smokeColor then
|
||||
cfxZones.markZoneWithSmoke(aZone, 0, 0, aZone.smokeColor, aZone.smokeAlt)
|
||||
if not aZone.paused and aZone.smokeColor then
|
||||
cfxSmokeZone.startSmoke(aZone)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function cfxSmokeZone.checkFlags()
|
||||
timer.scheduleFunction(cfxSmokeZone.checkFlags, {}, timer.getTime() + 1) -- every second
|
||||
for idx, aZone in pairs(cfxSmokeZone.smokeZones) do
|
||||
if aZone.paused and aZone.onFlagVal then
|
||||
-- see if this changed
|
||||
local currTriggerVal = trigger.misc.getUserFlag(aZone.onFlag)
|
||||
if currTriggerVal ~= aZone.onFlagVal then
|
||||
-- yupp, trigger start
|
||||
cfxSmokeZone.startSmoke(aZone)
|
||||
aZone.onFlagVal = currTriggerVal
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -89,15 +143,18 @@ function cfxSmokeZone.start()
|
||||
-- collect all spawn zones
|
||||
local attrZones = cfxZones.getZonesWithAttributeNamed("smoke")
|
||||
|
||||
-- now create a spawner for all, add them to the spawner updater, and spawn for all zones that are not
|
||||
-- paused
|
||||
-- now create a smoker for all, add them to updater,
|
||||
-- smoke all that aren't paused
|
||||
for k, aZone in pairs(attrZones) do
|
||||
cfxSmokeZone.processSmokeZone(aZone) -- process attribute and add to zone
|
||||
cfxSmokeZone.addSmokeZone(aZone) -- remember it so we can smoke it
|
||||
end
|
||||
|
||||
-- start update loop
|
||||
cfxSmokeZone.update()
|
||||
cfxSmokeZone.update() -- also starts all unpaused
|
||||
|
||||
-- start check loop in one second
|
||||
timer.scheduleFunction(cfxSmokeZone.checkFlags, {}, timer.getTime() + 1)
|
||||
|
||||
-- say hi
|
||||
trigger.action.outText("cfx Smoke Zones v" .. cfxSmokeZone.version .. " started.", 30)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
cfxSpawnZones = {}
|
||||
cfxSpawnZones.version = "1.5.1"
|
||||
cfxSpawnZones.version = "1.5.2"
|
||||
cfxSpawnZones.requiredLibs = {
|
||||
"dcsCommon", -- common is of course needed for everything
|
||||
-- pretty stupid to check for this since we
|
||||
@ -51,6 +51,7 @@ cfxSpawnZones.verbose = false
|
||||
-- - spawnWithSpawner made string compatible
|
||||
-- 1.5.1 - relaxed baseName and default to dcsCommon.uuid()
|
||||
-- - verbose
|
||||
-- 1.5.2 - activate?, pause? flag
|
||||
--
|
||||
-- new version requires cfxGroundTroops, where they are
|
||||
--
|
||||
@ -139,6 +140,16 @@ function cfxSpawnZones.createSpawner(inZone)
|
||||
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(inZone, "activate?") then
|
||||
theSpawner.activateFlag = cfxZones.getStringFromZoneProperty(inZone, "activate?", "none")
|
||||
theSpawner.lastActivateValue = trigger.misc.getUserFlag(theSpawner.activateFlag)
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(inZone, "pause?") then
|
||||
theSpawner.pauseFlag = cfxZones.getStringFromZoneProperty(inZone, "pause?", "none")
|
||||
theSpawner.lastPauseValue = trigger.misc.getUserFlag(theSpawner.pauseFlag)
|
||||
end
|
||||
|
||||
theSpawner.types = cfxZones.getZoneProperty(inZone, "types")
|
||||
--theSpawner.owner = cfxZones.getCoalitionFromZoneProperty(inZone, "owner", 0)
|
||||
-- synthesize types * typeMult
|
||||
@ -407,7 +418,16 @@ function cfxSpawnZones.update()
|
||||
-- is master zone still alinged with me?
|
||||
needsSpawn = needsSpawn and cfxSpawnZones.verifySpawnOwnership(spawner)
|
||||
|
||||
-- check if perhaps our watchtrigger causes spawn
|
||||
-- check if perhaps our watchtriggers causes spawn
|
||||
if spawner.pauseFlag then
|
||||
local currTriggerVal = trigger.misc.getUserFlag(spawner.pauseFlag)
|
||||
if currTriggerVal ~= spawner.lastPauseValue then
|
||||
spawner.paused = true
|
||||
needsSpawn = false
|
||||
spawner.lastPauseValue = currTriggerVal
|
||||
end
|
||||
end
|
||||
|
||||
if spawner.triggerFlag then
|
||||
local currTriggerVal = trigger.misc.getUserFlag(spawner.triggerFlag)
|
||||
if currTriggerVal ~= spawner.lastTriggerValue then
|
||||
@ -416,6 +436,16 @@ function cfxSpawnZones.update()
|
||||
end
|
||||
end
|
||||
|
||||
if spawner.activateFlag then
|
||||
local currTriggerVal = trigger.misc.getUserFlag(spawner.activateFlag)
|
||||
if currTriggerVal ~= spawner.lastActivateValue then
|
||||
spawner.paused = false
|
||||
spawner.lastActivateValue = currTriggerVal
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- if we get here, and needsSpawn is still set, we go ahead and spawn
|
||||
if needsSpawn then
|
||||
--- trigger.action.outText("+++ spawning for zone " .. spawner.zone.name, 30)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
--
|
||||
|
||||
cfxZones = {}
|
||||
cfxZones.version = "2.5.1"
|
||||
cfxZones.version = "2.5.2"
|
||||
--[[-- VERSION HISTORY
|
||||
- 2.2.4 - getCoalitionFromZoneProperty
|
||||
- getStringFromZoneProperty
|
||||
@ -43,6 +43,8 @@ cfxZones.version = "2.5.1"
|
||||
- 2.4.12 - getStringFromZoneProperty
|
||||
- 2.5.0 - harden getZoneProperty and all getPropertyXXXX
|
||||
- 2.5.1 - markZoneWithSmoke supports alt attribute
|
||||
- 2.5.2 - getPoint also writes through to zone itself for optimization
|
||||
- new method getPositiveRangeFromZoneProperty(theZone, theProperty, default)
|
||||
|
||||
--]]--
|
||||
cfxZones.verbose = true
|
||||
@ -1100,6 +1102,45 @@ function cfxZones.getMinMaxFromZoneProperty(theZone, theProperty)
|
||||
|
||||
end
|
||||
|
||||
function cfxZones.getPositiveRangeFromZoneProperty(theZone, theProperty, default)
|
||||
-- reads property as string, and interprets as range 'a-b'.
|
||||
-- if not a range but single number, returns both for upper and lower
|
||||
--trigger.action.outText("***Zne: enter with <" .. theZone.name .. ">: range for property <" .. theProperty .. ">!", 30)
|
||||
if not default then default = 0 end
|
||||
local lowerBound = default
|
||||
local upperBound = default
|
||||
|
||||
local rangeString = cfxZones.getStringFromZoneProperty(theZone, theProperty, "")
|
||||
if dcsCommon.containsString(rangeString, "-") then
|
||||
local theRange = dcsCommon.splitString(rangeString, "-")
|
||||
lowerBound = theRange[1]
|
||||
lowerBound = tonumber(lowerBound)
|
||||
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
|
||||
-- if rndFlags.verbose then
|
||||
-- trigger.action.outText("+++Zne: detected range <" .. lowerBound .. ", " .. upperBound .. ">", 30)
|
||||
-- end
|
||||
else
|
||||
-- bounds illegal
|
||||
trigger.action.outText("+++Zne: illegal range <" .. rangeString .. ">, using " .. default .. "-" .. default, 30)
|
||||
lowerBound = default
|
||||
upperBound = default
|
||||
end
|
||||
else
|
||||
upperBound = cfxZones.getNumberFromZoneProperty(theZone, theProperty, default) -- between pulses
|
||||
lowerBound = upperBound
|
||||
end
|
||||
-- trigger.action.outText("+++Zne: returning <" .. lowerBound .. ", " .. upperBound .. ">", 30)
|
||||
return lowerBound, upperBound
|
||||
end
|
||||
|
||||
function cfxZones.hasProperty(theZone, theProperty)
|
||||
return cfxZones.getZoneProperty(theZone, theProperty) ~= nil
|
||||
end
|
||||
@ -1223,7 +1264,7 @@ end
|
||||
--
|
||||
-- requires that readFromDCS has been done
|
||||
--
|
||||
function cfxZones.getPoint(aZone) -- always works, wven linked, point can be reused
|
||||
function cfxZones.getPoint(aZone) -- always works, even linked, point can be reused
|
||||
if aZone.linkedUnit then
|
||||
local theUnit = aZone.linkedUnit
|
||||
-- has a link. is link existing?
|
||||
@ -1237,6 +1278,8 @@ function cfxZones.getPoint(aZone) -- always works, wven linked, point can be reu
|
||||
thePos.x = aZone.point.x
|
||||
thePos.y = 0 -- aZone.y
|
||||
thePos.z = aZone.point.z
|
||||
-- since we are at it, update the zone as well
|
||||
aZone.point = thePos
|
||||
return thePos
|
||||
end
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
dcsCommon = {}
|
||||
dcsCommon.version = "2.5.1"
|
||||
dcsCommon.version = "2.5.2"
|
||||
--[[-- VERSION HISTORY
|
||||
2.2.6 - compassPositionOfARelativeToB
|
||||
- clockPositionOfARelativeToB
|
||||
@ -56,6 +56,8 @@ dcsCommon.version = "2.5.1"
|
||||
2.5.0 - "Line" formation with one unit places unit at center
|
||||
2.5.1 - vNorm(a)
|
||||
2.5.1 - added SA-18 Igla manpad to unitIsInfantry()
|
||||
2.5.2 - added copyArray method
|
||||
- corrected heading in createStaticObjectData
|
||||
--]]--
|
||||
|
||||
-- dcsCommon is a library of common lua functions
|
||||
@ -825,7 +827,14 @@ dcsCommon.version = "2.5.1"
|
||||
return copy
|
||||
end
|
||||
|
||||
|
||||
function dcsCommon.copyArray(inArray)
|
||||
-- warning: this is a ref copy!
|
||||
local theCopy = {}
|
||||
for idx, element in pairs(inArray) do
|
||||
table.insert(theCopy, element)
|
||||
end
|
||||
return theCopy
|
||||
end
|
||||
--
|
||||
--
|
||||
-- S P A W N I N G
|
||||
@ -1355,7 +1364,7 @@ dcsCommon.version = "2.5.1"
|
||||
-- now loop and create a unit for each table
|
||||
local num = 1
|
||||
for key, theType in pairs(theUnitTypes) do
|
||||
-- trigger.action.outText("creating unit " .. name .. "-" .. num, 30)
|
||||
-- trigger.action.outText("+++dcsC: creating unit " .. name .. "-" .. num .. ": " .. theType, 30)
|
||||
local aUnit = dcsCommon.createGroundUnitData(name .. "-"..num, theType, false)
|
||||
dcsCommon.addUnitToGroupData(aUnit, theNewGroup, 0, 0)
|
||||
num = num + 1
|
||||
@ -1478,7 +1487,7 @@ dcsCommon.version = "2.5.1"
|
||||
if not cargo then cargo = false end
|
||||
objType = dcsCommon.trim(objType)
|
||||
|
||||
staticObj.heading = 0
|
||||
staticObj.heading = heading
|
||||
-- staticObj.groupId = 0
|
||||
-- staticObj.shape_name = shape -- e.g. H-Windsock_RW
|
||||
staticObj.type = objType -- e.g. Windsock
|
||||
|
||||
268
modules/pulseFlags.lua
Normal file
268
modules/pulseFlags.lua
Normal file
@ -0,0 +1,268 @@
|
||||
pulseFlags = {}
|
||||
pulseFlags.version = "1.0.0"
|
||||
pulseFlags.verbose = false
|
||||
pulseFlags.requiredLibs = {
|
||||
"dcsCommon", -- always
|
||||
"cfxZones", -- Zones, of course
|
||||
}
|
||||
--[[--
|
||||
Pulse Flags: DML module to regularly change a flag
|
||||
|
||||
Copyright 2022 by Christian Franz and cf/x
|
||||
|
||||
Version History
|
||||
- 1.0.0 Initial version
|
||||
|
||||
--]]--
|
||||
|
||||
pulseFlags.pulses = {}
|
||||
|
||||
function pulseFlags.addPulse(aZone)
|
||||
table.insert(pulseFlags.pulses, aZone)
|
||||
end
|
||||
|
||||
--
|
||||
-- create a pulse
|
||||
--
|
||||
|
||||
function pulseFlags.createPulseWithZone(theZone)
|
||||
theZone.flag = cfxZones.getNumberFromZoneProperty(theZone, "flag!", -1) -- the flag to pulse
|
||||
|
||||
-- time can be number, or number-number range
|
||||
theZone.minTime, theZone.time = cfxZones.getPositiveRangeFromZoneProperty(theZone, "time", 1)
|
||||
|
||||
trigger.action.outText("***PulF: zone <" .. theZone.name .. "> time is <".. theZone.minTime ..", " .. theZone.time .. "!", 30)
|
||||
|
||||
theZone.pulses = cfxZones.getNumberFromZoneProperty(theZone, "pulses", -1)
|
||||
theZone.pulsesLeft = 0 -- will start new cycle
|
||||
|
||||
-- trigger flags
|
||||
if cfxZones.hasProperty(theZone, "activate?") then
|
||||
theZone.activateFlag = cfxZones.getStringFromZoneProperty(theZone, "activate?", "none")
|
||||
theZone.lastActivateValue = trigger.misc.getUserFlag(theZone.activateFlag) -- save last value
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(theZone, "pause?") then
|
||||
theZone.pauseFlag = cfxZones.getStringFromZoneProperty(theZone, "pause?", "none")
|
||||
theZone.lastPauseValue = trigger.misc.getUserFlag(theZone.pauseFlag) -- save last value
|
||||
end
|
||||
|
||||
theZone.paused = cfxZones.getBoolFromZoneProperty(theZone, "paused", false)
|
||||
|
||||
theZone.method = cfxZones.getStringFromZoneProperty(theZone, "method", "flip")
|
||||
|
||||
-- done flag
|
||||
if cfxZones.hasProperty(theZone, "done+1") then
|
||||
theZone.doneFlag = cfxZones.getStringFromZoneProperty(theZone, "done+1", "none")
|
||||
end
|
||||
|
||||
theZone.pulsing = false -- not running
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- update
|
||||
--
|
||||
function pulseFlags.pollFlag(theFlag, method)
|
||||
if pulseFlags.verbose then
|
||||
trigger.action.outText("+++PulF: polling flag " .. theFlag .. " with " .. method, 30)
|
||||
end
|
||||
|
||||
method = method:lower()
|
||||
local currVal = trigger.misc.getUserFlag(theFlag)
|
||||
if method == "inc" or method == "f+1" then
|
||||
trigger.action.setUserFlag(theFlag, currVal + 1)
|
||||
|
||||
elseif method == "dec" or method == "f-1" then
|
||||
trigger.action.setUserFlag(theFlag, currVal - 1)
|
||||
|
||||
elseif method == "off" or method == "f=0" then
|
||||
trigger.action.setUserFlag(theFlag, 0)
|
||||
|
||||
elseif method == "flip" or method == "xor" then
|
||||
if currVal ~= 0 then
|
||||
trigger.action.setUserFlag(theFlag, 0)
|
||||
else
|
||||
trigger.action.setUserFlag(theFlag, 1)
|
||||
end
|
||||
|
||||
else
|
||||
if method ~= "on" and method ~= "f=1" then
|
||||
trigger.action.outText("+++PulF: unknown method <" .. method .. "> - using 'on'", 30)
|
||||
end
|
||||
-- default: on.
|
||||
trigger.action.setUserFlag(theFlag, 1)
|
||||
end
|
||||
|
||||
local newVal = trigger.misc.getUserFlag(theFlag)
|
||||
if pulseFlags.verbose then
|
||||
trigger.action.outText("+++PulF: flag <" .. theFlag .. "> changed from " .. currVal .. " to " .. newVal, 30)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function pulseFlags.doPulse(args)
|
||||
local theZone = args[1]
|
||||
-- check if we have been paused. if so, simply
|
||||
-- exit with no new schedule
|
||||
if theZone.paused then
|
||||
theZone.pulsing = false
|
||||
return
|
||||
end
|
||||
|
||||
-- do a poll on flags
|
||||
pulseFlags.pollFlag(theZone.flag, theZone.method)
|
||||
|
||||
-- decrease count
|
||||
if theZone.pulses > 0 then
|
||||
-- only do this if ending
|
||||
theZone.pulsesLeft = theZone.pulsesLeft - 1
|
||||
|
||||
-- see if we are done
|
||||
if theZone.pulsesLeft < 1 then
|
||||
-- increment done flag if set
|
||||
if theZone.doneFlag then
|
||||
local currVal = trigger.misc.getUserFlag(theZone.doneFlag)
|
||||
trigger.action.setUserFlag(theZone.doneFlag, currVal + 1)
|
||||
end
|
||||
if pulseFlags.verbose then
|
||||
trigger.action.outText("***PulF: pulse <" .. theZone.name .. "> ended!", 30)
|
||||
end
|
||||
theZone.pulsing = false
|
||||
theZone.paused = true
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- if we get here, we'll do another one soon
|
||||
-- refresh pulse
|
||||
local delay = theZone.time
|
||||
if theZone.minTime > 0 and theZone.minTime < delay then
|
||||
-- we want a randomized from time from minTime .. delay
|
||||
local varPart = delay - theZone.minTime + 1
|
||||
varPart = dcsCommon.smallRandom(varPart) - 1
|
||||
delay = theZone.minTime + varPart
|
||||
end
|
||||
|
||||
--trigger.action.outText("***PulF: pulse <" .. theZone.name .. "> scheduled in ".. delay .."!", 30)
|
||||
|
||||
-- schedule in delay time
|
||||
timer.scheduleFunction(pulseFlags.doPulse, args, timer.getTime() + delay)
|
||||
if pulseFlags.verbose then
|
||||
trigger.action.outText("+++PulF: pulse <" .. theZone.name .. "> rescheduled in " .. delay, 30)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- start new pulse, will reset
|
||||
function pulseFlags.startNewPulse(theZone)
|
||||
theZone.pulsesLeft = theZone.pulses
|
||||
local args = {theZone}
|
||||
theZone.pulsing = true
|
||||
if pulseFlags.verbose then
|
||||
trigger.action.outText("+++PulF: starting pulse <" .. theZone.name .. ">", 30)
|
||||
end
|
||||
pulseFlags.doPulse(args)
|
||||
end
|
||||
|
||||
function pulseFlags.update()
|
||||
-- call me in a second to poll triggers
|
||||
timer.scheduleFunction(pulseFlags.update, {}, timer.getTime() + 1)
|
||||
|
||||
for idx, aZone in pairs(pulseFlags.pulses) do
|
||||
-- see if pulse is running
|
||||
if aZone.pulsing then
|
||||
-- this zone has a pulse and has scheduled
|
||||
-- a new pulse, nothing to do
|
||||
|
||||
else
|
||||
-- this zone has not scheduled a new pulse
|
||||
-- let's see why
|
||||
if aZone.paused then
|
||||
-- ok, zone is paused. all clear
|
||||
else
|
||||
-- zone isn't paused. we need to start the zone
|
||||
pulseFlags.startNewPulse(aZone)
|
||||
end
|
||||
end
|
||||
|
||||
-- see if we got a pause or activate command
|
||||
if aZone.activateFlag then
|
||||
local currTriggerVal = trigger.misc.getUserFlag(aZone.activateFlag)
|
||||
if currTriggerVal ~= aZone.lastActivateValue
|
||||
then
|
||||
trigger.action.outText("+++PulF: activating <" .. aZone.name .. ">", 30)
|
||||
aZone.lastActivateValue = currTriggerVal
|
||||
theZone.paused = false -- will start anew
|
||||
end
|
||||
end
|
||||
|
||||
if aZone.pauseFlag then
|
||||
local currTriggerVal = trigger.misc.getUserFlag(aZone.pauseFlag)
|
||||
if currTriggerVal ~= aZone.lastPauseValue
|
||||
then
|
||||
trigger.action.outText("+++PulF: pausing <" .. aZone.name .. ">", 30)
|
||||
aZone.lastPauseValue = currTriggerVal
|
||||
theZone.paused = true -- will start anew
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- start module and read config
|
||||
--
|
||||
function pulseFlags.readConfigZone()
|
||||
-- note: must match exactly!!!!
|
||||
local theZone = cfxZones.getZoneByName("pulseFlagsConfig")
|
||||
if not theZone then
|
||||
if pulseFlags.verbose then
|
||||
trigger.action.outText("+++PulF: NO config zone!", 30)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
pulseFlags.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
|
||||
|
||||
if pulseFlags.verbose then
|
||||
trigger.action.outText("+++PulF: read config", 30)
|
||||
end
|
||||
end
|
||||
|
||||
function pulseFlags.start()
|
||||
-- lib check
|
||||
if not dcsCommon.libCheck then
|
||||
trigger.action.outText("PulseFlags requires dcsCommon", 30)
|
||||
return false
|
||||
end
|
||||
if not dcsCommon.libCheck("cfx Pulse Flags",
|
||||
pulseFlags.requiredLibs) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- read config
|
||||
pulseFlags.readConfigZone()
|
||||
|
||||
-- process RND Zones
|
||||
local attrZones = cfxZones.getZonesWithAttributeNamed("pulse")
|
||||
|
||||
-- now create a pulse gen for each one and add them
|
||||
-- to our watchlist
|
||||
for k, aZone in pairs(attrZones) do
|
||||
pulseFlags.createPulseWithZone(aZone) -- process attribute and add to zone
|
||||
pulseFlags.addPulse(aZone) -- remember it so we can pulse it
|
||||
end
|
||||
|
||||
-- start update in 1 second
|
||||
--pulseFlags.update()
|
||||
timer.scheduleFunction(pulseFlags.update, {}, timer.getTime() + 1)
|
||||
|
||||
trigger.action.outText("cfx Pulse Flags v" .. pulseFlags.version .. " started.", 30)
|
||||
return true
|
||||
end
|
||||
|
||||
-- let's go!
|
||||
if not pulseFlags.start() then
|
||||
trigger.action.outText("cf/x Pulse Flags aborted: missing libraries", 30)
|
||||
pulseFlags = nil
|
||||
end
|
||||
Binary file not shown.
BIN
tutorial & demo missions/demo - FARP and away.miz
Normal file
BIN
tutorial & demo missions/demo - FARP and away.miz
Normal file
Binary file not shown.
BIN
tutorial & demo missions/demo - Pulsing Fun.miz
Normal file
BIN
tutorial & demo missions/demo - Pulsing Fun.miz
Normal file
Binary file not shown.
BIN
tutorial & demo missions/demo - Random Death.miz
Normal file
BIN
tutorial & demo missions/demo - Random Death.miz
Normal file
Binary file not shown.
BIN
tutorial & demo missions/demo - Random Glory.miz
Normal file
BIN
tutorial & demo missions/demo - Random Glory.miz
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user