Version 1.4.5

Cloners for HeloTrooper
This commit is contained in:
Christian Franz 2023-10-06 14:53:18 +02:00
parent d1d4af63a0
commit 28830f1378
10 changed files with 308 additions and 213 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
airfield = {} airfield = {}
airfield.version = "1.0.0" airfield.version = "1.1.0"
airfield.requiredLibs = { airfield.requiredLibs = {
"dcsCommon", "dcsCommon",
"cfxZones", "cfxZones",
@ -15,15 +15,21 @@ airfield.farps = false
Version History Version History
1.0.0 - initial release 1.0.0 - initial release
1.1.0 - added 'fixed' attribute
- added 'farps' attribute to individual zones
- allow zone.local farps designation
- always checks farp cap events
- added verbosity
--]]-- --]]--
-- --
-- setting up airfield -- setting up airfield
-- --
function airfield.createAirFieldFromZone(theZone) function airfield.createAirFieldFromZone(theZone)
theZone.farps = theZone:getBoolFromZoneProperty("farps", false)
local filterCat = 0 local filterCat = 0
if airfield.farps then filterCat = {0, 1} end -- bases and farps if (airfield.farps or theZone.farps) then filterCat = {0, 1} end -- bases and farps
local p = theZone:getPoint() local p = theZone:getPoint()
local theBase = dcsCommon.getClosestAirbaseTo(p, filterCat) local theBase = dcsCommon.getClosestAirbaseTo(p, filterCat)
theZone.airfield = theBase theZone.airfield = theBase
@ -72,12 +78,26 @@ function airfield.createAirFieldFromZone(theZone)
trigger.action.setUserFlag(theZone.ownedBy, theZone.owner) trigger.action.setUserFlag(theZone.ownedBy, theZone.owner)
end end
-- if fixed attribute, we switch to that color and keep it fixed.
-- can be overridden by either makeXX or autoCap.
if theZone:hasProperty("fixed") then
local theFixed = theZone:getCoalitionFromZoneProperty("fixed")
local theAirfield = theZone.airfield
airfield.assumeControl(theZone) -- turn off capturable
theAirfield:setCoalition(theFixed)
theZone.owner = theFixed
end
-- index by name, and warn if duplicate associate -- index by name, and warn if duplicate associate
if airfield.myAirfields[theZone.afName] then if airfield.myAirfields[theZone.afName] then
trigger.action.outText("+++airF: WARNING - zone <" .. theZone:getName() .. "> redefines airfield <" .. theZone.afName .. ">, discarded!", 30) trigger.action.outText("+++airF: WARNING - zone <" .. theZone:getName() .. "> redefines airfield <" .. theZone.afName .. ">, discarded!", 30)
else else
airfield.myAirfields[theZone.afName] = theZone airfield.myAirfields[theZone.afName] = theZone
end end
if theZone.verbose or airfield.verbose then
trigger.action.outText("+++airF: airfield zone <" .. theZone.name .. "> associates with <" .. theZone.afName .. ">, current owner is <" .. theZone.owner .. ">", 30)
end
end end
function airfield.assumeControl(theZone) function airfield.assumeControl(theZone)
@ -137,14 +157,14 @@ function airfield:onEvent(event)
local desc = theBase:getDesc() local desc = theBase:getDesc()
local bName = theBase:getName() local bName = theBase:getName()
local cat = desc.category -- never get cat directly! local cat = desc.category -- never get cat directly!
if cat == 1 then --[[-- if cat == 1 then
if not airfield.farps then if not airfield.farps then
if airfield.verbose then if airfield.verbose then
trigger.action.outText("+++airF: ignored cap event for FARP <" .. bName .. ">", 30) trigger.action.outText("+++airF: ignored cap event for FARP <" .. bName .. ">", 30)
end end
return return
end end
end end --]]
if airfield.verbose then if airfield.verbose then
trigger.action.outText("+++airF: cap event for <" .. bName .. ">, cat = (" .. cat .. ")", 30) trigger.action.outText("+++airF: cap event for <" .. bName .. ">, cat = (" .. cat .. ")", 30)
end end

View File

