mirror of
https://github.com/weyne85/DML.git
synced 2025-10-29 16:57:49 +00:00
Initial commit
This commit is contained in:
606
modules/cfxReconMode.lua
Normal file
606
modules/cfxReconMode.lua
Normal file
@@ -0,0 +1,606 @@
|
||||
cfxReconMode = {}
|
||||
cfxReconMode.version = "1.4.1"
|
||||
cfxReconMode.verbose = false -- set to true for debug info
|
||||
cfxReconMode.reconSound = "UI_SCI-FI_Tone_Bright_Dry_20_stereo.wav" -- to be played when somethiong discovered
|
||||
|
||||
cfxReconMode.prioList = {} -- group names that are high prio and generate special event
|
||||
cfxReconMode.blackList = {} -- group names that are NEVER detected. Comma separated strings, e.g. {"Always Hidden", "Invisible Group"}
|
||||
|
||||
cfxReconMode.requiredLibs = {
|
||||
"dcsCommon", -- always
|
||||
"cfxZones", -- Zones, of course
|
||||
}
|
||||
|
||||
--[[--
|
||||
VERSION HISTORY
|
||||
1.0.0 - initial version
|
||||
1.0.1 - removeScoutByName()
|
||||
1.0.2 - garbage collection
|
||||
1.1.0 - autoRecon - any aircraft taking off immediately
|
||||
signs up, no message when signing up or closing down
|
||||
standalone - copied common procs lerp, agl, dist, distflat
|
||||
from dcsCommon
|
||||
report numbers
|
||||
verbose flag
|
||||
1.2.0 - queued recons. One scout per second for more even
|
||||
performance
|
||||
removed gc since it's now integrated into
|
||||
update queue
|
||||
removeScout optimization when directly passing name
|
||||
playerOnlyRecon for autoRecon
|
||||
red, blue, grey side filtering on auto scout
|
||||
1.2.1 - parametrized report sound
|
||||
1.3.0 - added black list, prio list functionality
|
||||
1.3.1 - callbacks now also push name, as group can be dead
|
||||
- removed bug when removing dead groups from map
|
||||
1.4.0 - import dcsCommon, cfxZones etc
|
||||
- added lib check
|
||||
- config zone
|
||||
- prio+
|
||||
- detect+
|
||||
1.4.1 - invocation no longer happen twice for prio.
|
||||
- recon sound
|
||||
- read all flight groups at start to get rid of the
|
||||
- late activation work-around
|
||||
|
||||
|
||||
cfxReconMode is a script that allows units to perform reconnaissance
|
||||
missions and, after detecting units, marks them on the map with
|
||||
markers for their coalition and some text
|
||||
Also, a callback is initiated for scouts as follows
|
||||
signature: (reason, theSide, theSout, theGroup) with
|
||||
reason a string
|
||||
'detected' a group was detected
|
||||
'removed' a mark for a group timed out
|
||||
'priority' a member of prio group was detected
|
||||
'start' a scout started scouting
|
||||
'end' a scout stopped scouting
|
||||
'dead' a scout has died and was removed from pool
|
||||
theSide - side of the SCOUT that detected units
|
||||
theScout - the scout that detected the group
|
||||
theGroup - the group that is detected
|
||||
theName - the group's name
|
||||
--]]--
|
||||
|
||||
cfxReconMode.detectionMinRange = 3000 -- meters at ground level
|
||||
cfxReconMode.detectionMaxRange = 12000 -- meters at max alt (10'000m)
|
||||
cfxReconMode.maxAlt = 9000 -- alt for maxrange (9km = 27k feet)
|
||||
|
||||
cfxReconMode.autoRecon = true -- add all airborne units, unless
|
||||
cfxReconMode.redScouts = false -- set to false to prevent red scouts in auto mode
|
||||
cfxReconMode.blueScouts = true -- set to false to prevent blue scouts in auto-mode
|
||||
cfxReconMode.greyScouts = false -- set to false to prevent neutral scouts in auto mode
|
||||
cfxReconMode.playerOnlyRecon = false -- only players can do recon
|
||||
cfxReconMode.reportNumbers = true -- also add unit count in report
|
||||
cfxReconMode.prioFlag = nil
|
||||
cfxReconMode.detectFlag = nil
|
||||
cfxReconMode.applyMarks = true
|
||||
|
||||
cfxReconMode.ups = 1 -- updates per second.
|
||||
cfxReconMode.scouts = {} -- units that are performing scouting.
|
||||
cfxReconMode.processedScouts = {} -- for managing performance: queue
|
||||
cfxReconMode.detectedGroups = {} -- so we know which have been detected
|
||||
cfxReconMode.marksFadeAfter = 30*60 -- after detection, marks disappear after
|
||||
-- this amount of seconds. -1 means no fade
|
||||
-- 60 is one minute
|
||||
|
||||
cfxReconMode.callbacks = {} -- sig: cb(reason, side, scout, group)
|
||||
cfxReconMode.uuidCount = 0 -- for unique marks
|
||||
|
||||
|
||||
-- end standalone dcsCommon extract
|
||||
|
||||
function cfxReconMode.uuid()
|
||||
cfxReconMode.uuidCount = cfxReconMode.uuidCount + 1
|
||||
return cfxReconMode.uuidCount
|
||||
end
|
||||
|
||||
function cfxReconMode.addCallback(theCB)
|
||||
table.insert(cfxReconMode.callbacks, theCB)
|
||||
end
|
||||
|
||||
function cfxReconMode.invokeCallbacks(reason, theSide, theScout, theGroup, theName)
|
||||
for idx, theCB in pairs(cfxReconMode.callbacks) do
|
||||
theCB(reason, theSide, theScout, theGroup, theName)
|
||||
end
|
||||
end
|
||||
|
||||
-- add a priority/blackList group name to prio list
|
||||
function cfxReconMode.addToPrioList(aGroup)
|
||||
if not aGroup then return end
|
||||
if type(aGroup) == "table" and aGroup.getName then
|
||||
aGroup = aGroup:getName()
|
||||
end
|
||||
if type(aGroup) == "string" then
|
||||
table.insert(cfxReconMode.prioList, aGroup)
|
||||
end
|
||||
end
|
||||
|
||||
function cfxReconMode.addToBlackList(aGroup)
|
||||
if not aGroup then return end
|
||||
if type(aGroup) == "table" and aGroup.getName then
|
||||
aGroup = aGroup:getName()
|
||||
end
|
||||
if type(aGroup) == "string" then
|
||||
table.insert(cfxReconMode.blackList, aGroup)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function cfxReconMode.isStringInList(theString, theList)
|
||||
if not theString then return false end
|
||||
if not theList then return false end
|
||||
if type(theString) == "string" then
|
||||
for idx,anItem in pairs(theList) do
|
||||
if anItem == theString then return true end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- addScout directly adds a scout unit. Use from external
|
||||
-- to manually add a unit (e.g. via GUI when autoscout isExist
|
||||
-- off, or to force a scout unit (e.g. when scouts for a side
|
||||
-- are not allowed but you still want a unit from that side
|
||||
-- to scout
|
||||
-- since we use a queue for scouts, also always check the
|
||||
-- processed queue before adding to make sure a scout isn't
|
||||
-- entered multiple times
|
||||
|
||||
function cfxReconMode.addScout(theUnit)
|
||||
if not theUnit then
|
||||
trigger.action.outText("+++cfxRecon: WARNING - nil Unit on add", 30)
|
||||
return
|
||||
end
|
||||
|
||||
if type(theUnit) == "string" then
|
||||
local u = Unit.getByName(theUnit)
|
||||
theUnit = u
|
||||
end
|
||||
|
||||
if not theUnit then
|
||||
trigger.action.outText("+++cfxRecon: WARNING - did not find unit on add", 30)
|
||||
return
|
||||
end
|
||||
if not theUnit:isExist() then return end
|
||||
-- find out if this an update or a new scout
|
||||
local thisID = tonumber(theUnit:getID())
|
||||
local theName = theUnit:getName()
|
||||
local lastUnit = cfxReconMode.scouts[theName]
|
||||
local isProcced = false -- may also be in procced line
|
||||
if not lastUnit then
|
||||
lastUnit = cfxReconMode.processedScouts[theName]
|
||||
if lastUnit then isProcced = true end
|
||||
end
|
||||
|
||||
if lastUnit then
|
||||
-- this is merely an overwrite
|
||||
if cfxReconMode.verbose then trigger.action.outText("+++rcn: UPDATE scout " .. theName .. " -- no CB invoke", 30) end
|
||||
else
|
||||
if cfxReconMode.verbose then trigger.action.outText("+++rcn: new scout " .. theName .. " with ID " .. thisID, 30) end
|
||||
-- a new scout! Invoke callbacks
|
||||
local scoutGroup = theUnit:getGroup()
|
||||
local theSide = scoutGroup:getCoalition()
|
||||
cfxReconMode.invokeCallbacks("start", theSide, theUnit, nil, "<none>")
|
||||
end
|
||||
|
||||
if isProcced then
|
||||
-- overwrite exiting entry in procced queue
|
||||
cfxReconMode.processedScouts[theName] = theUnit
|
||||
else
|
||||
-- add / overwrite into normal queue
|
||||
cfxReconMode.scouts[theName] = theUnit
|
||||
end
|
||||
|
||||
if cfxReconMode.verbose then
|
||||
trigger.action.outText("+++rcn: addded scout " .. theUnit:getName(), 30)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function cfxReconMode.removeScout(theUnit)
|
||||
if not theUnit then
|
||||
trigger.action.outText("+++cfxRecon: WARNING - nil Unit on remove", 30)
|
||||
return
|
||||
end
|
||||
|
||||
if type(theUnit) == "string" then
|
||||
cfxReconMode.removeScoutByName(theUnit)
|
||||
return
|
||||
end
|
||||
|
||||
if not theUnit then return end
|
||||
if not theUnit:isExist() then return end
|
||||
cfxReconMode.removeScoutByName(theUnit:getName())
|
||||
local scoutGroup = theUnit:getGroup()
|
||||
local theSide = scoutGroup:getCoalition()
|
||||
cfxReconMode.invokeCallbacks("end", theSide, theUnit, nil, "<none>")
|
||||
end
|
||||
|
||||
-- warning: removeScoutByName does NOT invoke callbacks, always
|
||||
-- use removeScout instead!
|
||||
function cfxReconMode.removeScoutByName(aName)
|
||||
cfxReconMode.scouts[aName] = nil
|
||||
cfxReconMode.processedScouts[aName] = nil -- also remove from processed stack
|
||||
if cfxReconMode.verbose then
|
||||
trigger.action.outText("+++rcn: removed scout " .. aName, 30)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function cfxReconMode.canDetect(scoutPos, theGroup, visRange)
|
||||
-- determine if a member of theGroup can be seen from
|
||||
-- scoutPos at visRange
|
||||
-- returns true and pos when detected
|
||||
local allUnits = theGroup:getUnits()
|
||||
for idx, aUnit in pairs(allUnits) do
|
||||
if aUnit:isExist() and aUnit:getLife() >= 1 then
|
||||
local uPos = aUnit:getPoint()
|
||||
uPos.y = uPos.y + 3 -- raise my 3 meters
|
||||
local d = dcsCommon.distFlat(scoutPos, uPos)
|
||||
if d < visRange then
|
||||
-- is in visual range. do we have LOS?
|
||||
if land.isVisible(scoutPos, uPos) then
|
||||
-- group is visible, stop here, return true
|
||||
return true, uPos
|
||||
end
|
||||
else
|
||||
-- OPTIMIZATION: if a unit is outside
|
||||
-- detect range, we assume that entire group
|
||||
-- is, since they are bunched together
|
||||
-- edge cases may get lucky tests
|
||||
return false, nil
|
||||
end
|
||||
end
|
||||
end
|
||||
return false, nil -- nothing visible
|
||||
end
|
||||
|
||||
function cfxReconMode.placeMarkForUnit(location, theSide, theGroup)
|
||||
local theID = cfxReconMode.uuid()
|
||||
local theDesc = "Contact: "..theGroup:getName()
|
||||
if cfxReconMode.reportNumbers then
|
||||
theDesc = theDesc .. " (" .. theGroup:getSize() .. " units)"
|
||||
end
|
||||
trigger.action.markToCoalition(
|
||||
theID,
|
||||
theDesc,
|
||||
location,
|
||||
theSide,
|
||||
false,
|
||||
nil)
|
||||
return theID
|
||||
end
|
||||
|
||||
function cfxReconMode.removeMarkForArgs(args)
|
||||
local theSide = args[1]
|
||||
local theScout = args[2]
|
||||
local theGroup = args[3]
|
||||
local theID = args[4]
|
||||
local theName = args[5]
|
||||
|
||||
-- if not theGroup then return end
|
||||
-- if not theGroup:isExist then return end
|
||||
|
||||
trigger.action.removeMark(theID)
|
||||
cfxReconMode.detectedGroups[theName] = nil
|
||||
|
||||
-- invoke callbacks
|
||||
cfxReconMode.invokeCallbacks("removed", theSide, theScout, theGroup, theName)
|
||||
end
|
||||
|
||||
|
||||
function cfxReconMode.detectedGroup(mySide, theScout, theGroup, theLoc)
|
||||
-- put a mark on the map
|
||||
if cfxReconMode.applyMarks then
|
||||
local theID = cfxReconMode.placeMarkForUnit(theLoc, mySide, theGroup)
|
||||
|
||||
-- schedule removal if desired
|
||||
if cfxReconMode.marksFadeAfter > 0 then
|
||||
args = {mySide, theScout, theGroup, theID, theGroup:getName()}
|
||||
timer.scheduleFunction(cfxReconMode.removeMarkForArgs, args, timer.getTime() + cfxReconMode.marksFadeAfter)
|
||||
end
|
||||
end
|
||||
-- say something
|
||||
if cfxReconMode.announcer then
|
||||
trigger.action.outTextForCoalition(mySide, theScout:getName() .. " reports new ground contact " .. theGroup:getName(), 30)
|
||||
-- play a sound
|
||||
trigger.action.outSoundForCoalition(mySide, cfxReconMode.reconSound)
|
||||
end
|
||||
|
||||
-- see if it was a prio target
|
||||
if cfxReconMode.isStringInList(theGroup:getName(), cfxReconMode.prioList) then
|
||||
if cfxReconMode.announcer then
|
||||
trigger.action.outTextForCoalition(mySide, "Priority target confirmed", 30)
|
||||
end
|
||||
-- invoke callbacks
|
||||
cfxReconMode.invokeCallbacks("priotity", mySide, theScout, theGroup, theGroup:getName())
|
||||
|
||||
-- increase prio flag
|
||||
if cfxReconMode.prioFlag then
|
||||
local currVal = trigger.misc.getUserFlag(cfxReconMode.prioFlag)
|
||||
trigger.action.setUserFlag(cfxReconMode.prioFlag, currVal + 1)
|
||||
end
|
||||
else
|
||||
-- invoke callbacks
|
||||
cfxReconMode.invokeCallbacks("detected", mySide, theScout, theGroup, theGroup:getName())
|
||||
|
||||
-- increase normal flag
|
||||
if cfxReconMode.detectFlag then
|
||||
local currVal = trigger.misc.getUserFlag(cfxReconMode.detectFlag)
|
||||
trigger.action.setUserFlag(cfxReconMode.detectFlag, currVal + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cfxReconMode.performReconForUnit(theScout)
|
||||
if not theScout then return end
|
||||
if not theScout:isExist() then return end -- will be gc'd soon
|
||||
-- get altitude above ground to calculate visual range
|
||||
local alt = dcsCommon.getUnitAGL(theScout)
|
||||
local visRange = dcsCommon.lerp(cfxReconMode.detectionMinRange, cfxReconMode.detectionMaxRange, alt/cfxReconMode.maxAlt)
|
||||
local scoutPos = theScout:getPoint()
|
||||
-- figure out which groups we are looking for
|
||||
local myCoal = theScout:getCoalition()
|
||||
local enemyCoal = 1
|
||||
if myCoal == 1 then enemyCoal = 2 end
|
||||
|
||||
-- iterate all enemy units until we find one
|
||||
-- and then stop this iteration (can only detect one
|
||||
-- group per pass)
|
||||
local enemyGroups = coalition.getGroups(enemyCoal)
|
||||
for idx, theGroup in pairs (enemyGroups) do
|
||||
-- make sure it's a ground unit
|
||||
local isGround = theGroup:getCategory() == 2
|
||||
if theGroup:isExist() and isGround then
|
||||
local visible, location = cfxReconMode.canDetect(scoutPos, theGroup, visRange)
|
||||
if visible then
|
||||
-- see if we already detected this one
|
||||
local groupName = theGroup:getName()
|
||||
if cfxReconMode.detectedGroups[groupName] == nil then
|
||||
-- only now check against blackList
|
||||
if not cfxReconMode.isStringInList(groupName, cfxReconMode.blackList) then
|
||||
-- visible and not yet seen
|
||||
-- perhaps add some percent chance now
|
||||
-- remember that we know this group
|
||||
cfxReconMode.detectedGroups[groupName] = theGroup
|
||||
cfxReconMode.detectedGroup(myCoal, theScout, theGroup, location)
|
||||
return -- stop, as we only detect one group per pass
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function cfxReconMode.updateQueues()
|
||||
-- schedule next call
|
||||
timer.scheduleFunction(cfxReconMode.updateQueues, {}, timer.getTime() + 1/cfxReconMode.ups)
|
||||
|
||||
-- we only process the first aircraft in
|
||||
-- the scouts array, move it to processed and then shrink
|
||||
-- scouts table until it's empty. When empty, transfer all
|
||||
-- back and start cycle anew
|
||||
|
||||
local theFocusScoutName = nil
|
||||
local procCount = 0 -- no iterations done yet
|
||||
for name, scout in pairs(cfxReconMode.scouts) do
|
||||
theFocusScoutName = name -- remember so we can delete
|
||||
if not scout:isExist() then
|
||||
-- we ignore the scout, and it's
|
||||
-- forgotten since no longer transferred
|
||||
-- i.e. built-in GC
|
||||
if cfxReconMode.verbose then
|
||||
trigger.action.outText("+++rcn: GC - removing scout " .. name .. " because it no longer exists", 30)
|
||||
end
|
||||
-- invoke 'end' for this scout
|
||||
cfxReconMode.invokeCallbacks("dead", -1, nil, nil, name)
|
||||
else
|
||||
-- scan for this scout
|
||||
cfxReconMode.performReconForUnit(scout)
|
||||
-- move it to processed table
|
||||
cfxReconMode.processedScouts[name] = scout
|
||||
end
|
||||
procCount = 1 -- remember we went through one iteration
|
||||
break -- always end after first iteration
|
||||
end
|
||||
|
||||
-- remove processed scouts from scouts array
|
||||
if procCount > 0 then
|
||||
-- we processed one scout (even if scout itself did not exist)
|
||||
-- remove that scout from active scouts table
|
||||
cfxReconMode.scouts[theFocusScoutName] = nil
|
||||
else
|
||||
-- scouts is empty. copy processed table back to scouts
|
||||
-- restart scouts array, contains GC already
|
||||
cfxReconMode.scouts = cfxReconMode.processedScouts
|
||||
cfxReconMode.processedScouts = {} -- start new empty processed queue
|
||||
end
|
||||
end
|
||||
|
||||
-- event handler
|
||||
function cfxReconMode:onEvent(event)
|
||||
if not event then return end
|
||||
if not event.initiator then return end
|
||||
local theUnit = event.initiator
|
||||
|
||||
-- we simply add scouts as they are garbage-collected
|
||||
-- every so often when they do not exist
|
||||
if event.id == 15 or -- birth
|
||||
event.id == 3 -- take-off. should already have been taken
|
||||
-- care of by birth, but you never know
|
||||
then
|
||||
-- check if a side must not have scouts.
|
||||
-- this will prevent player units to auto-
|
||||
-- scout when they are on that side. in that case
|
||||
-- you must add manually
|
||||
local theSide = theUnit:getCoalition()
|
||||
if theSide == 0 and not cfxReconMode.greyScouts then
|
||||
return -- grey scouts are not allowed
|
||||
end
|
||||
if theSide == 1 and not cfxReconMode.redScouts then
|
||||
return -- grey scouts are not allowed
|
||||
end
|
||||
if theSide == 2 and not cfxReconMode.blueScouts then
|
||||
return -- grey scouts are not allowed
|
||||
end
|
||||
|
||||
if cfxReconMode.playerOnlyRecon then
|
||||
if not theUnit:getPlayerName() then
|
||||
return -- only players can do recon. this unit is AI
|
||||
end
|
||||
end
|
||||
if cfxReconMode.verbose then
|
||||
trigger.action.outText("+++rcn: event " .. event.id .. " for unit " .. theUnit:getName(), 30)
|
||||
end
|
||||
cfxReconMode.addScout(theUnit)
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- read all existing planes
|
||||
--
|
||||
function cfxReconMode.processScoutGroups(theGroups)
|
||||
for idx, aGroup in pairs(theGroups) do
|
||||
-- process all planes in that group
|
||||
-- we are very early in the mission, only few groups really
|
||||
-- exist now, the rest of the units come in with 15 event
|
||||
if aGroup:isExist() then
|
||||
local allUnits = Group.getUnits(aGroup)
|
||||
for idy, aUnit in pairs (allUnits) do
|
||||
if aUnit:isExist() then
|
||||
cfxReconMode.addScout(aUnit)
|
||||
if cfxReconMode.verbose then
|
||||
trigger.action.outText("+++rcn: added unit " ..aUnit:getName() .. " to pool at startup", 30)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cfxReconMode.initScouts()
|
||||
-- get all groups of aircraft. Unrolled loop 0..2
|
||||
local theAirGroups = {}
|
||||
if cfxReconMode.greyScouts then
|
||||
theAirGroups = coalition.getGroups(0, 0) -- 0 = aircraft
|
||||
cfxReconMode.processScoutGroups(theAirGroups)
|
||||
end
|
||||
if cfxReconMode.redScouts then
|
||||
theAirGroups = coalition.getGroups(1, 0) -- 1 = red, 0 = aircraft
|
||||
cfxReconMode.processScoutGroups(theAirGroups)
|
||||
end
|
||||
|
||||
if cfxReconMode.blueScouts then
|
||||
theAirGroups = coalition.getGroups(2, 0) -- 2 = blue, 0 = aircraft
|
||||
cfxReconMode.processScoutGroups(theAirGroups)
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- read config
|
||||
--
|
||||
function cfxReconMode.readConfigZone()
|
||||
-- note: must match exactly!!!!
|
||||
local theZone = cfxZones.getZoneByName("reconModeConfig")
|
||||
if not theZone then
|
||||
if cfxReconMode.verbose then
|
||||
trigger.action.outText("+++rcn: no config zone!", 30)
|
||||
end
|
||||
return
|
||||
end
|
||||
if cfxReconMode.verbose then
|
||||
trigger.action.outText("+++rcn: found config zone!", 30)
|
||||
end
|
||||
|
||||
cfxReconMode.verbose = cfxZones.getBoolFromZoneProperty(theZone, "verbose", false)
|
||||
|
||||
cfxReconMode.autoRecon = cfxZones.getBoolFromZoneProperty(theZone, "autoRecon", true)
|
||||
cfxReconMode.redScouts = cfxZones.getBoolFromZoneProperty(theZone, "redScouts", false)
|
||||
cfxReconMode.blueScouts = cfxZones.getBoolFromZoneProperty(theZone, "blueScouts", true)
|
||||
cfxReconMode.greyScouts = cfxZones.getBoolFromZoneProperty(theZone, "greyScouts", false)
|
||||
cfxReconMode.playerOnlyRecon = cfxZones.getBoolFromZoneProperty(theZone, "playerOnlyRecon", false)
|
||||
cfxReconMode.reportNumbers = cfxZones.getBoolFromZoneProperty(theZone, "reportNumbers", true)
|
||||
|
||||
cfxReconMode.detectionMinRange = cfxZones.getNumberFromZoneProperty(theZone, "detectionMinRange", 3000)
|
||||
cfxReconMode.detectionMaxRange = cfxZones.getNumberFromZoneProperty(theZone, "detectionMaxRange", 12000)
|
||||
cfxReconMode.maxAlt = cfxZones.getNumberFromZoneProperty(theZone, "maxAlt", 9000)
|
||||
|
||||
if cfxZones.hasProperty(theZone, "prio+") then
|
||||
cfxReconMode.prioFlag = cfxZones.getStringFromZoneProperty(theZone, "prio+", "none")
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(theZone, "detect+") then
|
||||
cfxReconMode.detectFlag = cfxZones.getStringFromZoneProperty(theZone, "detect+", "none")
|
||||
end
|
||||
|
||||
|
||||
cfxReconMode.applyMarks = cfxZones.getBoolFromZoneProperty(theZone, "applyMarks", true)
|
||||
cfxReconMode.announcer = cfxZones.getBoolFromZoneProperty(theZone, "announcer", true)
|
||||
|
||||
if cfxZones.hasProperty(theZone, "reconSound") then
|
||||
cfxReconMode.reconSound = cfxZones.getStringFromZoneProperty(theZone, "reconSound", "<nosound>")
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- start
|
||||
--
|
||||
function cfxReconMode.start()
|
||||
-- lib check
|
||||
if not dcsCommon.libCheck("cfx Recon Mode",
|
||||
cfxReconMode.requiredLibs) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- read config
|
||||
cfxReconMode.readConfigZone()
|
||||
|
||||
-- gather exiting planes
|
||||
cfxReconMode.initScouts()
|
||||
|
||||
-- start update cycle
|
||||
cfxReconMode.updateQueues()
|
||||
|
||||
if cfxReconMode.autoRecon then
|
||||
-- install own event handler to detect
|
||||
-- when a unit takes off and add it to scout
|
||||
-- roster
|
||||
world.addEventHandler(cfxReconMode)
|
||||
end
|
||||
|
||||
trigger.action.outText("cfx Recon version " .. cfxReconMode.version .. " started.", 30)
|
||||
return true
|
||||
end
|
||||
|
||||
--
|
||||
-- test callback
|
||||
--
|
||||
function cfxReconMode.demoReconCB(reason, theSide, theScout, theGroup, theName)
|
||||
trigger.action.outText("recon CB: " .. reason .. " -- " .. theScout:getName() .. " spotted " .. theName, 30)
|
||||
end
|
||||
|
||||
if not cfxReconMode.start() then
|
||||
cfxReconMode = nil
|
||||
end
|
||||
|
||||
-- debug: wire up my own callback
|
||||
-- cfxReconMode.addCallback(cfxReconMode.demoReconCB)
|
||||
|
||||
|
||||
--[[--
|
||||
|
||||
ideas:
|
||||
|
||||
- renew lease. when already sighted, simply renew lease, maybe update location.
|
||||
- update marks and renew lease
|
||||
TODO: red+ and blue+ - flags to increase when a plane of the other side is detected
|
||||
|
||||
|
||||
--]]--
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user