From c4c8e15a3265e9a41fdd02779b698273f51b9205 Mon Sep 17 00:00:00 2001 From: David Pierron Date: Fri, 25 Aug 2023 17:26:30 +0200 Subject: [PATCH 1/2] Changed the beacons radio transmissions There is no more a need to restart transmissions every 30 seconds, as the bug has been corrected (see https://forum.dcs.world/topic/276106-arc-frequencies/page/2/). Instead, I made changes to create the transmissions once, with a unique name (now mandatory, see https://forum.dcs.world/topic/316378-placed-adf-beacons-only-transmit-briefly/) and the "loop" parameter activated. Then, every minute, the updateRadioBeacon function checks if the beacons' batteries are still up, and stops them if they are not. If all is ok, the transmissions are stopped and immediately restarted. --- CTLD.lua | 115 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 49 deletions(-) diff --git a/CTLD.lua b/CTLD.lua index 567a1f8..30fc256 100644 --- a/CTLD.lua +++ b/CTLD.lua @@ -26,7 +26,7 @@ ctld = {} -- DONT REMOVE! ctld.Id = "CTLD - " --- Version. -ctld.Version = "20230414.01" +ctld.Version = "20230825.01" -- debug level, specific to this module ctld.Debug = true @@ -2764,10 +2764,12 @@ function ctld.loadNearbyCrate(_name) end ---recreates beacons to make sure they work! +--check each minute if the beacons' batteries have failed, and stop them accordingly +--there's no more need to actually refresh the beacons, since we set "loop" to true. function ctld.refreshRadioBeacons() + ctld.logDebug("ctld.refreshRadioBeacons()") - timer.scheduleFunction(ctld.refreshRadioBeacons, nil, timer.getTime() + 30) + timer.scheduleFunction(ctld.refreshRadioBeacons, nil, timer.getTime() + 60) for _index, _beaconDetails in ipairs(ctld.deployedRadioBeacons) do @@ -3390,10 +3392,11 @@ end -- one for VHF and one for UHF -- The units are set to to NOT engage function ctld.createRadioBeacon(_point, _coalition, _country, _name, _batteryTime, _isFOB) + ctld.logDebug(string.format("ctld.createRadioBeacon(_name=%s)", ctld.p(_name))) - local _uhfGroup = ctld.spawnRadioBeaconUnit(_point, _country, "UHF") - local _vhfGroup = ctld.spawnRadioBeaconUnit(_point, _country, "VHF") - local _fmGroup = ctld.spawnRadioBeaconUnit(_point, _country, "FM") + local _uhfGroup = ctld.spawnRadioBeaconUnit(_point, _country, _name .. "-UHF") + local _vhfGroup = ctld.spawnRadioBeaconUnit(_point, _country, _name .. "-VHF") + local _fmGroup = ctld.spawnRadioBeaconUnit(_point, _country, _name .. "-FM") local _freq = ctld.generateADFFrequencies() @@ -3443,6 +3446,8 @@ function ctld.createRadioBeacon(_point, _coalition, _country, _name, _batteryTim battery = _battery, coalition = _coalition, } + + ctld.logDebug(string.format("calling ctld.updateRadioBeacon for beacon %s", ctld.p(_name))) ctld.updateRadioBeacon(_beaconDetails) table.insert(ctld.deployedRadioBeacons, _beaconDetails) @@ -3484,7 +3489,8 @@ end -function ctld.spawnRadioBeaconUnit(_point, _country, _type) +function ctld.spawnRadioBeaconUnit(_point, _country, _name) + ctld.logDebug(string.format("ctld.spawnRadioBeaconUnit(_name=%s)", ctld.p(_name))) local _groupId = ctld.getNextGroupId() @@ -3498,7 +3504,7 @@ function ctld.spawnRadioBeaconUnit(_point, _country, _type) [1] = { ["y"] = _point.z, ["type"] = "TACAN_beacon", - ["name"] = _type .. " Radio Beacon Unit #" .. _unitId, + ["name"] = _name .. " - Unit #" .. _unitId, -- ["unitId"] = _unitId, ["heading"] = 0, ["playerCanDrive"] = true, @@ -3508,7 +3514,7 @@ function ctld.spawnRadioBeaconUnit(_point, _country, _type) }, -- ["y"] = _positions[1].z, -- ["x"] = _positions[1].x, - ["name"] = _type .. " Radio Beacon Group #" .. _groupId, + ["name"] = _name .. " - Group #" .. _groupId, ["task"] = {}, --added two fields below for MIST ["category"] = Group.Category.GROUND, @@ -3520,6 +3526,8 @@ function ctld.spawnRadioBeaconUnit(_point, _country, _type) end function ctld.updateRadioBeacon(_beaconDetails) + ctld.logDebug("ctld.updateRadioBeacon()") + ctld.logTrace(string.format("_beaconDetails=%s", ctld.p(_beaconDetails))) local _vhfGroup = Group.getByName(_beaconDetails.vhfGroup) @@ -3530,14 +3538,17 @@ function ctld.updateRadioBeacon(_beaconDetails) local _radioLoop = {} if _vhfGroup ~= nil and _vhfGroup:getUnits() ~= nil and #_vhfGroup:getUnits() == 1 then + ctld.logTrace(string.format("_vhfGroup=%s", ctld.p(_vhfGroup))) table.insert(_radioLoop, { group = _vhfGroup, freq = _beaconDetails.vhf, silent = false, mode = 0 }) end if _uhfGroup ~= nil and _uhfGroup:getUnits() ~= nil and #_uhfGroup:getUnits() == 1 then + ctld.logTrace(string.format("_uhfGroup=%s", ctld.p(_uhfGroup))) table.insert(_radioLoop, { group = _uhfGroup, freq = _beaconDetails.uhf, silent = true, mode = 0 }) end if _fmGroup ~= nil and _fmGroup:getUnits() ~= nil and #_fmGroup:getUnits() == 1 then + ctld.logTrace(string.format("_fmGroup=%s", ctld.p(_fmGroup))) table.insert(_radioLoop, { group = _fmGroup, freq = _beaconDetails.fm, silent = false, mode = 1 }) end @@ -3545,14 +3556,20 @@ function ctld.updateRadioBeacon(_beaconDetails) if (_batLife <= 0 and _beaconDetails.battery ~= -1) or #_radioLoop ~= 3 then -- ran out of batteries - + ctld.logDebug("ran out of batteries") if _vhfGroup ~= nil then + ctld.logTrace(string.format("stopping transmission of %s", ctld.p(_vhfGroup:getName()))) + trigger.action.stopRadioTransmission(_vhfGroup:getName()) _vhfGroup:destroy() end if _uhfGroup ~= nil then + ctld.logTrace(string.format("stopping transmission of %s", ctld.p(_uhfGroup:getName()))) + trigger.action.stopRadioTransmission(_uhfGroup:getName()) _uhfGroup:destroy() end if _fmGroup ~= nil then + ctld.logTrace(string.format("stopping transmission of %s", ctld.p(_fmGroup:getName()))) + trigger.action.stopRadioTransmission(_fmGroup:getName()) _fmGroup:destroy() end @@ -3577,17 +3594,17 @@ function ctld.updateRadioBeacon(_beaconDetails) _groupController:setOption(AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.WEAPON_HOLD) - trigger.action.radioTransmission(_sound, _radio.group:getUnit(1):getPoint(), _radio.mode, false, _radio.freq, 1000) - --This function doesnt actually stop transmitting when then sound is false. My hope is it will stop if a new beacon is created on the same - -- frequency... OR they fix the bug where it wont stop. - -- end + ctld.logTrace(string.format("stopping and restarting transmission of %s", ctld.p(_radio.group:getName()))) + + -- stop the transmission at each call to the ctld.updateRadioBeacon method (default each minute) + trigger.action.stopRadioTransmission(_radio.group:getName()) - -- + -- restart it as the battery is still up + -- the transmission is set to loop and has the name of the transmitting DCS group (that includes the type - i.e. FM, UHF, VHF) + trigger.action.radioTransmission(_sound, _radio.group:getUnit(1):getPoint(), _radio.mode, true, _radio.freq, 1000, _radio.group:getName()) end return true - - -- trigger.action.radioTransmission(ctld.radioSound, _point, 1, true, _frequency, 1000) end function ctld.listRadioBeacons(_args) @@ -5144,51 +5161,51 @@ function ctld.addJTACRadioCommand(_side) --make a copy of the JTAC group submenu's path to insert the target's list on as many pages as required. The JTAC's group submenu path only leads to the first page local jtacTargetPagePath = mist.utils.deepCopy(ctld.jtacGroupSubMenuPath[_jtacGroupName]) - --add a reset targeting option to revert to automatic JTAC unit targeting - missionCommands.addCommandForGroup(_groupId, "Reset TGT Selection", jtacTargetPagePath, ctld.setJTACTarget, {jtacGroupName = _jtacGroupName, targetName = nil}) - - --counter to know when to add the next page submenu to fit all of the targets in the JTAC's group submenu + --add a reset targeting option to revert to automatic JTAC unit targeting + missionCommands.addCommandForGroup(_groupId, "Reset TGT Selection", jtacTargetPagePath, ctld.setJTACTarget, {jtacGroupName = _jtacGroupName, targetName = nil}) + + --counter to know when to add the next page submenu to fit all of the targets in the JTAC's group submenu local itemCounter = 0 - --indicator table to know which unitType was already added to the radio submenu - local typeNameList = {} - for _,target in pairs(ctld.jtacTargetsList[_jtacGroupName]) do - local targetName = target.unit:getName() - --check if the jtac has a current target before filtering it out if possible - if (ctld.jtacCurrentTargets[_jtacGroupName] and targetName ~= ctld.jtacCurrentTargets[_jtacGroupName].name) then - local targetType_name = target.unit:getTypeName() + --indicator table to know which unitType was already added to the radio submenu + local typeNameList = {} + for _,target in pairs(ctld.jtacTargetsList[_jtacGroupName]) do + local targetName = target.unit:getName() + --check if the jtac has a current target before filtering it out if possible + if (ctld.jtacCurrentTargets[_jtacGroupName] and targetName ~= ctld.jtacCurrentTargets[_jtacGroupName].name) then + local targetType_name = target.unit:getTypeName() - if targetType_name then - if typeNameList[targetType_name] then - typeNameList[targetType_name].amount = typeNameList[targetType_name].amount + 1 - else - typeNameList[targetType_name] = {} - typeNameList[targetType_name].targetName = targetName --store the first targetName - typeNameList[targetType_name].amount = 1 + if targetType_name then + if typeNameList[targetType_name] then + typeNameList[targetType_name].amount = typeNameList[targetType_name].amount + 1 + else + typeNameList[targetType_name] = {} + typeNameList[targetType_name].targetName = targetName --store the first targetName + typeNameList[targetType_name].amount = 1 + end end end end - end - for typeName,info in pairs(typeNameList) do - local amount = info.amount - local targetName = info.targetName - itemCounter = itemCounter + 1 + for typeName,info in pairs(typeNameList) do + local amount = info.amount + local targetName = info.targetName + itemCounter = itemCounter + 1 - --F2 through F10 makes 9 entries possible per page, with one being the NextMenu submenu. Pages other than the first would have 10 entires but worse case scenario is considered - if itemCounter%9 == 0 then - jtacTargetPagePath = missionCommands.addSubMenuForGroup(_groupId, NextPageText, jtacTargetPagePath) + --F2 through F10 makes 9 entries possible per page, with one being the NextMenu submenu. Pages other than the first would have 10 entires but worse case scenario is considered + if itemCounter%9 == 0 then + jtacTargetPagePath = missionCommands.addSubMenuForGroup(_groupId, NextPageText, jtacTargetPagePath) + end + + missionCommands.addCommandForGroup(_groupId, string.format(typeName .. "(" .. amount .. ")"), jtacTargetPagePath, ctld.setJTACTarget, {jtacGroupName = _jtacGroupName, targetName = targetName}) end - - missionCommands.addCommandForGroup(_groupId, string.format(typeName .. "(" .. amount .. ")"), jtacTargetPagePath, ctld.setJTACTarget, {jtacGroupName = _jtacGroupName, targetName = targetName}) end end end end end end - end - + if ctld.newJtac[_side] then ctld.newJtac[_side] = false end @@ -5326,7 +5343,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour, _ --Targets list and Selected target initialization if not ctld.jtacTargetsList[_jtacGroupName] then - ctld.jtacTargetsList[_jtacGroupName] = {} + ctld.jtacTargetsList[_jtacGroupName] = {} if _jtacCoalition then ctld.newJtac[_jtacCoalition] = true end end @@ -6108,7 +6125,7 @@ function ctld.setJTACTarget(_args) elseif not targetName and ctld.jtacSelectedTarget[_jtacGroupName] ~= 1 then ctld.jtacSelectedTarget[_jtacGroupName] = 1 ctld.jtacCurrentTargets[_jtacGroupName] = nil - + local message = _jtacGroupName .. ", target selection reset." ctld.notifyCoalition(message, 10, ctld.jtacUnits[_jtacGroupName].side, ctld.jtacRadioData[_jtacGroupName]) end From c1891a1a52ecf2d3c3078b5a838a136ae7e1428a Mon Sep 17 00:00:00 2001 From: David Pierron Date: Tue, 29 Aug 2023 17:57:21 +0200 Subject: [PATCH 2/2] stop transmission if ctld.removeRadioBeacon is called --- CTLD.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CTLD.lua b/CTLD.lua index 30fc256..2ddc904 100644 --- a/CTLD.lua +++ b/CTLD.lua @@ -3693,12 +3693,18 @@ function ctld.removeRadioBeacon(_args) local _fmGroup = Group.getByName(_closetBeacon.fmGroup) if _vhfGroup ~= nil then + ctld.logTrace(string.format("stopping transmission of %s", ctld.p(_vhfGroup:getName()))) + trigger.action.stopRadioTransmission(_vhfGroup:getName()) _vhfGroup:destroy() end if _uhfGroup ~= nil then + ctld.logTrace(string.format("stopping transmission of %s", ctld.p(_uhfGroup:getName()))) + trigger.action.stopRadioTransmission(_uhfGroup:getName()) _uhfGroup:destroy() end if _fmGroup ~= nil then + ctld.logTrace(string.format("stopping transmission of %s", ctld.p(_fmGroup:getName()))) + trigger.action.stopRadioTransmission(_fmGroup:getName()) _fmGroup:destroy() end