Version 0.997

Wiper
This commit is contained in:
Christian Franz 2022-04-07 16:26:48 +02:00
parent 9f54ac1917
commit 2b97597e83
14 changed files with 602 additions and 32 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
cfxGroundTroops = {}
cfxGroundTroops.version = "1.7.4"
cfxGroundTroops.version = "1.7.5"
cfxGroundTroops.ups = 1
cfxGroundTroops.verbose = false
cfxGroundTroops.requiredLibs = {
@ -59,6 +59,7 @@ cfxGroundTroops.deployedTroops = {}
-- - callback when group is being engaged under guard orders
-- 1.7.3 - callbacks for lase:tracking and lase:stop
-- 1.7.4 - verbose flag, warnings suppressed
-- 1.7.5 - some troop.group hardening with isExist()
@ -199,6 +200,11 @@ end
-- enemies are an attribute of the troop structure
function cfxGroundTroops.makeTroopsEngageEnemies(troop)
local group = troop.group
if not group:isExist() then
trigger.action.outText("+++gndT: troup don't exist, dropping", 30)
return
end
local enemies = troop.enemy
local from = dcsCommon.getGroupLocation(group)
if not from then return end -- the commandos died
@ -218,6 +224,11 @@ end
-- attribute
function cfxGroundTroops.makeTroopsEngageZone(troop)
local group = troop.group
if not group:isExist() then
trigger.action.outText("+++gndT: make engage zone: troops do not exist, exiting", 30)
return
end
local enemyZone = troop.destination -- must be cfxZone
local from = dcsCommon.getGroupLocation(group)
if not from then return end -- the group died
@ -250,6 +261,10 @@ function cfxGroundTroops.switchToOffroad(troops)
-- on their route for longer than allowed
-- we now force a direct approach
local group = troops.group
if not group.isExist() then
return
end
local enemies = troops.destination
local from = dcsCommon.getGroupLocation(group)
if not from then return end -- the commandos died
@ -315,6 +330,7 @@ end
function cfxGroundTroops.updateAttackers(troop)
if not troop then return end
if not troop.destination then return end
if not troop.group:isExist() then return end
if cfxZones.isGroupPartiallyInZone(troop.group, troop.destination) then
-- we have arrived
@ -335,6 +351,10 @@ end
-- 'engaged' means that the troop.enemy attribute is set
function cfxGroundTroops.updateGuards(troop)
if not troop.group:isExist() then
return
end
local theEnemy = troop.enemy
if theEnemy then
-- see if enemy is dead
@ -807,7 +827,7 @@ function cfxGroundTroops.checkPileUp()
for idx, troop in pairs(cfxGroundTroops.deployedTroops) do
-- get each group and count them if they are inside
-- their destination
if troop.insideDestination then
if troop.insideDestination and troop.group:isExist() then
local side = troop.group:getCoalition()
local thePile = thePiles[troop.destination]
local theSide = troop.group:getCoalition()
@ -879,7 +899,7 @@ function cfxGroundTroops.checkSchedules()
-- plan and needs to be scheduled
if troop.updateID == nil then
troop.unscheduleCount = troop.unscheduleCount + 1
if (troop.unscheduleCount > 1) then
if (troop.unscheduleCount > 1) and troop.group:isExist() then
trigger.action.outText("+++ groundT: unscheduled group " .. troop.group:getName() .. " cnt=" .. troop.unscheduleCount , 30)
end
end
@ -896,7 +916,7 @@ function cfxGroundTroops.getTroopReport(theSide, ignoreInfantry)
if not ignoreInfantry then ignoreInfantry = false end
local report = "GROUND FORCES REPORT"
for idx, troop in pairs(cfxGroundTroops.deployedTroops) do
if troop.side == theSide then
if troop.side == theSide and troop.group:isExist() then
local unitNum = troop.group:getSize()
report = report .. "\n" .. troop.name .. " (".. unitNum .."): <" .. troop.orders .. ">"
if troop.orders == "attackOwnedZone" then
@ -975,9 +995,15 @@ function cfxGroundTroops.addGroundTroopsToPool(troops) -- troops MUST be a table
end
function cfxGroundTroops.removeTroopsFromPool(troops)
if not troops then return end
if troops.signature ~= "cfx" then return end
if not troops.group:isExist() then
trigger.action.outText("warning: removeFromPool called with inexistant group", 30)
return
end
if cfxGroundTroops.deployedTroops[troops.group:getName()] then
local troop = cfxGroundTroops.deployedTroops[troops.group:getName()]
troops.reschedule = false -- so a reschedule wont update any more
@ -1066,7 +1092,9 @@ function cfxGroundTroops.manageQueues()
-- trnasfer items from the front to the managed queue
local theTroops = cfxGroundTroops.troopQueue[1]
table.remove(cfxGroundTroops.troopQueue, 1)
cfxGroundTroops.deployedTroops[theTroops.group:getName()] = theTroops
if theTroops.group:isExist() then
cfxGroundTroops.deployedTroops[theTroops.group:getName()] = theTroops
end
-- trigger.action.outText("+++gT: dequed and activaed " .. theTroops.group:getName(), 30)
end
end

View File

@ -1,5 +1,5 @@
cfxSmokeZone = {}
cfxSmokeZone.version = "1.0.4"
cfxSmokeZone.version = "1.1.0"
cfxSmokeZone.requiredLibs = {
"dcsCommon", -- always
"cfxZones", -- Zones, of course
@ -15,6 +15,7 @@ cfxSmokeZone.requiredLibs = {
1.0.4 - startSmoke? synonym
- alphanum DML flag upgrade
- random color support
1.1.0 - Watchflag upgrade
SMOKE ZONES *** EXTENDS ZONES ***
keeps 'eternal' smoke up for any zone that has the
@ -49,7 +50,7 @@ function cfxSmokeZone.processSmokeZone(aZone)
-- f? query flags
if cfxZones.hasProperty(aZone, "f?") then
aZone.onFlag = cfxZones.getStringFromZoneProperty(aZone, "f?", "none")
aZone.onFlag = cfxZones.getStringFromZoneProperty(aZone, "f?", "*<none>")
end
if cfxZones.hasProperty(aZone, "startSmoke?") then
@ -59,6 +60,15 @@ function cfxSmokeZone.processSmokeZone(aZone)
if aZone.onFlag then
aZone.onFlagVal = cfxZones.getFlagValue(aZone.onFlag, aZone) -- save last value
end
-- watchflags:
-- triggerMethod
aZone.smokeTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, "triggerMethod", "change")
if cfxZones.hasProperty(aZone, "smokeTriggerMethod") then
aZone.delayTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, "smokeTriggerMethod", "change")
end
end
function cfxSmokeZone.addSmokeZone(aZone)
@ -122,7 +132,6 @@ function cfxSmokeZone.update()
for idx, aZone in pairs(cfxSmokeZone.smokeZones) do
if not aZone.paused and aZone.smokeColor then
cfxSmokeZone.startSmoke(aZone)
end
end
end
@ -131,14 +140,21 @@ 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
if cfxZones.testZoneFlag(aZone, aZone.onFlag, aZone.smokeTriggerMethod, "onFlagVal") then
cfxSmokeZone.startSmoke(aZone)
end
--[[--
-- old code
local currTriggerVal = cfxZones.getFlagValue(aZone.onFlag, aZone) -- trigger.misc.getUserFlag(aZone.onFlag)
if currTriggerVal ~= aZone.onFlagVal then
-- yupp, trigger start
cfxSmokeZone.startSmoke(aZone)
aZone.onFlagVal = currTriggerVal
end
--]]--
end
end
end

View File

@ -64,6 +64,7 @@ cfxZones.version = "2.7.0"
- verbose for zone-local accepted (but not acted upon)
- hasProperty now offers active information when looking for '*?' and '*!'
- 2.7.0 - doPollFlag - fully support multiple flags per bang!
- 2.7.1 - setFlagValueMult()
--]]--
cfxZones.verbose = false
@ -2881,6 +2882,25 @@ function cfxZones.pollFlag(theFlag, method, theZone)
end
function cfxZones.setFlagValueMult(theFlag, theValue, theZone)
local allFlags = {}
if dcsCommon.containsString(theFlag, ",") then
if cfxZones.verbose then
trigger.action.outText("+++zones: will multi-set flags <" .. theFlag .. "> to " .. theValue, 30)
end
allFlags = dcsCommon.splitString(theFlag, ",")
else
table.insert(allFlags, theFlag)
end
for idx, aFlag in pairs(allFlags) do
aFlag = dcsCommon.trim(aFlag)
-- note: mey require range preprocessing, but that's not
-- a priority
cfxZones.setFlagValue(aFlag, theValue, theZone)
end
end
function cfxZones.setFlagValue(theFlag, theValue, theZone)
local zoneName = "<dummy>"
if not theZone then
@ -3036,7 +3056,7 @@ function cfxZones.testFlagByMethodForZone(currVal, lastVal, theMethod, theZone)
end
function cfxZones.testZoneFlag(theZone, theFlagName, theMethod, latchName)
-- returns true if method contraints are met for flag theFlagName
-- returns true if method constraints are met for flag theFlagName
-- as defined by theMethod
if not theMethod then
theMethod = "change"