@ -1,9 +1,10 @@
cfxHeloTroops = {} cfxHeloTroops = {}
cfxHeloTroops.version = "2.4.1" cfxHeloTroops.version = "3.0.0"
cfxHeloTroops.verbose = false cfxHeloTroops.verbose = false
cfxHeloTroops.autoDrop = true cfxHeloTroops.autoDrop = true
cfxHeloTroops.autoPickup = false cfxHeloTroops.autoPickup = false
cfxHeloTroops.pickupRange = 100 -- meters cfxHeloTroops.pickupRange = 100 -- meters
cfxHeloTroops.requestRange = 500 -- meters
-- --
--[[-- --[[--
VERSION HISTORY VERSION HISTORY
@ -32,7 +33,11 @@ cfxHeloTroops.pickupRange = 100 -- meters
- removed restriction to only apply to helicopters in anticipation of the C-130 Hercules appearing in the game - removed restriction to only apply to helicopters in anticipation of the C-130 Hercules appearing in the game
2.4.1 - new actionSound attribute, sound plays to group whenever 2.4.1 - new actionSound attribute, sound plays to group whenever
troops have boarded or disembarked troops have boarded or disembarked
3.0.0 - added requestable cloner support
- harmonized spawning invocations across cloners and spawners
- dmlZones
- requestRange attribute
--]]-- --]]--
-- --
-- cfxHeloTroops -- a module to pick up and drop infantry. -- cfxHeloTroops -- a module to pick up and drop infantry.
@ -158,13 +163,11 @@ function cfxHeloTroops.heloLanded(theUnit)
cfxHeloTroops.setCommsMenu(conf.unit) cfxHeloTroops.setCommsMenu(conf.unit)
end end
-- --
-- --
-- Helo took off -- Helo took off
-- --
-- --
function cfxHeloTroops.heloDeparted(theUnit) function cfxHeloTroops.heloDeparted(theUnit)
if not dcsCommon.isTroopCarrier(theUnit, cfxHeloTroops.troopCarriers) then return end if not dcsCommon.isTroopCarrier(theUnit, cfxHeloTroops.troopCarriers) then return end
@ -206,17 +209,14 @@ function cfxHeloTroops.cleanHelo(theUnit)
end end
end end
end end
conf.troopsOnBoard = {} conf.troopsOnBoard = {}
end end
function cfxHeloTroops.heloCrashed(theUnit) function cfxHeloTroops.heloCrashed(theUnit)
if not dcsCommon.isTroopCarrier(theUnit, cfxHeloTroops.troopCarriers) then return if not dcsCommon.isTroopCarrier(theUnit, cfxHeloTroops.troopCarriers) then return
end end
-- clean up -- clean up
cfxHeloTroops.cleanHelo(theUnit) cfxHeloTroops.cleanHelo(theUnit)
end end
-- --
@ -252,7 +252,6 @@ function cfxHeloTroops.removeComms(theUnit)
conf.id = id conf.id = id
conf.unit = theUnit conf.unit = theUnit
cfxHeloTroops.removeCommsFromConfig(conf) cfxHeloTroops.removeCommsFromConfig(conf)
end end
@ -371,16 +370,15 @@ function cfxHeloTroops.addGroundMenu(conf)
return return
end end
-- case 2A: no troops aboard, and spawners in range -- case 2A: no troops aboard, and requestable spawners/cloners in range
-- that are requestable
local p = conf.unit:getPosition().p local p = conf.unit:getPosition().p
local mySide = conf.unit:getCoalition() local mySide = conf.unit:getCoalition()
if cfxSpawnZones then -- collect available spawn zones
-- only if SpawnZones is implemented local availableSpawners = {}
local availableSpawnersRaw = cfxSpawnZones.getRequestableSpawnersInRange(p, 500, mySide) if cfxSpawnZones then -- only if SpawnZones is implemented
-- DONE: requestable spawners must check for troop compatibility local availableSpawnersRaw = cfxSpawnZones.getRequestableSpawnersInRange(p, cfxHeloTroops.requestRange, mySide)
local availableSpawners = {}
for idx, aSpawner in pairs(availableSpawnersRaw) do for idx, aSpawner in pairs(availableSpawnersRaw) do
-- filter all spawners that spawn "illegal" troops -- filter all spawners that spawn "illegal" troops
local theTypes = aSpawner.types local theTypes = aSpawner.types
@ -403,26 +401,55 @@ function cfxHeloTroops.addGroundMenu(conf)
table.insert(availableSpawners, aSpawner) table.insert(availableSpawners, aSpawner)
end end
end end
end
local numSpawners = #availableSpawners
if numSpawners > 5 then numSpawners = 5 end
while numSpawners > 0 do
-- for each spawner in range, create a
-- spawn menu item
local spawner = availableSpawners[numSpawners]
local theName = spawner.baseName
local comm = "Request <" .. theName .. "> troops for transport" -- .. math.floor(aTeam.dist) .. "m away"
local theCommand = missionCommands.addCommandForGroup(
conf.id,
comm,
conf.myMainMenu,
cfxHeloTroops.redirectSpawnGroup,
{conf, spawner}
)
table.insert(conf.myCommands, theCommand)
numSpawners = numSpawners - 1
end
-- collect available clone zones
if cloneZones then
local availableSpawnersRaw = cloneZones.getRequestableClonersInRange(p, cfxHeloTroops.requestRange, mySide)
for idx, aSpawner in pairs(availableSpawnersRaw) do
-- filter all spawners that spawn "illegal" troops or have none
local theTypes = aSpawner.allTypes
local allLegal = true
local numTypes = dcsCommon.getSizeOfTable(theTypes)
if numTypes > 0 then
for aType, cnt in pairs(theTypes) do
if cfxHeloTroops.legalTroops then
if not dcsCommon.arrayContainsString(cfxHeloTroops.legalTroops, aType) then
allLegal = false
end
else
if not dcsCommon.typeIsInfantry(aType) then
allLegal = false
end
end
end
else
allegal = false
end
if allLegal then
table.insert(availableSpawners, aSpawner)
end
end
end
local numSpawners = #availableSpawners
if numSpawners > 5 then numSpawners = 5 end
while numSpawners > 0 do
-- for each spawner in range, create a
-- spawn menu item
local spawner = availableSpawners[numSpawners]
local theName = spawner.baseName
local comm = "Request <" .. theName .. "> troops for transport" -- .. math.floor(aTeam.dist) .. "m away"
local theCommand = missionCommands.addCommandForGroup(
conf.id,
comm,
conf.myMainMenu,
cfxHeloTroops.redirectSpawnGroup,
{conf, spawner}
)
table.insert(conf.myCommands, theCommand)
numSpawners = numSpawners - 1
end end
-- case 2B: no troops aboard. see if there are troops around -- case 2B: no troops aboard. see if there are troops around
@ -440,7 +467,6 @@ function cfxHeloTroops.addGroundMenu(conf)
-- now limit the options to the five closest legal groups -- now limit the options to the five closest legal groups
local numUnits = #unitsToLoad local numUnits = #unitsToLoad
if numUnits > 5 then numUnits = 5 end if numUnits > 5 then numUnits = 5 end
if numUnits < 1 then if numUnits < 1 then
local theCommand = missionCommands.addCommandForGroup( local theCommand = missionCommands.addCommandForGroup(
conf.id, conf.id,
@ -469,8 +495,6 @@ function cfxHeloTroops.addGroundMenu(conf)
) )
table.insert(conf.myCommands, theCommand) table.insert(conf.myCommands, theCommand)
end end
end end
function cfxHeloTroops.filterTroopsByType(unitsToLoad) function cfxHeloTroops.filterTroopsByType(unitsToLoad)
@ -546,7 +570,6 @@ end
-- --
-- Deploying Troops -- Deploying Troops
-- --
function cfxHeloTroops.redirectDeployTroops(args) function cfxHeloTroops.redirectDeployTroops(args)
timer.scheduleFunction(cfxHeloTroops.doDeployTroops, args, timer.getTime() + 0.1) timer.scheduleFunction(cfxHeloTroops.doDeployTroops, args, timer.getTime() + 0.1)
end end
@ -626,8 +649,7 @@ function cfxHeloTroops.deployTroopsFromHelicopter(conf)
trigger.action.outTextForGroup(conf.id, "+++ <" .. conf.troopsOnBoard.name .. "> revoke 'wait' orders, proceed with <".. orders .. ">", 30) trigger.action.outTextForGroup(conf.id, "+++ <" .. conf.troopsOnBoard.name .. "> revoke 'wait' orders, proceed with <".. orders .. ">", 30)
end end
local chopperZone = cfxZones.createSimpleZone("choppa", p, 12) -- 12 m ratius around choppa local chopperZone = cfxZones.createSimpleZone("choppa", p, 12) -- 12 m radius around choppa
--local theCoalition = theUnit:getCountry() -- make it choppers country
local theCoalition = theUnit:getGroup():getCoalition() -- make it choppers COALITION local theCoalition = theUnit:getGroup():getCoalition() -- make it choppers COALITION
local theGroup, theData = cfxZones.createGroundUnitsInZoneForCoalition ( local theGroup, theData = cfxZones.createGroundUnitsInZoneForCoalition (
theCoalition, theCoalition,
@ -649,7 +671,7 @@ function cfxHeloTroops.deployTroopsFromHelicopter(conf)
troop.destination = dest -- transfer target zone for attackzone oders troop.destination = dest -- transfer target zone for attackzone oders
cfxGroundTroops.addGroundTroopsToPool(troop) -- will schedule move orders cfxGroundTroops.addGroundTroopsToPool(troop) -- will schedule move orders
trigger.action.outTextForGroup(conf.id, "<" .. theGroup:getName() .. "> have deployed to the ground with orders " .. orders .. "!", 30) trigger.action.outTextForGroup(conf.id, "<" .. theGroup:getName() .. "> have deployed to the ground with orders " .. orders .. "!", 30)
trigger.action.outSoundForGroup(conf.id, cfxHeloTroops.actionSound) -- "Quest Snare 3.wav") trigger.action.outSoundForGroup(conf.id, cfxHeloTroops.actionSound)
-- see if this is tracked by a tracker, and pass them back so -- see if this is tracked by a tracker, and pass them back so
-- they can un-limbo -- they can un-limbo
if groupTracker then if groupTracker then
@ -665,7 +687,6 @@ function cfxHeloTroops.deployTroopsFromHelicopter(conf)
end end
end end
-- --
-- Loading Troops -- Loading Troops
-- --
@ -755,7 +776,7 @@ end
function cfxHeloTroops.doSpawnGroup(args) function cfxHeloTroops.doSpawnGroup(args)
local conf = args[1] local conf = args[1]
local theSpawner = args[2] local theSpawner = args[2]
-- NOTE: theSpawner can be of type cfxSpawnZone !!!OR!!! cfxCloneZones
-- make sure cooldown on spawner has timed out, else -- make sure cooldown on spawner has timed out, else
-- notify that you have to wait -- notify that you have to wait
local now = timer.getTime() local now = timer.getTime()
@ -765,13 +786,13 @@ function cfxHeloTroops.doSpawnGroup(args)
return return
end end
cfxSpawnZones.spawnWithSpawner(theSpawner) --cfxSpawnZones.spawnWithSpawner(theSpawner) -- old code
theSpawner.spawnWithSpawner(theSpawner) -- can be both spawner and cloner
trigger.action.outTextForGroup(conf.id, "Deploying <" .. theSpawner.baseName .. "> now...", 30) trigger.action.outTextForGroup(conf.id, "Deploying <" .. theSpawner.baseName .. "> now...", 30)
-- reset all comms so we can include new troops -- reset all comms so we can include new troops
-- into load menu -- into load menu
timer.scheduleFunction(cfxHeloTroops.delayedCommsResetForUnit, {conf.unit, "ignore"}, now + 1.0) timer.scheduleFunction(cfxHeloTroops.delayedCommsResetForUnit, {conf.unit, "ignore"}, now + 1.0)
end end
-- --
@ -859,14 +880,13 @@ function cfxHeloTroops.readConfigZone()
-- note: must match exactly!!!! -- note: must match exactly!!!!
local theZone = cfxZones.getZoneByName("heloTroopsConfig") local theZone = cfxZones.getZoneByName("heloTroopsConfig")
if not theZone then if not theZone then
trigger.action.outText("+++heloT: no config zone!", 30)
theZone = cfxZones.createSimpleZone("heloTroopsConfig") theZone = cfxZones.createSimpleZone("heloTroopsConfig")
end end
cfxHeloTroops.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false) cfxHeloTroops.verbose = theZone:getBoolFromZoneProperty("verbose", false)
if cfxZones.hasProperty(theZone, "legalTroops") then if theZone:hasProperty("legalTroops") then
local theTypesString = cfxZones.getStringFromZoneProperty(theZone, "legalTroops", "") local theTypesString = theZone:getStringFromZoneProperty("legalTroops", "")
local unitTypes = dcsCommon.splitString(aSpawner.types, ",") local unitTypes = dcsCommon.splitString(aSpawner.types, ",")
if #unitTypes < 1 then if #unitTypes < 1 then
unitTypes = {"Soldier AK", "Infantry AK", "Infantry AK ver2", "Infantry AK ver3", "Infantry AK Ins", "Soldier M249", "Soldier M4 GRG", "Soldier M4", "Soldier RPG", "Paratrooper AKS-74", "Paratrooper RPG-16", "Stinger comm dsr", "Stinger comm", "Soldier stinger", "SA-18 Igla-S comm", "SA-18 Igla-S manpad", "Igla manpad INS", "SA-18 Igla comm", "SA-18 Igla manpad",} -- default unitTypes = {"Soldier AK", "Infantry AK", "Infantry AK ver2", "Infantry AK ver3", "Infantry AK Ins", "Soldier M249", "Soldier M4 GRG", "Soldier M4", "Soldier RPG", "Paratrooper AKS-74", "Paratrooper RPG-16", "Stinger comm dsr", "Stinger comm", "Soldier stinger", "SA-18 Igla-S comm", "SA-18 Igla-S manpad", "Igla manpad INS", "SA-18 Igla comm", "SA-18 Igla manpad",} -- default
@ -876,18 +896,19 @@ function cfxHeloTroops.readConfigZone()
cfxHeloTroops.legalTroops = unitTypes cfxHeloTroops.legalTroops = unitTypes
end end
cfxHeloTroops.troopWeight = cfxZones.getNumberFromZoneProperty(theZone, "troopWeight", 100) -- kg average weight per trooper cfxHeloTroops.troopWeight = theZone:getNumberFromZoneProperty("troopWeight", 100) -- kg average weight per trooper
cfxHeloTroops.autoDrop = cfxZones.getBoolFromZoneProperty(theZone, "autoDrop", false) cfxHeloTroops.autoDrop = theZone:getBoolFromZoneProperty("autoDrop", false)
cfxHeloTroops.autoPickup = cfxZones.getBoolFromZoneProperty(theZone, "autoPickup", false) cfxHeloTroops.autoPickup = theZone:getBoolFromZoneProperty("autoPickup", false)
cfxHeloTroops.pickupRange = cfxZones.getNumberFromZoneProperty(theZone, "pickupRange", 100) cfxHeloTroops.pickupRange = theZone:getNumberFromZoneProperty("pickupRange", 100)
cfxHeloTroops.combatDropScore = cfxZones.getNumberFromZoneProperty(theZone, "combatDropScore", 200) cfxHeloTroops.combatDropScore = theZone:getNumberFromZoneProperty( "combatDropScore", 200)
cfxHeloTroops.actionSound = cfxZones.getStringFromZoneProperty(theZone, "actionSound", "Quest Snare 3.wav") cfxHeloTroops.actionSound = theZone:getStringFromZoneProperty("actionSound", "Quest Snare 3.wav")
cfxHeloTroops.requestRange = theZone:getNumberFromZoneProperty("requestRange", 500)
-- add own troop carriers -- add own troop carriers
if cfxZones.hasProperty(theZone, "troopCarriers") then if theZone:hasProperty("troopCarriers") then
local tc = cfxZones.getStringFromZoneProperty(theZone, "troopCarriers", "UH-1D") local tc = theZone:getStringFromZoneProperty("troopCarriers", "UH-1D")
tc = dcsCommon.splitString(tc, ",") tc = dcsCommon.splitString(tc, ",")
cfxHeloTroops.troopCarriers = dcsCommon.trimArray(tc) cfxHeloTroops.troopCarriers = dcsCommon.trimArray(tc)
end end

