diff --git a/CTLD-i18n.lua b/CTLD-i18n.lua index 6746544..8a1c8b2 100644 --- a/CTLD-i18n.lua +++ b/CTLD-i18n.lua @@ -256,12 +256,18 @@ ctld.i18n["fr"]["Drop Orange Smoke"] = "Déposer Fumi Orange" ctld.i18n["fr"]["Drop Green Smoke"] = "Déposer Fumi Vert" ctld.i18n["fr"]["Drop Beacon"] = "Déposer Fumi Vert" ctld.i18n["fr"]["Radio Beacons"] = "Déposer Balise" -ctld.i18n["fr"]["Remove Closet Beacon"] = "Supprimer Balise +proche" +ctld.i18n["fr"]["Remove Closest Beacon"] = "Supprimer Balise +proche" ctld.i18n["fr"]["JTAC Status"] = "Statut JTAC" ctld.i18n["fr"]["DISABLE "] = "DESACTIVE " ctld.i18n["fr"]["ENABLE "] = "ACTIVE " ctld.i18n["fr"]["REQUEST "] = "DEMANDE" ctld.i18n["fr"]["Reset TGT Selection"] = "Réinitialiser sélection TGT" +-- F10 RECON menus +ctld.i18n["fr"]["RECON"] = "RECONNAISSANCE" +ctld.i18n["fr"]["Show targets in LOS (refresh)"] = "Marquer cibles visibles sur carte F10" +ctld.i18n["fr"]["Hide targets in LOS"] = "Effacer marques sur carte F10" +ctld.i18n["fr"]["START autoRefresh targets in LOS"] = "Lancer suivi automatique des cibles" +ctld.i18n["fr"]["STOP autoRefresh targets in LOS"] = "Stopper suivi automatique des cibles" --====== SPANISH : ESPAÑOL==================================================================================== ctld.i18n["es"] = {} @@ -519,12 +525,18 @@ ctld.i18n["es"]["Drop Orange Smoke"] = "Soltar humo naranja" ctld.i18n["es"]["Drop Green Smoke"] = "Soltar humo verde" ctld.i18n["es"]["Drop Beacon"] = "Soltar baliza" ctld.i18n["es"]["Radio Beacons"] = "Balizas de radio" -ctld.i18n["es"]["Remove Closet Beacon"] = "Quitar baliza cercana" +ctld.i18n["es"]["Remove Closest Beacon"] = "Quitar baliza cercana" ctld.i18n["es"]["JTAC Status"] = "Estado de JTAC" ctld.i18n["es"]["DISABLE "] = "DESHABILITAR " ctld.i18n["es"]["ENABLE "] = "HABILITAR " ctld.i18n["es"]["REQUEST "] = "SOLICITUD " ctld.i18n["es"]["Reset TGT Selection"] = "Restablecer selección TGT" +-- F10 RECON menus +ctld.i18n["es"]["RECON"] = "RECONOCIMIENTO" +ctld.i18n["es"]["Show targets in LOS (refresh)"] = "Marcar objetivos visibles en el mapa F10" +ctld.i18n["es"]["Hide targets in LOS"] = "Borrar marcas del mapa F10" +ctld.i18n["es"]["START autoRefresh targets in LOS"] = "Iniciar el seguimiento automático de objetivos" +ctld.i18n["es"]["STOP autoRefresh targets in LOS"] = "Detener el seguimiento automático de objetivos" --======================================================================================================================== --======== Korean - 한국어 ===================================================================================== @@ -763,7 +775,7 @@ ctld.i18n["ko"]["Drop Orange Smoke"] = "주황색 연막 투하" ctld.i18n["ko"]["Drop Green Smoke"] = "녹색 연막 투하" ctld.i18n["ko"]["Drop Beacon"] = "비콘 투하" ctld.i18n["ko"]["Radio Beacons"] = "라디오 비콘" -ctld.i18n["ko"]["Remove Closet Beacon"] = "가까운 비콘 제거" +ctld.i18n["ko"]["Remove Closest Beacon"] = "가까운 비콘 제거" ctld.i18n["ko"]["JTAC Status"] = "JTAC 상태" ctld.i18n["ko"]["DISABLE "] = "비활성화 " ctld.i18n["ko"]["ENABLE "] = "활성화 " diff --git a/CTLD.lua b/CTLD.lua index f6e3815..e5c7173 100644 --- a/CTLD.lua +++ b/CTLD.lua @@ -307,12 +307,18 @@ ctld.i18n["en"]["Drop Orange Smoke"] = nil ctld.i18n["en"]["Drop Green Smoke"] = nil ctld.i18n["en"]["Drop Beacon"] = nil ctld.i18n["en"]["Radio Beacons"] = nil -ctld.i18n["en"]["Remove Closet Beacon"] = nil +ctld.i18n["en"]["Remove Closest Beacon"] = nil ctld.i18n["en"]["JTAC Status"] = nil ctld.i18n["en"]["DISABLE "] = nil ctld.i18n["en"]["ENABLE "] = nil ctld.i18n["en"]["REQUEST "] = nil ctld.i18n["en"]["Reset TGT Selection"] = nil +-- F10 RECON menus +ctld.i18n["en"]["RECON"] = nil +ctld.i18n["en"]["Show targets in LOS (refresh)"] = nil +ctld.i18n["en"]["Hide targets in LOS"] = nil +ctld.i18n["en"]["START autoRefresh targets in LOS"] = nil +ctld.i18n["en"]["STOP autoRefresh targets in LOS"] = nil --- Translates a string (text) with parameters (parameters) to the language defined in ctld.i18n_lang ---@param text string The text to translate, with the parameters as %1, %2, etc. (all strings!!!!) @@ -5760,7 +5766,7 @@ function ctld.addTransportF10MenuOptions(_unitName) missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Load Nearby Crate"), _crateCommands, ctld.loadNearbyCrate, _unitName ) end end - + if ctld.loadCrateFromMenu or ctld.hoverPickup then missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Crate"), _crateCommands, ctld.dropSlingCrate, { _unitName }) end @@ -5785,7 +5791,7 @@ function ctld.addTransportF10MenuOptions(_unitName) local _radioCommands = missionCommands.addSubMenuForGroup(_groupId, ctld.i18n_translate("Radio Beacons"), _rootPath) missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("List Beacons"), _radioCommands, ctld.listRadioBeacons, { _unitName }) missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Beacon"), _radioCommands, ctld.dropRadioBeacon, { _unitName }) - missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Remove Closet Beacon"), _radioCommands, ctld.removeRadioBeacon, { _unitName }) + missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Remove Closest Beacon"), _radioCommands, ctld.removeRadioBeacon, { _unitName }) elseif ctld.deployedRadioBeacons ~= {} then local _radioCommands = missionCommands.addSubMenuForGroup(_groupId, ctld.i18n_translate("Radio Beacons"), _rootPath) missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("List Beacons"), _radioCommands, ctld.listRadioBeacons, { _unitName }) @@ -5822,6 +5828,11 @@ function ctld.addOtherF10MenuOptions() ctld.addJTACRadioCommand(2) -- get all BLUE players ctld.addJTACRadioCommand(1) -- get all RED players end + + if ctld.reconF10Menu then + ctld.addReconRadioCommand(2) -- get all BLUE players + ctld.addReconRadioCommand(1) -- get all RED players + end end) if (not status) then @@ -7382,6 +7393,189 @@ function ctld.getPositionString(_unit) return " @ " .. _latLngStr .. " - MGRS " .. _mgrsString .. " - ALTI: " .. mist.utils.round(_TargetAlti, 0) .. " m / " .. mist.utils.round(_TargetAlti/0.3048, 0) .. " ft" end +--********************************************************************** +-- RECOGNITION SUPPORT FUNCTIONS +-- Shows/remove/refresh marks in F10 map on targets in LOS of a unit passed in params +--------------------------------------------------------------------- +-- examples --------------------------------------------------------- +--ctld.reconRefreshTargetsInLosOnF10Map(Unit.getByName("uh2-1"), 2000, 200) +--ctld.reconRemoveTargetsInLosOnF10Map(Unit.getByName("uh2-1")) +--ctld.reconShowTargetsInLosOnF10Map(Unit.getByName("uh2-1"), 2000, 200) +---------------------------------------------------------------------- +--if ctld == nil then ctld = {} end +if ctld.lastMarkId == nil then + ctld.lastMarkId = 0 +end + +-- ***************** RECON CONFIGURATION ***************** +ctld.reconF10Menu = true -- enables F10 RECON menu +ctld.reconMenuName = ctld.i18n_translate("RECON") --name of the CTLD JTAC radio menu +ctld.reconRadioAdded = {} --stores the groups that have had the radio menu added +ctld.reconLosSearchRadius = 2000 -- search radius in meters +ctld.reconLosMarkRadius = 100 -- mark radius dimension in meters +ctld.reconAutoRefreshLosTargetMarks = true -- if true recon LOS marks are automaticaly refreshed on F10 map +ctld.reconLastScheduleIdAutoRefresh = 0 + +---- F10 RECON Menus ------------------------------------------------------------------ +function ctld.addReconRadioCommand(_side) -- _side = 1 or 2 (red or blue) + if ctld.reconF10Menu then + if _side == 1 or _side == 2 then + local _players = coalition.getPlayers(_side) + if _players ~= nil then + for _, _playerUnit in pairs(_players) do + local _groupId = ctld.getGroupId(_playerUnit) + if _groupId then + if ctld.reconRadioAdded[tostring(_groupId)] == nil then + ctld.logDebug("ctld.addReconRadioCommand - adding RECON radio menu for unit [%s]", ctld.p(_playerUnit:getName())) + local RECONpath = missionCommands.addSubMenuForGroup(_groupId, ctld.reconMenuName) + missionCommands.addCommandForGroup(_groupId, + ctld.i18n_translate("Show targets in LOS (refresh)"), RECONpath, + ctld.reconRefreshTargetsInLosOnF10Map, { + _groupId = _groupId, + _playerUnit = _playerUnit, + _searchRadius = ctld.reconLosSearchRadius, + _markRadius = ctld.reconLosMarkRadius, + _boolRemove = true + }) + missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Hide targets in LOS"), RECONpath, ctld.reconRemoveTargetsInLosOnF10Map, _playerUnit) + if ctld.reconAutoRefreshLosTargetMarks then + missionCommands.addCommandForGroup(_groupId, + ctld.i18n_translate("STOP autoRefresh targets in LOS"), RECONpath, + ctld.reconStopAutorefreshTargetsInLosOnF10Map, + _groupId, + _playerUnit, + ctld.reconLosSearchRadius, + ctld.reconLosMarkRadius, + true) + else + missionCommands.addCommandForGroup(_groupId, + ctld.i18n_translate("START autoRefresh targets in LOS"), RECONpath, + ctld.reconStartAutorefreshTargetsInLosOnF10Map, + _groupId, + _playerUnit, + ctld.reconLosSearchRadius, + ctld.reconLosMarkRadius, + true + ) + end + ctld.reconRadioAdded[tostring(_groupId)] = timer.getTime() --fetch the time to check for a regular refresh + end + end + end + end + end + end +end +-------------------------------------------------------------------- +function ctld.reconStopAutorefreshTargetsInLosOnF10Map(_groupId, _playerUnit, _searchRadius, _markRadius, _boolRemove) + ctld.reconAutoRefreshLosTargetMarks = false + + if ctld.reconLastScheduleIdAutoRefresh ~= 0 then + timer.removeFunction(ctld.reconLastScheduleIdAutoRefresh) -- reset last schedule + end + + ctld.reconRemoveTargetsInLosOnF10Map(_playerUnit) + missionCommands.removeItemForGroup(_groupId, {ctld.reconMenuName, ctld.i18n_translate("STOP autoRefresh targets in LOS")}) + missionCommands.addCommandForGroup( _groupId, ctld.i18n_translate("START autoRefresh targets in LOS"), {ctld.reconMenuName}, + ctld.reconStartAutorefreshTargetsInLosOnF10Map, + _groupId, + _playerUnit, + _searchRadius, + _markRadius, + _boolRemove) +end +-------------------------------------------------------------------- +function ctld.reconStartAutorefreshTargetsInLosOnF10Map(_groupId, _playerUnit, _searchRadius, _markRadius, _boolRemove) + ctld.reconAutoRefreshLosTargetMarks = true + ctld.reconRefreshTargetsInLosOnF10Map({ _groupId = _groupId, + _playerUnit = _playerUnit, + _searchRadius = _searchRadius or ctld.reconLosSearchRadius, + _markRadius = _markRadius or ctld.reconLosMarkRadius, + _boolRemove = _boolRemove or true}, + timer.getTime()) + missionCommands.removeItemForGroup( _groupId, {ctld.reconMenuName, ctld.i18n_translate("START autoRefresh targets in LOS")}) + missionCommands.addCommandForGroup( _groupId, ctld.i18n_translate("STOP autoRefresh targets in LOS"), {ctld.reconMenuName}, + ctld.reconStopAutorefreshTargetsInLosOnF10Map, + _groupId, + _playerUnit, + _searchRadius, + _markRadius, + _boolRemove) +end +-------------------------------------------------------------------- +function ctld.reconShowTargetsInLosOnF10Map(_playerUnit, _searchRadius, _markRadius) -- _groupId targeting + -- _searchRadius and _markRadius in meters + if _playerUnit then + local TargetsInLOS = {} + + local enemyColor = "red" + local color = {1, 0, 0, 0.2} -- red + + if _playerUnit:getCoalition() == 1 then + enemyColor = "blue" + color = {51/255, 51/255, 1, 0.2} -- blue + end + + local t = mist.getUnitsLOS({_playerUnit:getName()}, 180, mist.makeUnitTable({'['..enemyColor..'][vehicle]'}),180, _searchRadius) + + local MarkIds = {} + if t then + for i=1, #t do -- for each unit having los on enemies + for j=1, #t[i].vis do -- for each enemy unit in los + local targetPoint = t[i].vis[j]:getPoint() -- point of each target on LOS + ctld.lastMarkId = ctld.lastMarkId + 1 + trigger.action.circleToAll(_playerUnit:getCoalition(), ctld.lastMarkId, targetPoint, _markRadius , color, color, 1, false, nil) + MarkIds[#MarkIds+1] = ctld.lastMarkId + TargetsInLOS[#TargetsInLOS+1] = { targetObject = t[i].vis[j]:getName(), + targetTypeName = t[i].vis[j]:getTypeName(), + targetPoint = targetPoint} + end + end + end + mist.DBs.humansByName[_playerUnit:getName()].losMarkIds = MarkIds -- store list of marksIds generated and showed on F10 map + return TargetsInLOS + else + return nil + end +end +--------------------------------------------------------- +function ctld.reconRemoveTargetsInLosOnF10Map(_playerUnit) + local unitName = _playerUnit:getName() + if mist.DBs.humansByName[unitName].losMarkIds then + for i=1, #mist.DBs.humansByName[unitName].losMarkIds do -- for each unit having los on enemies + trigger.action.removeMark(mist.DBs.humansByName[unitName].losMarkIds[i]) + end + mist.DBs.humansByName[unitName].losMarkIds = nil + end +end +--------------------------------------------------------- +function ctld.reconRefreshTargetsInLosOnF10Map(_params, _t) -- _params._playerUnit targeting + -- _params._searchRadius and _params._markRadius in meters + -- _params._boolRemove = true to remove previous marksIds + if _t == nil then _t = timer.getTime() end + + if ctld.reconAutoRefreshLosTargetMarks then -- to follow mobile enemy targets + ctld.reconLastScheduleIdAutoRefresh = timer.scheduleFunction(ctld.reconRefreshTargetsInLosOnF10Map, {_groupId = _params._groupId, + _playerUnit = _params._playerUnit, + _searchRadius = _params._searchRadius, + _markRadius = _params._markRadius, + _boolRemove = _params._boolRemove + }, + timer.getTime() + 10) + end + + if _params._boolRemove == true then + ctld.reconRemoveTargetsInLosOnF10Map(_params._playerUnit) + end + + return ctld.reconShowTargetsInLosOnF10Map(_params._playerUnit, _params._searchRadius, _params._markRadius) -- returns TargetsInLOS table +end +--- test ------------------------------------------------------ +--local unitName = "uh2-1" --"uh1-1" --"uh2-1" +--ctld.reconShowTargetsInLosOnF10Map(Unit.getByName(unitName),2000,200) + + +--********************************************************************** -- ***************** SETUP SCRIPT **************** function ctld.initialize() diff --git a/README.md b/README.md index 657846f..b34ffd6 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ This script is a rewrite of some of the functionality of the original Complete C * [Mi\-8 ARC\-9 VHF Radio Setup](#mi-8-arc-9-vhf-radio-setup) * [UH\-1 ADF VHF Radio Setup](#uh-1-adf-vhf-radio-setup) * [Advanced Scripting](#advanced-scripting) +* [recognition assistance](#recognition-assistance) ## Features The script supports: @@ -103,6 +104,7 @@ The script supports: * Count soldiers extracted to a zone (the soldiers disappear) * Waypoint triggers to force dropped groups to head to a location * Advanced Scripting Callback system +* Target recognition assistance functions to mark targets on the F10 map A complete test mission is included. @@ -1102,6 +1104,13 @@ White pointer pointing to beacon on the compass: ![alt text](http://i1056.photobucket.com/albums/t379/cfisher881/dcs.exe_DX9_20150608_075211_zpsdaus4wxt.png~original "Radio Compass") +# recognition-assistance +The recognition functions in the F10 menu allow you to mark/delete/refresh marks on targets within sight of the aircraft being piloted by the player. + +Enabling/disabling automatic refreshing of marks on targets within view allows you to track them as they move. + +Below is a complete list of all the "actions" plus the data that is sent through. For more information its best to check the CTLD Code to see more details of the arguments. + # Advanced Scripting CTLD has an optional callback API that can be used to trigger actions in code