148
modules/changer.lua Normal file
View File

@ -0,0 +1,148 @@
changer = {}
changer.version = "0.0.0"
changer.verbose = false
changer.ups = 1
changer.requiredLibs = {
"dcsCommon", -- always
"cfxZones", -- Zones, of course
}
changer.changers = {}
--[[--
Version History
1.0.0 - Initial version
--]]--
function changer.addChanger(theZone)
table.insert(changer.changers, theZone)
end
function changer.getChangerByName(aName)
for idx, aZone in pairs(changer.changers) do
if aName == aZone.name then return aZone end
end
if changer.verbose then
trigger.action.outText("+++chgr: no changer with name <" .. aName ..">", 30)
end
return nil
end
--
-- read zone
--
function wiper.createWiperWithZone(theZone)
theZone.triggerWiperFlag = cfxZones.getStringFromZoneProperty(theZone, "wipe?", "*<none>")
-- triggerWiperMethod
theZone.triggerWiperMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
if cfxZones.hasProperty(theZone, "triggerWiperMethod") then
theZone.triggerWiperMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerWiperMethod", "change")
end
if theZone.triggerWiperFlag then
theZone.lastTriggerWiperValue = cfxZones.getFlagValue(theZone.triggerWiperFlag, theZone)
end
local theCat = cfxZones.getStringFromZoneProperty(theZone, "category", "static")
if cfxZones.hasProperty(theZone, "wipeCategory") then
theCat = cfxZones.getStringFromZoneProperty(theZone, "wipeCategory", "static")
end
if cfxZones.hasProperty(theZone, "wipeCat") then
theCat = cfxZones.getStringFromZoneProperty(theZone, "wipeCat", "static")
end
theZone.wipeCategory = dcsCommon.string2ObjectCat(theCat)
if cfxZones.hasProperty(theZone, "wipeNamed") then
theZone.wipeNamed = cfxZones.getStringFromZoneProperty(theZone, "wipeNamed", "<no name given>")
if dcsCommon.stringEndsWith(theZone.wipeNamed, "*") then
theZone.wipeNamedBeginsWith = true
theZone.wipeNamed = dcsCommon.removeEnding(theZone.wipeNamed, "*")
end
end
theZone.wipeInventory = cfxZones.getBoolFromZoneProperty(theZone, "wipeInventory", false)
if wiper.verbose or theZone.verbose then
trigger.action.outText("+++wpr: new wiper zone <".. theZone.name ..">", 30)
end
end
--
-- MAIN ACTION
--
function changer.isTriggered(theZone)
end
--
-- Update
--
function changer.update()
-- call me in a second to poll triggers
timer.scheduleFunction(changer.update, {}, timer.getTime() + 1/changer.ups)
for idx, aZone in pairs(changer.changers) do
end
end
--
-- Config & Start
--
function changer.readConfigZone()
local theZone = cfxZones.getZoneByName("changerConfig")
if not theZone then
if changer.verbose then
trigger.action.outText("+++chgr: NO config zone!", 30)
end
theZone = cfxZones.createSimpleZone("changerConfig") -- temp only
end
changer.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
changer.ups = cfxZones.getNumberFromZoneProperty(theZone, "ups", 1)
if changer.verbose then
trigger.action.outText("+++chgr: read config", 30)
end
end
function wiper.start()
-- lib check
if not dcsCommon.libCheck then
trigger.action.outText("cfx Wiper requires dcsCommon", 30)
return false
end
if not dcsCommon.libCheck("cfx Wiper", wiper.requiredLibs) then
return false
end
-- read config
wiper.readConfigZone()
-- process cloner Zones
local attrZones = cfxZones.getZonesWithAttributeNamed("wipe?")
for k, aZone in pairs(attrZones) do
wiper.createWiperWithZone(aZone) -- process attributes
wiper.addWiper(aZone) -- add to list
end
-- start update
wiper.update()
trigger.action.outText("cfx Wiper v" .. wiper.version .. " started.", 30)
return true
end
-- let's go!
if not wiper.start() then
trigger.action.outText("cfx Wiper aborted: missing libraries", 30)
wiper = nil
end