View File

@ -1,5 +1,5 @@
cfxSpawnZones = {} cfxSpawnZones = {}
cfxSpawnZones.version = "1.7.5" cfxSpawnZones.version = "2.0.0"
cfxSpawnZones.requiredLibs = { cfxSpawnZones.requiredLibs = {
"dcsCommon", -- common is of course needed for everything "dcsCommon", -- common is of course needed for everything
-- pretty stupid to check for this since we -- pretty stupid to check for this since we
@ -68,27 +68,10 @@ cfxSpawnZones.spawnedGroups = {}
1.7.4 - wait-attackZone fixes 1.7.4 - wait-attackZone fixes
1.7.5 - improved verbosity on spawning 1.7.5 - improved verbosity on spawning
- getRequestableSpawnersInRange() ignores height for distance - getRequestableSpawnersInRange() ignores height for distance
2.0.0 - dmlZones
- moved "types" to spawner
- types - type strings, comma separated - baseName defaults to zone name, as it is safe for naming
see here: https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB - spawnWithSpawner direct link in spawner to spawnZones
- country - defaults to 2 (usa) -- see here https://wiki.hoggitworld.com/view/DCS_enum_country
some important: 0 = Russia, 2 = US, 82 = UN neutral
country is converted to coalition and then assigned to
Joint Task Force <side> upon spawn
- formation - default is circle_out; other formations are
- line - left lo right (west-east) facing north
- line_V - vertical line, facing north
- chevron - west-east, point growing to north
- scattered, random
- circle, circle_forward (all fact north)
- circle-in (all face in)
- circle-out (all face out)
- grid, square, rect arrayed in optimal grid
- 2deep, 2cols two columns, deep
- 2wide 2 columns wide (2 deep)
--]]-- --]]--
cfxSpawnZones.allSpawners = {} cfxSpawnZones.allSpawners = {}
@ -115,103 +98,101 @@ function cfxSpawnZones.createSpawner(inZone)
local theSpawner = {} local theSpawner = {}
theSpawner.zone = inZone theSpawner.zone = inZone
theSpawner.name = inZone.name theSpawner.name = inZone.name
theSpawner.spawnWithSpawner = cfxSpawnZones.spawnWithSpawner
-- interface to groupTracker -- interface to groupTracker
-- WARNING: attaches to ZONE, not spawner object -- WARNING: attaches to ZONE, not spawner object
if cfxZones.hasProperty(inZone, "trackWith:") then if inZone:hasProperty("trackWith:") then
inZone.trackWith = cfxZones.getStringFromZoneProperty(inZone, "trackWith:", "<None>") inZone.trackWith = inZone:getStringFromZoneProperty("trackWith:", "<None>")
end end
-- interface to delicates -- interface to delicates
if cfxZones.hasProperty(inZone, "useDelicates") then if inZone:hasProperty("useDelicates") then
theSpawner.delicateName = dcsCommon.trim(cfxZones.getStringFromZoneProperty(inZone, "useDelicates", "<none>")) theSpawner.delicateName = dcsCommon.trim(inZone:getStringFromZoneProperty("useDelicates", "<none>"))
if theSpawner.delicateName == "*" then theSpawner.delicateName = inZone.name end if theSpawner.delicateName == "*" then theSpawner.delicateName = inZone.name end
end end
-- connect with ME if a trigger flag is given -- connect with ME if a trigger flag is given
if cfxZones.hasProperty(inZone, "f?") then if inZone:hasProperty("f?") then
theSpawner.triggerFlag = cfxZones.getStringFromZoneProperty(inZone, "f?", "none") theSpawner.triggerFlag = inZone:getStringFromZoneProperty("f?", "none")
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
elseif inZone:hasProperty("spawn?") then
theSpawner.triggerFlag = inZone:getStringFromZoneProperty("spawn?", "none")
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
elseif inZone:hasProperty("spawnUnits?") then
theSpawner.triggerFlag = inZone:getStringFromZoneProperty( "spawnObject?", "none")
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag) theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
end end
-- synonyms spawn? and spawnObject? if inZone:hasProperty("activate?") then
if cfxZones.hasProperty(inZone, "spawn?") then theSpawner.activateFlag = inZone:getStringFromZoneProperty( "activate?", "none")
theSpawner.triggerFlag = cfxZones.getStringFromZoneProperty(inZone, "spawn?", "none")
theSpawner.lastTriggerValue = trigger.misc.getUserFlag(theSpawner.triggerFlag)
end
if cfxZones.hasProperty(inZone, "spawnUnits?") then
theSpawner.triggerFlag = cfxZones.getStringFromZoneProperty(inZone, "spawnObject?", "none")
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) theSpawner.lastActivateValue = trigger.misc.getUserFlag(theSpawner.activateFlag)
end end
if cfxZones.hasProperty(inZone, "pause?") then if inZone:hasProperty("pause?") then
theSpawner.pauseFlag = cfxZones.getStringFromZoneProperty(inZone, "pause?", "none") theSpawner.pauseFlag = inZone:getStringFromZoneProperty("pause?", "none")
theSpawner.lastPauseValue = trigger.misc.getUserFlag(theSpawner.pauseFlag) theSpawner.lastPauseValue = trigger.misc.getUserFlag(theSpawner.pauseFlag)
end end
theSpawner.types = cfxZones.getZoneProperty(inZone, "types") if inZone:hasProperty("types") then
--theSpawner.owner = cfxZones.getCoalitionFromZoneProperty(inZone, "owner", 0) theSpawner.types = inZone:getStringFromZoneProperty("types", "Soldier M4")
-- synthesize types * typeMult else
local n = cfxZones.getNumberFromZoneProperty(inZone, "typeMult", 1) theSpawner.types = inZone:getStringFromZoneProperty("spawner", "Soldier M4")
local repeater = "" end
if n < 1 then n = 1 end -- synthesize types * typeMult
while n > 1 do if inZone:hasProperty("typeMult") then
repeater = repeater .. "," .. theSpawner.types local n = inZone:getNumberFromZoneProperty("typeMult", 1)
n = n - 1 local repeater = ""
if n < 1 then n = 1 end
while n > 1 do
repeater = repeater .. "," .. theSpawner.types
n = n - 1
end
theSpawner.types = theSpawner.types .. repeater
end end
theSpawner.types = theSpawner.types .. repeater
theSpawner.country = cfxZones.getNumberFromZoneProperty(inZone, "country", 0) -- coalition2county(theSpawner.owner) theSpawner.country = inZone:getNumberFromZoneProperty("country", 0)
theSpawner.masterZoneName = cfxZones.getStringFromZoneProperty(inZone, "masterOwner", "") if inZone:hasProperty("masterOwner") then
if theSpawner.masterZoneName == "" then theSpawner.masterZoneName = nil end theSpawner.masterZoneName = inZone:getStringFromZoneProperty("masterOwner", "")
if theSpawner.masterZoneName == "" then theSpawner.masterZoneName = nil end
end
theSpawner.rawOwner = coalition.getCountryCoalition(theSpawner.country) theSpawner.rawOwner = coalition.getCountryCoalition(theSpawner.country)
--theSpawner.baseName = cfxZones.getZoneProperty(inZone, "baseName") -- theSpawner.baseName = inZone:getStringFromZoneProperty("baseName", dcsCommon.uuid("SpwnDflt"))
theSpawner.baseName = cfxZones.getStringFromZoneProperty(inZone, "baseName", dcsCommon.uuid("SpwnDflt")) theSpawner.baseName = inZone:getStringFromZoneProperty("baseName", "*")
theSpawner.baseName = dcsCommon.trim(theSpawner.baseName) theSpawner.baseName = dcsCommon.trim(theSpawner.baseName)
if theSpawner.baseName == "*" then if theSpawner.baseName == "*" then
theSpawner.baseName = inZone.name -- convenience shortcut theSpawner.baseName = inZone.name -- convenience shortcut
end end
theSpawner.cooldown = cfxZones.getNumberFromZoneProperty(inZone, "cooldown", 60) theSpawner.cooldown = inZone:getNumberFromZoneProperty("cooldown", 60)
theSpawner.autoRemove = cfxZones.getBoolFromZoneProperty(inZone, "autoRemove", false) theSpawner.autoRemove = inZone:getBoolFromZoneProperty("autoRemove", false)
theSpawner.lastSpawnTimeStamp = -10000 -- just init so it will always work theSpawner.lastSpawnTimeStamp = -10000 -- init so it will always work
theSpawner.heading = cfxZones.getNumberFromZoneProperty(inZone, "heading", 0) theSpawner.heading = inZone:getNumberFromZoneProperty("heading", 0)
--trigger.action.outText("+++spwn: zone " .. inZone.name .. " owner " .. theSpawner.owner " --> ctry " .. theSpawner.country, 30)
theSpawner.cdTimer = 0 -- used for cooldown. if timer.getTime < this value, don't spawn theSpawner.cdTimer = 0 -- used for cooldown. if timer.getTime < this value, don't spawn
theSpawner.cdStarted = false -- used to initiate cooldown when theSpawn disappears theSpawner.cdStarted = false -- used to initiate cooldown when theSpawn disappears
theSpawner.count = 1 -- used to create names, and count how many groups created theSpawner.count = 1 -- used to create names, and count how many groups created
theSpawner.theSpawn = nil -- link to last spawned group theSpawner.theSpawn = nil -- link to last spawned group
theSpawner.formation = "circle_out" theSpawner.formation = inZone:getStringFromZoneProperty("formation", "circle_out")
theSpawner.formation = cfxZones.getStringFromZoneProperty(inZone, "formation", "circle_out") theSpawner.paused = inZone:getBoolFromZoneProperty("paused", false)
theSpawner.paused = cfxZones.getBoolFromZoneProperty(inZone, "paused", false)
-- orders are always converted to all lower case -- orders are always converted to all lower case
theSpawner.orders = cfxZones.getStringFromZoneProperty(inZone, "orders", "guard"):lower() theSpawner.orders = inZone:getStringFromZoneProperty("orders", "guard"):lower()
-- used to assign orders, default is 'guard', use "laze" to make them laze targets. can be 'wait-' which may auto-convert to 'guard' after pick-up by helo, to be handled outside. -- used to assign orders, default is 'guard', use "laze" to make them laze targets. can be 'wait-' which may auto-convert to 'guard' after pick-up by helo, to be handled outside.
-- use "train" to tell them to HOLD WEAPONS, don't move and don't participate in loop, so we have in effect target dummies -- use "train" to tell them to HOLD WEAPONS, don't move and don't participate in loop, so we have in effect target dummies
-- can also use order 'dummy' or 'dummies' to switch to train -- can also use order 'dummy' or 'dummies' to switch to train
if theSpawner.orders:lower() == "dummy" or theSpawner.orders:lower() == "dummies" then theSpawner.orders = "train" end if theSpawner.orders:lower() == "dummy" or theSpawner.orders:lower() == "dummies" then theSpawner.orders = "train" end
if theSpawner.orders:lower() == "training" then theSpawner.orders = "train" end if theSpawner.orders:lower() == "training" then theSpawner.orders = "train" end
theSpawner.range = cfxZones.getNumberFromZoneProperty(inZone, "range", 300) -- if we have a range, for example enemy detection for Lasing or engage range theSpawner.range = inZone:getNumberFromZoneProperty("range", 300) -- if we have a range, for example enemy detection for Lasing or engage range
theSpawner.maxSpawns = cfxZones.getNumberFromZoneProperty(inZone, "maxSpawns", -1) -- if there is a limit on how many troops can spawn. -1 = endless spawns theSpawner.maxSpawns = inZone:getNumberFromZoneProperty("maxSpawns", -1) -- if there is a limit on how many troops can spawn. -1 = endless spawns
theSpawner.requestable = cfxZones.getBoolFromZoneProperty(inZone, "requestable", false) theSpawner.requestable = inZone:getBoolFromZoneProperty( "requestable", false)
if theSpawner.requestable then if theSpawner.requestable then
theSpawner.paused = true theSpawner.paused = true
if inZone.verbose or cfxSpawnZones.verbose then if inZone.verbose or cfxSpawnZones.verbose then
trigger.action.outText("+++spwn: spawner <" .. inZone.name .. "> paused: requestable enabled", 30) trigger.action.outText("+++spwn: spawner <" .. inZone.name .. "> paused: requestable enabled", 30)
end end
end end
if cfxZones.hasProperty(inZone, "target") then if inZone:hasProperty("target") then
theSpawner.target = cfxZones.getStringFromZoneProperty(inZone, "target", "") theSpawner.target = inZone:getStringFromZoneProperty("target", "")
if theSpawner.target == "" then -- this is the defaut case if theSpawner.target == "" then -- this is the defaut case
theSpawner.target = nil theSpawner.target = nil
end end