View File

@ -1,6 +1,6 @@
countDown = {}
countDown.version = "1.3.0"
countDown.verbose = true
countDown.verbose = false
countDown.ups = 1
countDown.requiredLibs = {
"dcsCommon", -- always

View File

@ -1,5 +1,5 @@
dcsCommon = {}
dcsCommon.version = "2.5.8"
dcsCommon.version = "2.5.9"
--[[-- VERSION HISTORY
2.2.6 - compassPositionOfARelativeToB
- clockPositionOfARelativeToB
@ -68,6 +68,7 @@ dcsCommon.version = "2.5.8"
2.5.6 - corrected stringEndsWith() bug with str
2.5.7 - point2text(p)
2.5.8 - string2GroupCat()
2.5.9 - string2ObjectCat()
--]]--
@ -1806,6 +1807,28 @@ dcsCommon.version = "2.5.8"
return catNum
end
function dcsCommon.string2ObjectCat(inString)
if not inString then return 3 end -- default static
inString = inString:lower()
inString = dcsCommon.trim(inString)
local catNum = tonumber(inString)
if catNum then
if catNum < 0 then catNum = 0 end
if catNum > 6 then catNum = 6 end
return catNum
end
catNum = 3 -- static default
if dcsCommon.stringStartsWith(inString, "uni") then catNum = 1 end
if dcsCommon.stringStartsWith(inString, "wea") then catNum = 2 end
if dcsCommon.stringStartsWith(inString, "bas") then catNum = 4 end
if dcsCommon.stringStartsWith(inString, "sce") then catNum = 5 end
if dcsCommon.stringStartsWith(inString, "car") then catNum = 6 end
return catNum
end
-- recursively show the contents of a variable
function dcsCommon.dumpVar(key, value, prefix, inrecursion)

View File

@ -1,5 +1,5 @@
unitZone={}
unitZone.version = "1.1.0"
unitZone.version = "1.2.0"
unitZone.verbose = false
unitZone.ups = 1
unitZone.requiredLibs = {
@ -11,6 +11,7 @@ unitZone.requiredLibs = {
1.0.0 - Initial Version
1.1.0 - DML flag integration
- method/uzMethod
1.2.0 - uzOn?, uzOff?, triggerMethod
--]]--
@ -73,11 +74,11 @@ function unitZone.createUnitZone(theZone)
theZone.uzCoalition = cfxZones.getCoalitionFromZoneProperty(theZone, "uzCoalition", 0)
end
if unitZone.verbose then
if unitZone.verbose or theZone.verbose then
trigger.action.outText("+++uZne: set coa " .. theZone.uzCoalition .. " for <" .. theZone.name .. ">", 30)
end
-- DML M;ethod
-- DML Method
theZone.uzMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "inc")
if cfxZones.hasProperty(theZone, "uzMethod") then
theZone.uzMethod = cfxZones.getStringFromZoneProperty(theZone, "uzMethod", "inc")
@ -90,16 +91,30 @@ function unitZone.createUnitZone(theZone)
if cfxZones.hasProperty(theZone, "filterFor") then
local filterString = cfxZones.getStringFromZoneProperty(theZone, "filterFor", "1") -- ground
theZone.filterFor = unitZone.string2cat(filterString)
if unitZone.verbose then
if unitZone.verbose or theZone.verbose then
trigger.action.outText("+++uZne: filtering " .. theZone.filterFor .. " in " .. theZone.name, 30)
end
end
-- on/off flags
theZone.uzPaused = false -- we are turned on
theZone.triggerOnFlag = cfxZones.getStringFromZoneProperty(theZone, "uzOn?", "*<none1>")
theZone.lastTriggerOnValue = cfxZones.getFlagValue(theZone.triggerOnFlag, theZone)
theZone.triggerOffFlag = cfxZones.getStringFromZoneProperty(theZone, "uzOff?", "*<none2>")
theZone.lastTriggerOffValue = cfxZones.getFlagValue(theZone.triggerOffFlag, theZone)
theZone.uzTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
if cfxZones.hasProperty(theZone, "uzTriggerMethod") then
theZone.uzTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "uzTriggerMethod", "change")
end
-- now get initial zone status ?
theZone.lastStatus = unitZone.checkZoneStatus(theZone)
if unitZone.verbose then
if unitZone.verbose or theZone.verbose then
trigger.action.outText("+++uZne: processsed unit zone " .. theZone.name, 30)
end
end
@ -221,13 +236,30 @@ function unitZone.update()
timer.scheduleFunction(unitZone.update, {}, timer.getTime() + 1/unitZone.ups)
for idx, aZone in pairs(unitZone.unitZones) do
-- scan all zones
local newState = unitZone.checkZoneStatus(aZone)
-- check if we need to pause/unpause
if cfxZones.testZoneFlag(aZone, aZone.triggerOnFlag, aZone.uzTriggerMethod, "lastTriggerOnValue") then
if unitZone.verbose or aZone.verbose then
trigger.action.outText("+++uZone: turning " .. aZone.name .. " on", 30)
end
aZone.uzPaused = false
end
if newState ~= aZone.lastStatus then
-- bang on change!
unitZone.bangState(aZone, newState)
aZone.lastStatus = newState
if cfxZones.testZoneFlag(aZone, aZone.triggerOffFlag, aZone.uzTriggerMethod, "lastTriggerOffValue") then
if unitZone.verbose or aZone.verbose then
trigger.action.outText("+++uZone: turning " .. aZone.name .. " OFF", 30)
end
aZone.uzPaused = true
end
-- scan all zones
if not aZone.uzPaused then
local newState = unitZone.checkZoneStatus(aZone)
if newState ~= aZone.lastStatus then
-- bang on change!
unitZone.bangState(aZone, newState)
aZone.lastStatus = newState
end
end
end
end