View File

@ -1,5 +1,5 @@
cloneZones = {} cloneZones = {}
cloneZones.version = "1.8.2" cloneZones.version = "1.9.0"
cloneZones.verbose = false cloneZones.verbose = false
cloneZones.requiredLibs = { cloneZones.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
@ -100,8 +100,12 @@ cloneZones.respawnOnGroupID = true
- upgraded config zone parsing - upgraded config zone parsing
1.8.1 - clone zone definition now supports quads 1.8.1 - clone zone definition now supports quads
1.8.2 - on pre-wipe, delay respawn by 0.5s to avoid 'dropping' statics 1.8.2 - on pre-wipe, delay respawn by 0.5s to avoid 'dropping' statics
1.9.0 - minor clean-up for synonyms
- spawnWithSpawner alias for HeloTroops etc requestable SPAWN
- requestable attribute
- cooldown attribute
- cloner collects all types used
- groupScheme attribute
--]]-- --]]--
-- --
@ -194,7 +198,7 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
if cloneZones.verbose or theZone.verbose then if cloneZones.verbose or theZone.verbose then
trigger.action.outText("+++clnZ: new cloner <" .. theZone.name ..">", 30) trigger.action.outText("+++clnZ: new cloner <" .. theZone.name ..">", 30)
end end
theZone.spawnWithSpawner = cloneZones.spawnWithSpawner
theZone.myUniqueCounter = cloneZones.lclUniqueCounter -- init local counter theZone.myUniqueCounter = cloneZones.lclUniqueCounter -- init local counter
local localZones = cloneZones.allGroupsInZoneByData(theZone) local localZones = cloneZones.allGroupsInZoneByData(theZone)
@ -226,11 +230,11 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
theZone.source = theZone:getStringFromZoneProperty("source", "<none>") theZone.source = theZone:getStringFromZoneProperty("source", "<none>")
if theZone.source == "<none>" then theZone.source = nil end if theZone.source == "<none>" then theZone.source = nil end
end end
theZone.allTypes = {} -- names of all types
if not theZone.source then if not theZone.source then
theZone.cloneNames = {} -- names of the groups. only present in template spawners theZone.cloneNames = {} -- names of the groups. only present in template spawners
theZone.staticNames = {} -- names of all statics. only present in templates theZone.staticNames = {} -- names of all statics. only present in templates
for idx, aGroup in pairs(localZones) do for idx, aGroup in pairs(localZones) do
local gName = aGroup:getName() local gName = aGroup:getName()
if gName then if gName then
@ -239,10 +243,19 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
-- now get group data and save a lookup for -- now get group data and save a lookup for
-- resolving internal references -- resolving internal references
local rawData, cat, ctry = cfxMX.getGroupFromDCSbyName(gName) local rawData, cat, ctry = cfxMX.getGroupFromDCSbyName(gName)
-- iterate all units and save their individual types
for idy, aUnit in pairs(rawData.units) do
local theType = aUnit.type
-- trigger.action.outText("proccing type <" .. theType .. ">", 30)
if not theZone.allTypes[theType] then
theZone.allTypes[theType] = 1 -- first one
else
theZone.allTypes[theType] = theZone.allTypes[theType] + 1 -- increment
end
end
local origID = rawData.groupId local origID = rawData.groupId
end end
end end
for idx, aStatic in pairs (localObjects) do for idx, aStatic in pairs (localObjects) do
local sName = aStatic:getName() local sName = aStatic:getName()
if sName then if sName then
@ -277,17 +290,11 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
-- f? and spawn? and other synonyms map to the same -- f? and spawn? and other synonyms map to the same
if theZone:hasProperty("f?") then if theZone:hasProperty("f?") then
theZone.spawnFlag = theZone:getStringFromZoneProperty("f?", "none") theZone.spawnFlag = theZone:getStringFromZoneProperty("f?", "none")
end elseif theZone:hasProperty("in?") then
if theZone:hasProperty("in?") then
theZone.spawnFlag = theZone:getStringFromZoneProperty("in?", "none") theZone.spawnFlag = theZone:getStringFromZoneProperty("in?", "none")
end elseif theZone:hasProperty("spawn?") then
if theZone:hasProperty("spawn?") then
theZone.spawnFlag = theZone:getStringFromZoneProperty("spawn?", "none") theZone.spawnFlag = theZone:getStringFromZoneProperty("spawn?", "none")
end elseif theZone:hasProperty("clone?") then
if theZone:hasProperty("clone?") then
theZone.spawnFlag = theZone:getStringFromZoneProperty("clone?", "none") theZone.spawnFlag = theZone:getStringFromZoneProperty("clone?", "none")
end end
@ -298,13 +305,9 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
-- deSpawn? -- deSpawn?
if theZone:hasProperty("deSpawn?") then if theZone:hasProperty("deSpawn?") then
theZone.deSpawnFlag = theZone:getStringFromZoneProperty( "deSpawn?", "none") theZone.deSpawnFlag = theZone:getStringFromZoneProperty( "deSpawn?", "none")
end elseif theZone:hasProperty("deClone?") then
if theZone:hasProperty("deClone?") then
theZone.deSpawnFlag = theZone:getStringFromZoneProperty( "deClone?", "none") theZone.deSpawnFlag = theZone:getStringFromZoneProperty( "deClone?", "none")
end elseif theZone:hasProperty("wipe?") then
if theZone:hasProperty("wipe?") then
theZone.deSpawnFlag = theZone:getStringFromZoneProperty("wipe?", "none") theZone.deSpawnFlag = theZone:getStringFromZoneProperty("wipe?", "none")
end end
@ -312,6 +315,9 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
theZone.lastDeSpawnValue = theZone:getFlagValue(theZone.deSpawnFlag) theZone.lastDeSpawnValue = theZone:getFlagValue(theZone.deSpawnFlag)
end end
theZone.cooldown = theZone:getNumberFromZoneProperty("cooldown", -1) -- anything > 0 activates cd
theZone.lastSpawnTimeStamp = -10000
theZone.onStart = theZone:getBoolFromZoneProperty("onStart", false) theZone.onStart = theZone:getBoolFromZoneProperty("onStart", false)
theZone.moveRoute = theZone:getBoolFromZoneProperty("moveRoute", false) theZone.moveRoute = theZone:getBoolFromZoneProperty("moveRoute", false)
@ -354,6 +360,15 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
end end
end end
-- interface to requestable, must be unsourced!
if theZone:hasProperty("requestable") then
theZone.requestable = theZone:getBoolFromZoneProperty( "requestable", false)
theZone.baseName = theZone.name -- backward compatibility with HeloTroops
if theZone.source then
trigger.action.outText("WARNING: cloner <" .. theZone.name .. "> has 'source' attribute and is marked 'requestable' - this can result in unrequestable clones", 30)
end
end
-- randomized locations on spawn -- randomized locations on spawn
theZone.rndLoc = theZone:getBoolFromZoneProperty("randomizedLoc", false) theZone.rndLoc = theZone:getBoolFromZoneProperty("randomizedLoc", false)
if theZone:hasProperty("rndLoc") then if theZone:hasProperty("rndLoc") then
@ -380,9 +395,14 @@ function cloneZones.createClonerWithZone(theZone) -- has "Cloner"
theZone.nameScheme = theZone:getStringFromZoneProperty( "nameScheme", "<o>-<uid>") -- default to [<original name> "-" <uuid>] theZone.nameScheme = theZone:getStringFromZoneProperty( "nameScheme", "<o>-<uid>") -- default to [<original name> "-" <uuid>]
end end
if theZone:hasProperty("groupScheme") then
theZone.groupScheme = theZone:getStringFromZoneProperty("groupScheme", "<o>-<uid>")
end
if theZone.identical and theZone.nameScheme then if theZone.identical and theZone.nameScheme then
trigger.action.outText("+++clnZ: WARNING - clone zone <" .. theZone.name .. "> has both IDENTICAL and NAMESCHEME attributes. nameScheme is ignored.", 30) trigger.action.outText("+++clnZ: WARNING - clone zone <" .. theZone.name .. "> has both IDENTICAL and NAMESCHEME/GROUPSCHEME attributes. nameScheme is ignored.", 30)
theZone.nameScheme = nil theZone.nameScheme = nil
theZone.groupScheme = nil
end end
-- we end with clear plate -- we end with clear plate
end end
@ -629,14 +649,19 @@ end
function cloneZones.uniqueNameGroupData(theData, theCloneZone, sourceName) function cloneZones.uniqueNameGroupData(theData, theCloneZone, sourceName)
if not sourceName then sourceName = theCloneZone.name end if not sourceName then sourceName = theCloneZone.name end
theData.name = dcsCommon.uuid(theData.name) if not theCloneZone.groupScheme then
theData.name = dcsCommon.uuid(theData.name)
else
theData.name = cloneZones.nameFromSchema(theCloneZone.groupScheme, theData.name, theCloneZone, sourceName, 1)
end
local schema = theCloneZone.nameScheme
local units = theData.units local units = theData.units
local iterCount = 1 local iterCount = 1
local newName = "none" local newName = "none"
local allNames = {} -- enforce unique names inside group local allNames = {} -- enforce unique names inside group
for idx, aUnit in pairs(units) do for idx, aUnit in pairs(units) do
if theCloneZone and theCloneZone.nameScheme then if theCloneZone and theCloneZone.nameScheme then
local schema = theCloneZone.nameScheme
newName, iterCount = cloneZones.nameFromSchema(schema, aUnit.name, theCloneZone, sourceName, iterCount) newName, iterCount = cloneZones.nameFromSchema(schema, aUnit.name, theCloneZone, sourceName, iterCount)
-- make sure that this name is has not been generated yet -- make sure that this name is has not been generated yet
@ -1490,6 +1515,16 @@ function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)
return spawnedGroups, spawnedStatics return spawnedGroups, spawnedStatics
end end
-- retro-fit for helo troops and others to provide 'requestable' support
function cloneZones.spawnWithSpawner(theZone)
-- analog to cfxSpawnZones.spawnWithSpawner(theSpawner)
-- glue code for helo troops and other modules
-- we may want to check if cloner isn't emtpy first
cloneZones.spawnWithCloner(theZone)
end
function cloneZones.spawnWithCloner(theZone) function cloneZones.spawnWithCloner(theZone)
if not theZone then if not theZone then
trigger.action.outText("+++clnZ: nil zone on spawnWithCloner", 30) trigger.action.outText("+++clnZ: nil zone on spawnWithCloner", 30)
@ -1500,11 +1535,24 @@ function cloneZones.spawnWithCloner(theZone)
return return
end end
-- see if we are on cooldown. If so, exit
if theZone.cooldown > 0 then
local now = timer.getTime()
if now < theZone.lastSpawnTimeStamp + theZone.cooldown then
if theZone.verbose or cloneZones.verbose then
trigger.action.outText("+++clnZ: cloner <" .. theZone.name .. "> still on cool-down, no clone cycle", 30)
end
return
else
theZone.lastSpawnTimeStamp = now
end
end
-- force spawn with this spawner -- force spawn with this spawner
local templateZone = theZone local templateZone = theZone
if theZone.source then if theZone.source then
-- we use a different zone for templates -- we use a different zone for templates
-- souce can be a comma separated list -- source can be a comma separated list
local templateName = theZone.source local templateName = theZone.source
if dcsCommon.containsString(templateName, ",") then if dcsCommon.containsString(templateName, ",") then
local allNames = templateName local allNames = templateName
@ -1615,18 +1663,8 @@ function cloneZones.hasLiveUnits(theZone)
if theZone.mySpawns then if theZone.mySpawns then
for idx, aGroup in pairs(theZone.mySpawns) do for idx, aGroup in pairs(theZone.mySpawns) do
if aGroup:isExist() then if aGroup:isExist() then
-- an easier/faster method would be to invoke
-- aGroup:getSize()
local uNum = aGroup:getSize() local uNum = aGroup:getSize()
if uNum > 0 then return true end if uNum > 0 then return true end
--[[
local allUnits = aGroup:getUnits()
for idy, aUnit in pairs(allUnits) do
if aUnit:isExist() and aUnit:getLife() >= 1 then
return true
end
end
--]]--
end end
end end
end end
@ -1642,6 +1680,49 @@ function cloneZones.hasLiveUnits(theZone)
return false return false
end end
function cloneZones.resolveOwningCoalition(theZone)
if not theZone.masterOwner then return theZone.owner end
local masterZone = cfxZones.getZoneByName(theZone.masterOwner)
if not masterZone then
trigger.action.outText("+++clnZ: cloner " .. theZone.name .. " could not find master owner <" .. theZone.masterOwner .. ">", 30)
return theZone.owner
end
return masterZone.owner
end
function cloneZones.getRequestableClonersInRange(aPoint, aRange, aSide)
if not aSide then aSide = 0 end
if not aRange then aRange = 200 end
if not aPoint then return {} end
local theSpawners = {}
for idx, aZone in pairs(cloneZones.cloners) do
-- iterate all zones and collect those that match
local hasMatch = true
local delta = dcsCommon.distFlat(aPoint, aZone:getPoint())
if delta > aRange then hasMatch = false end
if aSide ~= 0 then
-- check if side is correct for owned zone
local resolved = cloneZones.resolveOwningCoalition(aZone)
--if resolved ~= 0 and resolved ~= aSide then
if resolved == 0 or resolved ~= aSide then
-- failed ownership test. must match and not be zero
hasMatch = false
end
end
if not aZone.requestable then
hasMatch = false
end
if hasMatch then
table.insert(theSpawners, aZone)
end
end
return theSpawners
end
-- --
-- UPDATE -- UPDATE
-- --
@ -1672,14 +1753,7 @@ function cloneZones.update()
-- empty handling -- empty handling
local isEmpty = cloneZones.countLiveUnits(aZone) < 1 and aZone.hasClones local isEmpty = cloneZones.countLiveUnits(aZone) < 1 and aZone.hasClones
if isEmpty then if isEmpty then
-- see if we need to bang a flag -- see if we need to bang a flag
--[[--
if aZone.emptyFlag then
--cloneZones.pollFlag(aZone.emptyFlag)
cfxZones.pollFlag(aZone.emptyFlag, 'inc', aZone)
end
--]]--
if aZone.emptyBangFlag then if aZone.emptyBangFlag then
aZone:pollFlag(aZone.emptyBangFlag, aZone.cloneMethod) aZone:pollFlag(aZone.emptyBangFlag, aZone.cloneMethod)
if cloneZones.verbose then if cloneZones.verbose then
@ -2049,8 +2123,6 @@ end
- FAC Assign group - FAC Assign group
- set freq for unit - set freq for unit
-- fixedName: immutable name, no safe renaming. always use ID and name without changing it. very special use case.
nameTest - optional safety / debug feature that will name-test each unit that is about to be spawned for replacement. Maybe auto turn on when verbose is set? nameTest - optional safety / debug feature that will name-test each unit that is about to be spawned for replacement. Maybe auto turn on when verbose is set?
identical - make a clone of template and do not touch name nor id. will fully replace
make example where transport can be different plane types but have same name make example where transport can be different plane types but have same name
--]]-- --]]--

View File

@ -15,6 +15,10 @@ raiseFlag.flags = {}
1.1.0 - DML update 1.1.0 - DML update
1.2.0 - Watchflag update 1.2.0 - Watchflag update
1.2.1 - support for 'inc', 'dec', 'flip' 1.2.1 - support for 'inc', 'dec', 'flip'
2.0.0 - dmlZones
- full method support
- full DML upgrade
- method attribute (synonym to 'value'
--]]-- --]]--
function raiseFlag.addRaiseFlag(theZone) function raiseFlag.addRaiseFlag(theZone)
@ -43,22 +47,28 @@ function raiseFlag.createRaiseFlagWithZone(theZone)
theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, "raiseFlag!", "<none>") -- the flag to raise theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, "raiseFlag!", "<none>") -- the flag to raise
end end
theZone.flagValue = cfxZones.getStringFromZoneProperty(theZone, "value", "inc") -- value to set to. default is command 'inc' -- pre-method DML raiseFlag is now upgraded to method.
-- flagValue now carries the method
if theZone:hasProperty("value") then -- backward compatibility
theZone.flagValue = theZone:getStringFromZoneProperty("value", "inc") -- value to set to. default is command 'inc'
else
theZone.flagValue = theZone:getStringFromZoneProperty("method", "inc")
end
theZone.flagValue = theZone.flagValue:lower() theZone.flagValue = theZone.flagValue:lower()
theZone.minAfterTime, theZone.maxAfterTime = cfxZones.getPositiveRangeFromZoneProperty(theZone, "afterTime", -1) theZone.minAfterTime, theZone.maxAfterTime = theZone:getPositiveRangeFromZoneProperty("afterTime", -1)
-- method for triggering -- method for triggering
-- watchflag: -- watchflag:
-- triggerMethod -- triggerMethod
theZone.raiseTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "triggerMethod", "change") theZone.raiseTriggerMethod = theZone:getStringFromZoneProperty( "triggerMethod", "change")
if cfxZones.hasProperty(theZone, "raiseTriggerMethod") then if theZone:hasProperty("raiseTriggerMethod") then
theZone.raiseTriggerMethod = cfxZones.getStringFromZoneProperty(theZone, "raiseTriggerMethod", "change") theZone.raiseTriggerMethod = theZone:getStringFromZoneProperty("raiseTriggerMethod", "change")
end end
if cfxZones.hasProperty(theZone, "stopFlag?") then if theZone:hasProperty("stopFlag?") then
theZone.triggerStopFlag = cfxZones.getStringFromZoneProperty(theZone, "stopFlag?", "none") theZone.triggerStopFlag = theZone:getStringFromZoneProperty( "stopFlag?", "none")
theZone.lastTriggerStopValue = cfxZones.getFlagValue(theZone.triggerStopFlag, theZone) -- save last value theZone.lastTriggerStopValue = theZone:getFlagValue(theZone.triggerStopFlag) -- save last value
end end
theZone.scheduleID = nil theZone.scheduleID = nil
@ -80,6 +90,12 @@ function raiseFlag.triggered(args)
if theZone.raiseStopped then return end if theZone.raiseStopped then return end
-- if we get here, we aren't stopped and do the flag pull -- if we get here, we aren't stopped and do the flag pull
local command = theZone.flagValue local command = theZone.flagValue
theZone:pollFlag(theZone.raiseFlag, command)
if raiseFlag.verbose or theZone.verbose then
trigger.action.outText("+++rFlg - raising <" .. theZone.raiseFlag .. "> with method '" .. command .. "'" ,30)
end
--[[--
command = dcsCommon.trim(command) command = dcsCommon.trim(command)
if command == "inc" or command == "dec" or command == "flip" then if command == "inc" or command == "dec" or command == "flip" then
cfxZones.pollFlag(theZone.raiseFlag, command, theZone) cfxZones.pollFlag(theZone.raiseFlag, command, theZone)
@ -92,6 +108,7 @@ function raiseFlag.triggered(args)
trigger.action.outText("+++rFlg - raising <" .. theZone.raiseFlag .. "> to value: " .. theZone.flagValue ,30) trigger.action.outText("+++rFlg - raising <" .. theZone.raiseFlag .. "> to value: " .. theZone.flagValue ,30)
end end
end end
--]]--
end end
-- --
@ -103,20 +120,10 @@ function raiseFlag.update()
for idx, aZone in pairs(raiseFlag.flags) do for idx, aZone in pairs(raiseFlag.flags) do
-- make sure to re-start before reading time limit -- make sure to re-start before reading time limit
if cfxZones.testZoneFlag(aZone, aZone.triggerStopFlag, aZone.raiseTriggerMethod, "lastTriggerStopValue") then if aZone:testZoneFlag(aZone.triggerStopFlag, aZone.raiseTriggerMethod, "lastTriggerStopValue") then
theZone.raiseStopped = true -- we are done, no flag! theZone.raiseStopped = true -- we are done, no flag!
end end
-- old code
--[[--
if aZone.triggerStopFlag then
local currTriggerVal = cfxZones.getFlagValue(aZone.triggerStopFlag, theZone)
if currTriggerVal ~= aZone.lastTriggerStopValue
then
theZone.raiseStopped = true -- we are done, no flag!
end
end
--]]--
end end
end end
@ -127,13 +134,10 @@ end
function raiseFlag.readConfigZone() function raiseFlag.readConfigZone()
local theZone = cfxZones.getZoneByName("raiseFlagConfig") local theZone = cfxZones.getZoneByName("raiseFlagConfig")
if not theZone then if not theZone then
if raiseFlag.verbose then theZone = cfxZones.createSimpleZone("raiseFlagConfig")
trigger.action.outText("+++rFlg: NO config zone!", 30)
end
return
end end
raiseFlag.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false) raiseFlag.verbose = theZone.verbose
if raiseFlag.verbose then if raiseFlag.verbose then
trigger.action.outText("+++rFlg: read config", 30) trigger.action.outText("+++rFlg: read config", 30)
@ -178,6 +182,3 @@ if not raiseFlag.start() then
trigger.action.outText("cfx Raise Flag aborted: missing libraries", 30) trigger.action.outText("cfx Raise Flag aborted: missing libraries", 30)
raiseFlag = nil raiseFlag = nil
end end
-- add rnd(a,b) support to value
-- better: if value is a range, make it a random. problem: negative values are legal, so we need formula

View File

@ -1,5 +1,5 @@
stopGap = {} stopGap = {}
stopGap.version = "1.0.8" stopGap.version = "1.0.9"
stopGap.verbose = false stopGap.verbose = false
stopGap.ssbEnabled = true stopGap.ssbEnabled = true
stopGap.ignoreMe = "-sg" stopGap.ignoreMe = "-sg"

Binary file not shown.