278
modules/wiper.lua Normal file
View File

@ -0,0 +1,278 @@
wiper = {}
wiper.version = "1.0.0"
wiper.verbose = false
wiper.ups = 1
wiper.requiredLibs = {
"dcsCommon", -- always
"cfxZones", -- Zones, of course
}
wiper.wipers = {}
--[[--
Version History
1.0.0 - Initial Version
--]]--
function wiper.addWiper(theZone)
table.insert(wiper.wipers, theZone)
end
function wiper.getWiperByName(aName)
for idx, aZone in pairs(wiper.wipers) do
if aName == aZone.name then return aZone end
end
if wiper.verbose then
trigger.action.outText("+++wpr: no wiper with name <" .. aName ..">", 30)
end
return nil
end
--
-- read zone
--
function wiper.createWiperWithZone(theZone)
theZone.triggerWiperFlag = cfxZones.getStringFromZoneProperty(theZone, "wipe?", "*<none>")
-- triggerWiperMethod
theZone.triggerWiperMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change")
if cfxZones.hasProperty(theZone, "triggerWiperMethod") then
theZone.triggerWiperMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerWiperMethod", "change")
end
if theZone.triggerWiperFlag then
theZone.lastTriggerWiperValue = cfxZones.getFlagValue(theZone.triggerWiperFlag, theZone)
end
local theCat = cfxZones.getStringFromZoneProperty(theZone, "category", "static")
if cfxZones.hasProperty(theZone, "wipeCategory") then
theCat = cfxZones.getStringFromZoneProperty(theZone, "wipeCategory", "static")
end
if cfxZones.hasProperty(theZone, "wipeCat") then
theCat = cfxZones.getStringFromZoneProperty(theZone, "wipeCat", "static")
end
theZone.wipeCategory = dcsCommon.string2ObjectCat(theCat)
if cfxZones.hasProperty(theZone, "wipeNamed") then
theZone.wipeNamed = cfxZones.getStringFromZoneProperty(theZone, "wipeNamed", "<no name given>")
theZone.oWipeNamed = theZone.wipeNamed -- save original
-- assemble list of all names to wipe, including wildcard
local allNames = {}
if dcsCommon.containsString(theZone.wipeNamed, ",") then
allNames = dcsCommon.splitString(theZone.wipeNamed, ",")
allNames = dcsCommon.trimArray(allNames)
else
allNames = {dcsCommon.trim(theZone.wipeNamed)}
end
-- assemble dict of all wipeNamed and endswith
local theDict = {}
for idx, aName in pairs(allNames) do
local shortName = aName
local ew = dcsCommon.stringEndsWith(aName, "*")
if ew then
shortName = dcsCommon.removeEnding(aName, "*")
end
theDict[shortName] = ew
if wiper.verbose or theZone.verbose then
trigger.action.outText("+++wpr: dict [".. shortName .."] = " .. dcsCommon.bool2Text(ew),30)
end
end
theZone.wipeNamed = theDict
end
theZone.wipeInventory = cfxZones.getBoolFromZoneProperty(theZone, "wipeInventory", false)
if wiper.verbose or theZone.verbose then
trigger.action.outText("+++wpr: new wiper zone <".. theZone.name ..">", 30)
end
end
--
-- Wiper main action
--
function wiper.objectHandler(theObject, theCollector)
table.insert(theCollector, theObject)
return true
end
wiper.inventory = ""
function wiper.seeZoneInventory(theZone)
-- run a diag which objects are in the zone, and which cat they are
-- set up args
local allCats = {1, 2, 3, 4, 5, 6}
wiper.inventory = ""
for idx, aCat in pairs(allCats) do
local p = cfxZones.getPoint(theZone)
local lp = {x = p.x, y = p.z}
p.y = land.getHeight(lp)
local collector = {}
-- now build the search argument
local args = {
id = world.VolumeType.SPHERE,
params = {
point = p,
radius = theZone.radius
}
}
-- now call search
world.searchObjects(aCat, args, wiper.objectHandler, collector)
wiper.inventory = wiper.inventory .. "Cat = " .. aCat .. ":"
for idy, anObject in pairs(collector) do
wiper.inventory = wiper.inventory .. anObject:getName() .. " "
end
wiper.inventory = wiper.inventory .. "\n"
end
end
function wiper.isTriggered(theZone)
-- see if we need a diagnostic run
wiper.inventory = ""
if theZone.wipeInventory then
wiper.seeZoneInventory(theZone)
-- inventory data
if theZone.wipeInventory then
trigger.action.outText(wiper.inventory, 30)
end
end
-- get current location in case theZone is moving
local p = cfxZones.getPoint(theZone)
local lp = {x = p.x, y = p.z}
p.y = land.getHeight(lp)
local collector = {}
-- now build the search argument
local args = {
id = world.VolumeType.SPHERE,
params = {
point = p,
radius = theZone.radius
}
}
-- set up remaining arguments
local cat = theZone.wipeCategory -- Object.Category.STATIC
-- now call search
world.searchObjects(cat, args, wiper.objectHandler, collector)
if #collector < 1 and (wiper.verbose or theZone.verbose) then
trigger.action.outText("+++wpr: world search returned zero elements for <" .. theZone.name .. "> (cat=" .. theZone.wipeCategory .. ")",30)
end
-- wipe'em!
for idx, anObject in pairs(collector) do
local doWipe = true
-- see if we filter to only named objects
if theZone.wipeNamed then
doWipe = false
local oName = tostring(anObject:getName()) -- prevent number mismatch
for wipeName, beginsWith in pairs(theZone.wipeNamed) do
if beginsWith then
doWipe = doWipe or dcsCommon.stringStartsWith(oName, wipeName)
else
doWipe = doWipe or oName == wipeName
end
end
if wiper.verbose or theZone.verbose then
if not doWipe then
trigger.action.outText("+++wpr: <"..oName.."> not removed, name restriction <" .. theZone.oWipeNamed .. "> not met.",30)
end
end
end
if doWipe then
if wiper.verbose or theZone.verbose then
trigger.action.outText("+++wpr: wiping " .. anObject:getName(), 30)
end
anObject:destroy()
else
if wiper.verbose or theZone.verbose then
trigger.action.outText("+++wpr: spared object <" .. anObject:getName() .. ">",30)
end
end
end
end
--
-- Update
--
function wiper.update()
-- call me in a second to poll triggers
timer.scheduleFunction(wiper.update, {}, timer.getTime() + 1/wiper.ups)
for idx, aZone in pairs(wiper.wipers) do
if cfxZones.testZoneFlag(aZone, aZone.triggerWiperFlag, aZone.triggerWiperMethod, "lastTriggerWiperValue") then
if wiper.verbose or aZone.verbose then
trigger.action.outText("+++wpr: triggered on ".. aZone.triggerWiperFlag .. " for <".. aZone.name ..">", 30)
end
wiper.isTriggered(aZone)
end
end
end
--
-- Config & Start
--
function wiper.readConfigZone()
local theZone = cfxZones.getZoneByName("wiperConfig")
if not theZone then
if wiper.verbose then
trigger.action.outText("+++wpr: NO config zone!", 30)
end
theZone = cfxZones.createSimpleZone("wiperConfig") -- temp only
end
wiper.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
wiper.ups = cfxZones.getNumberFromZoneProperty(theZone, "ups", 1)
if wiper.verbose then
trigger.action.outText("+++wpr: read config", 30)
end
end
function wiper.start()
-- lib check
if not dcsCommon.libCheck then
trigger.action.outText("cfx Wiper requires dcsCommon", 30)
return false
end
if not dcsCommon.libCheck("cfx Wiper", wiper.requiredLibs) then
return false
end
-- read config
wiper.readConfigZone()
-- process cloner Zones
local attrZones = cfxZones.getZonesWithAttributeNamed("wipe?")
for k, aZone in pairs(attrZones) do
wiper.createWiperWithZone(aZone) -- process attributes
wiper.addWiper(aZone) -- add to list
end
-- start update
wiper.update()
trigger.action.outText("cfx Wiper v" .. wiper.version .. " started.", 30)
return true
end
-- let's go!
if not wiper.start() then
trigger.action.outText("cfx Wiper aborted: missing libraries", 30)
wiper = nil
end

View File

@ -1,5 +1,5 @@
xFlags = {}
xFlags.version = "1.0.1"
xFlags.version = "1.2.0"
xFlags.verbose = false
xFlags.ups = 1 -- overwritten in get config when configZone is present
xFlags.requiredLibs = {
@ -13,6 +13,8 @@ xFlags.requiredLibs = {
1.0.0 - Initial version
1.0.1 - allow flags names for ops as well
1.1.0 - Watchflags harmonization
1.2.0 - xDirect flag,
- direct array support
--]]--
xFlags.xFlagZones = {}
@ -62,13 +64,17 @@ function xFlags.createXFlagsWithZone(theZone)
theZone.xHasFired = false
theZone.xSuccess = cfxZones.getStringFromZoneProperty(theZone, "xSuccess!", "<none>")
if cfxZones.hasProperty(theZone, "out!") then
theZone.xSuccess = cfxZones.getStringFromZoneProperty(theZone, "out!", "<none>")
theZone.xSuccess = cfxZones.getStringFromZoneProperty(theZone, "out!", "*<none>")
end
if cfxZones.hasProperty(theZone, "xChange!") then
theZone.xChange = cfxZones.getStringFromZoneProperty(theZone, "xChange!", "<none>")
theZone.xChange = cfxZones.getStringFromZoneProperty(theZone, "xChange!", "*<none>")
end
theZone.xDirect = cfxZones.getStringFromZoneProperty(theZone, "xDirect!", "*<none>")
theZone.inspect = cfxZones.getStringFromZoneProperty(theZone, "require", "or") -- same as any
-- supported any/or, all/and, moreThan, atLeast, exactly
theZone.inspect = string.lower(theZone.inspect)
@ -89,13 +95,15 @@ function xFlags.createXFlagsWithZone(theZone)
theZone.xLastReset = cfxZones.getFlagValue(theZone.xReset, theZone)
end
theZone.xMethod = cfxZones.getStringFromZoneProperty(theZone, "xMethod", "flip")
theZone.xMethod = cfxZones.getStringFromZoneProperty(theZone, "xMethod", "inc")
if cfxZones.hasProperty(theZone, "method") then
theZone.xMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "flip")
theZone.xMethod = cfxZones.getStringFromZoneProperty(theZone, "method", "inc")
end
theZone.xOneShot = cfxZones.getBoolFromZoneProperty(theZone, "oneShot", true)
end
function xFlags.evaluateFlags(theZone)
@ -187,21 +195,28 @@ end
function xFlags.evaluateZone(theZone)
-- short circuit if we are done
if theZone.xHasFired and theZone.xOneShot then return end
local hits, checkSum = xFlags.evaluateFlags(theZone)
-- depending on inspect see what the outcome is
-- supported any/or, all/and, moreThan, atLeast, exactly
local op = theZone.inspect
local evalResult = false
if (op == "or" or op == "any") and hits > 0 then
if (op == "or" or op == "any" or op == "some") and hits > 0 then
evalResult = true
elseif (op == "and" or op == "all") and hits == #theZone.flagNames then
evalResult = true
elseif (op == "morethan" or op == "more than") and hits > theZone.matchNum then
evalResult = true
elseif (op == "atleast" or op == "at lest") and hits >= theZone.matchNum then
elseif (op == "atleast" or op == "at least") and hits >= theZone.matchNum then
evalResult = true
elseif op == "exactly" and hits == theZone.matchNum then
evalResult = true
elseif (op == "none" or op == "nor") and hits == 0 then
evalResult = true
elseif (op == "not all" or op == "notall" or op == "nand") and hits < #theZone.flagNames then
evalResult = true
end
-- now check if changed and if result true
@ -219,7 +234,17 @@ function xFlags.evaluateZone(theZone)
theZone.flagChecksum = checkSum
end
if theZone.xHasFired and theZone.xOneShot then return end
-- now directly set the value of evalResult (0 = false, 1 = true)
-- to "xDirect!". Always sets output to current result of evaluation
-- true (1)/false(0), no matter if changed or not
if evalResult then
cfxZones.setFlagValueMult(theZone.xDirect, 1, theZone)
else
cfxZones.setFlagValueMult(theZone.xDirect, 0, theZone)
end
-- now see if we bang the output according to method
if evalResult then
if xFlags.verbose then
trigger.action.outText("+++xFlag: success bang! on " .. theZone.xSuccess .. " for " .. theZone.name, 30)