mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Add CTLD script and update JTACAutoLase config
- Added the CTLD script - Removed the previous jtacautolase script - Updated the configuration to allow the JTACAutoLase function to work - Added the JTac name, freq and mod to the lua
This commit is contained in:
parent
0a7ded4052
commit
de148dbb61
@ -20,6 +20,7 @@ Saves from 5.x are not compatible with 6.0.
|
||||
* **[UI]** Added separate images for the different carrier types.
|
||||
* **[Campaign]** Allow campaign designers to define default values for the economy settings (starting budget and multiplier).
|
||||
* **[Plugins]** Allow full support of the SkynetIADS plugin with all advanced features (connection nodes, power sources, command centers) if campaign supports it.
|
||||
* **[Plugins]** Added support for the CTLD script by ciribob and updated the JTAC Autolase
|
||||
|
||||
## Fixes
|
||||
|
||||
|
||||
@ -146,7 +146,7 @@ class FlotGenerator:
|
||||
# If the option fc3LaserCode is enabled, force all JTAC
|
||||
# laser codes to 1113 to allow lasing for Su-25 Frogfoots and A-10A Warthogs.
|
||||
# Otherwise use 1688 for the first JTAC, 1687 for the second etc.
|
||||
if self.game.settings.plugins["plugins.jtacautolase.fc3LaserCode"]:
|
||||
if self.game.settings.plugins["plugins.ctld.fc3LaserCode"]:
|
||||
code = 1113
|
||||
else:
|
||||
code = self.laser_code_registry.get_next_laser_code()
|
||||
|
||||
@ -77,6 +77,17 @@ class LuaGenerator:
|
||||
jtac_item.add_key_value("zone", jtac.region)
|
||||
jtac_item.add_key_value("dcsUnit", jtac.unit_name)
|
||||
jtac_item.add_key_value("laserCode", jtac.code)
|
||||
jtac_item.add_key_value("radio", str(jtac.freq.mhz))
|
||||
jtac_item.add_key_value("modulation", jtac.freq.modulation.name)
|
||||
|
||||
logistics_object = lua_data.add_item("Logistics")
|
||||
for logistic_info in self.air_support.logistics.values():
|
||||
logistics_item = logistics_object.add_item()
|
||||
logistics_item.add_data_array("pilot_names", logistic_info.pilot_names)
|
||||
logistics_item.add_key_value("pickup_zone", logistic_info.pickup_zone)
|
||||
logistics_item.add_key_value("drop_off_zone", logistic_info.drop_off_zone)
|
||||
logistics_item.add_key_value("target_zone", logistic_info.target_zone)
|
||||
logistics_item.add_key_value("side", str(2 if logistic_info.blue else 1))
|
||||
|
||||
target_points = lua_data.add_item("TargetPoints")
|
||||
for flight in self.flights:
|
||||
|
||||
6427
resources/plugins/ctld/CTLD.lua
Normal file
6427
resources/plugins/ctld/CTLD.lua
Normal file
File diff suppressed because it is too large
Load Diff
66
resources/plugins/ctld/ctld-config.lua
Normal file
66
resources/plugins/ctld/ctld-config.lua
Normal file
@ -0,0 +1,66 @@
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- configuration file for the CTLD Plugin including the JTAC Autolase
|
||||
--
|
||||
-- This configuration is tailored for a mission generated by DCS Liberation
|
||||
-- see https://github.com/dcs-liberation/dcs_liberation
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- CTLD plugin - configuration
|
||||
if dcsLiberation then
|
||||
local ctld_pickup_smoke = "none"
|
||||
local ctld_dropoff_smoke = "none"
|
||||
|
||||
-- JTACAutoLase specific options
|
||||
local autolase = false
|
||||
local smoke = false
|
||||
local fc3LaserCode = false
|
||||
|
||||
-- retrieve specific options values
|
||||
if dcsLiberation.plugins then
|
||||
if dcsLiberation.plugins.ctld then
|
||||
env.info("DCSLiberation|CTLD plugin - Setting Up")
|
||||
|
||||
ctld.Debug = dcsLiberation.plugins.ctld.debug
|
||||
ctld.Trace = dcsLiberation.plugins.ctld.debug
|
||||
ctld.transportPilotNames = {}
|
||||
ctld.pickupZones = {}
|
||||
ctld.dropOffZones = {}
|
||||
ctld.wpZones = {}
|
||||
|
||||
for _, item in pairs(dcsLiberation.Logistics) do
|
||||
for _, pilot in pairs(item.pilot_names) do
|
||||
table.insert(ctld.transportPilotNames, pilot)
|
||||
end
|
||||
if dcsLiberation.plugins.ctld.smoke then
|
||||
ctld_pickup_smoke = "blue"
|
||||
ctld_dropoff_smoke = "green"
|
||||
end
|
||||
table.insert(ctld.pickupZones, { item.pickup_zone, ctld_pickup_smoke, -1, "yes", tonumber(item.side) })
|
||||
table.insert(ctld.dropOffZones, { item.drop_off_zone, ctld_dropoff_smoke, tonumber(item.side) })
|
||||
table.insert(ctld.wpZones, { item.target_zone, "none", "yes", tonumber(item.side) })
|
||||
end
|
||||
|
||||
autolase = dcsLiberation.plugins.ctld.autolase
|
||||
env.info(string.format("DCSLiberation|CTLD plugin - JTAC AutoLase enabled = %s", tostring(autolase)))
|
||||
|
||||
if autolase then
|
||||
smoke = dcsLiberation.plugins.ctld.jtacsmoke
|
||||
env.info(string.format("DCSLiberation|CTLD plugin - JTACAutolase smoke = %s", tostring(smoke)))
|
||||
|
||||
fc3LaserCode = dcsLiberation.plugins.ctld.fc3LaserCode
|
||||
env.info(string.format("DCSLiberation|CTLD plugin - JTACAutolase fc3LaserCode = %s", tostring(fc3LaserCode)))
|
||||
|
||||
-- JTAC Autolase configuration code
|
||||
for _, jtac in pairs(dcsLiberation.JTACs) do
|
||||
env.info(string.format("DCSLiberation|JTACAutolase - setting up %s", jtac.dcsUnit))
|
||||
if fc3LaserCode then
|
||||
-- If fc3LaserCode is enabled in the plugin configuration, force the JTAC
|
||||
-- laser code to 1113 to allow lasing for Su-25 Frogfoots and A-10A Warthogs.
|
||||
jtac.laserCode = 1113
|
||||
end
|
||||
ctld.JTACAutoLase(jtac.dcsUnit, jtac.laserCode, smoke, 'vehicle', nil, { freq = jtac.radio, mod = jtac.modulation, name = jtac.dcsGroupName })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
43
resources/plugins/ctld/plugin.json
Normal file
43
resources/plugins/ctld/plugin.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"nameInUI": "CTLD",
|
||||
"defaultValue": true,
|
||||
"specificOptions": [
|
||||
{
|
||||
"nameInUI": "CTLD Use smoke in zones",
|
||||
"mnemonic": "smoke",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"nameInUI": "JTAC Autolase",
|
||||
"mnemonic": "autolase",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"nameInUI": "JTAC Use smoke",
|
||||
"mnemonic": "jtacsmoke",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"nameInUI": "Use FC3 laser code (1113)",
|
||||
"mnemonic": "fc3LaserCode",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"nameInUI": "CTLD Debug",
|
||||
"mnemonic": "ctld-debug",
|
||||
"defaultValue": false
|
||||
}
|
||||
],
|
||||
"scriptsWorkOrders": [
|
||||
{
|
||||
"file": "CTLD.lua",
|
||||
"mnemonic": "ctld-script"
|
||||
}
|
||||
],
|
||||
"configurationWorkOrders": [
|
||||
{
|
||||
"file": "ctld-config.lua",
|
||||
"mnemonic": "ctld-config"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,729 +0,0 @@
|
||||
--[[
|
||||
JTAC Automatic Targeting and Laser Script
|
||||
|
||||
Allows a JTAC to mark and hold an IR and Laser point on a target allowing TGP's to lock onto the lase and ease
|
||||
of target location using NV Goggles
|
||||
|
||||
The JTAC will automatically switch targets when a target is destroyed or goes out of Line of Sight
|
||||
|
||||
NOTE: LOS doesn't include buildings or tree's... Sorry!
|
||||
|
||||
The script can also be useful in daylight by enabling the JTAC to mark enemy positions with Smoke.
|
||||
The JTAC will only move the smoke to the target every 5 minutes (to stop a huge trail of smoke markers) unless the target
|
||||
is destroyed, in which case the new target will be marked straight away with smoke.
|
||||
|
||||
You can also enable an F10 menu option for coalition units allowing the JTAC(s) to report their current status.
|
||||
|
||||
If a JTAC is down it won't report in.
|
||||
|
||||
USAGE:
|
||||
|
||||
Place JTAC units on the map with the mission editor putting each JTAC in it's own group containing only itself and no
|
||||
other units. Name the group something easy to remember e.g. JTAC1 and make sure the JTAC units have a unique name which must
|
||||
not be the same as the group name. The editor should do this for you but be careful if you copy and paste.
|
||||
|
||||
Load the script at the start of the mission with a Trigger Once or as the init script of the mission
|
||||
|
||||
Run the code below as a DO SCRIPT at the start of the mission, or after a delay if you prefer
|
||||
|
||||
JTACAutoLase('JTAC1', 1688)
|
||||
|
||||
OR
|
||||
|
||||
JTACAutoLase('JTAC1', 1688, false,"all") - means no smoke marks for this jtac and it will target all ground troops
|
||||
|
||||
OR
|
||||
|
||||
JTACAutoLase('JTAC1', 1688, true,"vehicle") - means smoke marks for this jtac and it will target ONLY ground vehicles
|
||||
|
||||
OR
|
||||
|
||||
JTACAutoLase('JTAC1', 1688, true,"troop") - means smoke marks for this jtac and it will target ONLY ground troops
|
||||
|
||||
OR
|
||||
|
||||
JTACAutoLase('JTAC1', 1688, true,"all", 4) - means BLUE smoke marks for this jtac and it will target all ground troops
|
||||
|
||||
Where JTAC1 is the Group name of the JTAC Group with one and only one JTAC unit.
|
||||
|
||||
The script doesn't care if the unit isn't activated when run, as it'll automatically activate when the JTAC is activated in
|
||||
the mission but there can be a delay of up to 30 seconds after activation for the JTAC to start searching for targets.
|
||||
|
||||
You can also run the code at any time if a JTAC is dynamically added to the map as long as you know the Group name of the JTAC.
|
||||
|
||||
Last Edit: 21/04/2015
|
||||
|
||||
Change log:
|
||||
Added new config of JTAC smoke colour globally or per JTAC
|
||||
Added new config of JTAC targetting to either target only troops or vehicles or all
|
||||
Added new induvidual config of JTAC smoke and location which will override global setting
|
||||
Added Lat / Lon + MGRS to JTAC Target position
|
||||
Changed Lasing method to update laser marker rather than create and destroy
|
||||
- This gives much better tracking behaviour!
|
||||
Fixed JTAC lasing through terrain.
|
||||
Fixed Lase staying on when JTAC Dies
|
||||
Fixed Lase staying on when target dies and there are no other targets
|
||||
Added Radio noise when message is shown
|
||||
Stop multiple JTACS targeting the same target
|
||||
|
||||
|
||||
Parts of MIST used. Source is https://github.com/mrSkortch/MissionScriptingTools/blob/master/mist.lua
|
||||
|
||||
]]
|
||||
|
||||
-- CONFIG
|
||||
JTAC_maxDistance = 50000 -- How far a JTAC can "see" in meters (with LOS)
|
||||
|
||||
JTAC_smokeOn = true -- enables marking of target with smoke, can be overriden by the JTACAutoLase in editor
|
||||
|
||||
JTAC_smokeColour = 1 -- Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4
|
||||
|
||||
JTAC_jtacStatusF10 = true -- enables F10 JTAC Status menu
|
||||
|
||||
JTAC_location = true -- shows location in JTAC message, can be overriden by the JTACAutoLase in editor
|
||||
|
||||
JTAC_lock = "all" -- "vehicle" OR "troop" OR "all" forces JTAC to only lock vehicles or troops or all ground units
|
||||
|
||||
-- END CONFIG
|
||||
|
||||
-- BE CAREFUL MODIFYING BELOW HERE
|
||||
|
||||
GLOBAL_JTAC_LASE = {}
|
||||
GLOBAL_JTAC_IR = {}
|
||||
GLOBAL_JTAC_SMOKE = {}
|
||||
GLOBAL_JTAC_UNITS = {} -- list of JTAC units for f10 command
|
||||
GLOBAL_JTAC_CURRENT_TARGETS = {}
|
||||
GLOBAL_JTAC_RADIO_ADDED = {} --keeps track of who's had the radio command added
|
||||
GLOBAL_JTAC_LASER_CODES = {} -- keeps track of laser codes for jtac
|
||||
|
||||
|
||||
function JTACAutoLase(jtacGroupName, laserCode,smoke,lock,colour)
|
||||
|
||||
if smoke == nil then
|
||||
|
||||
smoke = JTAC_smokeOn
|
||||
end
|
||||
|
||||
if lock == nil then
|
||||
|
||||
lock = JTAC_lock
|
||||
end
|
||||
|
||||
if colour == nil then
|
||||
colour = JTAC_smokeColour
|
||||
end
|
||||
|
||||
GLOBAL_JTAC_LASER_CODES[jtacGroupName] = laserCode
|
||||
|
||||
local jtacGroup = getGroup(jtacGroupName)
|
||||
local jtacUnit
|
||||
|
||||
if jtacGroup == nil or #jtacGroup == 0 then
|
||||
|
||||
notify("JTAC Group " .. jtacGroupName .. " KIA!", 10)
|
||||
|
||||
--remove from list
|
||||
GLOBAL_JTAC_UNITS[jtacGroupName] = nil
|
||||
|
||||
cleanupJTAC(jtacGroupName)
|
||||
|
||||
return
|
||||
else
|
||||
|
||||
jtacUnit = jtacGroup[1]
|
||||
--add to list
|
||||
GLOBAL_JTAC_UNITS[jtacGroupName] = jtacUnit:getName()
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- search for current unit
|
||||
|
||||
if jtacUnit:isActive() == false then
|
||||
|
||||
cleanupJTAC(jtacGroupName)
|
||||
|
||||
env.info(jtacGroupName .. ' Not Active - Waiting 30 seconds')
|
||||
timer.scheduleFunction(timerJTACAutoLase, { jtacGroupName, laserCode,smoke,lock,colour}, timer.getTime() + 30)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local enemyUnit = getCurrentUnit(jtacUnit, jtacGroupName)
|
||||
|
||||
if enemyUnit == nil and GLOBAL_JTAC_CURRENT_TARGETS[jtacGroupName] ~= nil then
|
||||
|
||||
local tempUnitInfo = GLOBAL_JTAC_CURRENT_TARGETS[jtacGroupName]
|
||||
|
||||
-- env.info("TEMP UNIT INFO: " .. tempUnitInfo.name .. " " .. tempUnitInfo.unitType)
|
||||
|
||||
local tempUnit = Unit.getByName(tempUnitInfo.name)
|
||||
|
||||
if tempUnit ~= nil and tempUnit:getLife() > 0 and tempUnit:isActive() == true then
|
||||
notify(jtacGroupName .. " target " .. tempUnitInfo.unitType .. " lost. Scanning for Targets. ", 20)
|
||||
else
|
||||
notify(jtacGroupName .. " target " .. tempUnitInfo.unitType .. " KIA. Good Job! Scanning for Targets. ", 20)
|
||||
end
|
||||
|
||||
--remove from smoke list
|
||||
GLOBAL_JTAC_SMOKE[tempUnitInfo.name] = nil
|
||||
|
||||
-- remove from target list
|
||||
GLOBAL_JTAC_CURRENT_TARGETS[jtacGroupName] = nil
|
||||
|
||||
--stop lasing
|
||||
cancelLase(jtacGroupName)
|
||||
|
||||
end
|
||||
|
||||
|
||||
if enemyUnit == nil then
|
||||
enemyUnit = findNearestVisibleEnemy(jtacUnit,lock)
|
||||
|
||||
if enemyUnit ~= nil then
|
||||
|
||||
-- store current target for easy lookup
|
||||
GLOBAL_JTAC_CURRENT_TARGETS[jtacGroupName] = { name = enemyUnit:getName(), unitType = enemyUnit:getTypeName(), unitId = enemyUnit:getID() }
|
||||
|
||||
notify(jtacGroupName .. " lasing new target " .. enemyUnit:getTypeName() .. '. CODE: ' .. laserCode ..getPositionString(enemyUnit) , 30)
|
||||
|
||||
-- create smoke
|
||||
if smoke == true then
|
||||
|
||||
--create first smoke
|
||||
createSmokeMarker(enemyUnit,colour)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if enemyUnit ~= nil then
|
||||
|
||||
laseUnit(enemyUnit, jtacUnit, jtacGroupName, laserCode)
|
||||
|
||||
-- env.info('Timer timerSparkleLase '..jtacGroupName.." "..laserCode.." "..enemyUnit:getName())
|
||||
timer.scheduleFunction(timerJTACAutoLase, { jtacGroupName, laserCode, smoke,lock,colour }, timer.getTime() + 1)
|
||||
|
||||
|
||||
if smoke == true then
|
||||
local nextSmokeTime = GLOBAL_JTAC_SMOKE[enemyUnit:getName()]
|
||||
|
||||
--recreate smoke marker after 5 mins
|
||||
if nextSmokeTime ~= nil and nextSmokeTime < timer.getTime() then
|
||||
|
||||
createSmokeMarker(enemyUnit, colour)
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
-- env.info('LASE: No Enemies Nearby')
|
||||
|
||||
-- stop lazing the old spot
|
||||
cancelLase(jtacGroupName)
|
||||
-- env.info('Timer Slow timerSparkleLase '..jtacGroupName.." "..laserCode.." "..enemyUnit:getName())
|
||||
|
||||
timer.scheduleFunction(timerJTACAutoLase, { jtacGroupName, laserCode, smoke,lock,colour }, timer.getTime() + 5)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- used by the timer function
|
||||
function timerJTACAutoLase(args)
|
||||
|
||||
JTACAutoLase(args[1], args[2], args[3],args[4])
|
||||
end
|
||||
|
||||
function cleanupJTAC(jtacGroupName)
|
||||
-- clear laser - just in case
|
||||
cancelLase(jtacGroupName)
|
||||
|
||||
-- Cleanup
|
||||
GLOBAL_JTAC_UNITS[jtacGroupName] = nil
|
||||
|
||||
GLOBAL_JTAC_CURRENT_TARGETS[jtacGroupName] = nil
|
||||
end
|
||||
|
||||
|
||||
function notify(message, displayFor)
|
||||
|
||||
|
||||
trigger.action.outTextForCoalition(coalition.side.BLUE, message, displayFor)
|
||||
trigger.action.outSoundForCoalition(coalition.side.BLUE, "radiobeep.ogg")
|
||||
end
|
||||
|
||||
function createSmokeMarker(enemyUnit,colour)
|
||||
|
||||
--recreate in 5 mins
|
||||
GLOBAL_JTAC_SMOKE[enemyUnit:getName()] = timer.getTime() + 300.0
|
||||
|
||||
-- move smoke 2 meters above target for ease
|
||||
local enemyPoint = enemyUnit:getPoint()
|
||||
trigger.action.smoke({ x = enemyPoint.x, y = enemyPoint.y + 2.0, z = enemyPoint.z }, colour)
|
||||
end
|
||||
|
||||
function cancelLase(jtacGroupName)
|
||||
|
||||
--local index = "JTAC_"..jtacUnit:getID()
|
||||
|
||||
local tempLase = GLOBAL_JTAC_LASE[jtacGroupName]
|
||||
|
||||
if tempLase ~= nil then
|
||||
Spot.destroy(tempLase)
|
||||
GLOBAL_JTAC_LASE[jtacGroupName] = nil
|
||||
|
||||
-- env.info('Destroy laze '..index)
|
||||
|
||||
tempLase = nil
|
||||
end
|
||||
|
||||
local tempIR = GLOBAL_JTAC_IR[jtacGroupName]
|
||||
|
||||
if tempIR ~= nil then
|
||||
Spot.destroy(tempIR)
|
||||
GLOBAL_JTAC_IR[jtacGroupName] = nil
|
||||
|
||||
-- env.info('Destroy laze '..index)
|
||||
|
||||
tempIR = nil
|
||||
end
|
||||
end
|
||||
|
||||
function laseUnit(enemyUnit, jtacUnit, jtacGroupName, laserCode)
|
||||
|
||||
--cancelLase(jtacGroupName)
|
||||
|
||||
local spots = {}
|
||||
|
||||
local enemyVector = enemyUnit:getPoint()
|
||||
local enemyVectorUpdated = { x = enemyVector.x, y = enemyVector.y + 2.0, z = enemyVector.z }
|
||||
|
||||
local oldLase = GLOBAL_JTAC_LASE[jtacGroupName]
|
||||
local oldIR = GLOBAL_JTAC_IR[jtacGroupName]
|
||||
|
||||
if oldLase == nil or oldIR == nil then
|
||||
|
||||
-- create lase
|
||||
|
||||
local status, result = pcall(function()
|
||||
spots['irPoint'] = Spot.createInfraRed(jtacUnit, { x = 0, y = 2.0, z = 0 }, enemyVectorUpdated)
|
||||
spots['laserPoint'] = Spot.createLaser(jtacUnit, { x = 0, y = 2.0, z = 0 }, enemyVectorUpdated, laserCode)
|
||||
return spots
|
||||
end)
|
||||
|
||||
if not status then
|
||||
env.error('ERROR: ' .. assert(result), false)
|
||||
else
|
||||
if result.irPoint then
|
||||
|
||||
-- env.info(jtacUnit:getName() .. ' placed IR Pointer on '..enemyUnit:getName())
|
||||
|
||||
GLOBAL_JTAC_IR[jtacGroupName] = result.irPoint --store so we can remove after
|
||||
|
||||
end
|
||||
if result.laserPoint then
|
||||
|
||||
-- env.info(jtacUnit:getName() .. ' is Lasing '..enemyUnit:getName()..'. CODE:'..laserCode)
|
||||
|
||||
GLOBAL_JTAC_LASE[jtacGroupName] = result.laserPoint
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
-- update lase
|
||||
|
||||
if oldLase~=nil then
|
||||
oldLase:setPoint(enemyVectorUpdated)
|
||||
end
|
||||
|
||||
if oldIR ~= nil then
|
||||
oldIR:setPoint(enemyVectorUpdated)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- get currently selected unit and check they're still in range
|
||||
function getCurrentUnit(jtacUnit, jtacGroupName)
|
||||
|
||||
|
||||
local unit = nil
|
||||
|
||||
if GLOBAL_JTAC_CURRENT_TARGETS[jtacGroupName] ~= nil then
|
||||
unit = Unit.getByName(GLOBAL_JTAC_CURRENT_TARGETS[jtacGroupName].name)
|
||||
end
|
||||
|
||||
local tempPoint = nil
|
||||
local tempDist = nil
|
||||
local tempPosition = nil
|
||||
|
||||
local jtacPosition = jtacUnit:getPosition()
|
||||
local jtacPoint = jtacUnit:getPoint()
|
||||
|
||||
if unit ~= nil and unit:getLife() > 0 and unit:isActive() == true then
|
||||
|
||||
-- calc distance
|
||||
tempPoint = unit:getPoint()
|
||||
-- tempPosition = unit:getPosition()
|
||||
|
||||
tempDist = getDistance(tempPoint.x, tempPoint.z, jtacPoint.x, jtacPoint.z)
|
||||
if tempDist < JTAC_maxDistance then
|
||||
-- calc visible
|
||||
|
||||
-- check slightly above the target as rounding errors can cause issues, plus the unit has some height anyways
|
||||
local offsetEnemyPos = { x = tempPoint.x, y = tempPoint.y + 2.0, z = tempPoint.z }
|
||||
local offsetJTACPos = { x = jtacPoint.x, y = jtacPoint.y + 2.0, z = jtacPoint.z }
|
||||
|
||||
if land.isVisible(offsetEnemyPos, offsetJTACPos) then
|
||||
return unit
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
-- Find nearest enemy to JTAC that isn't blocked by terrain
|
||||
function findNearestVisibleEnemy(jtacUnit, targetType)
|
||||
|
||||
local x = 1
|
||||
local i = 1
|
||||
|
||||
local units = nil
|
||||
local groupName = nil
|
||||
|
||||
local nearestUnit = nil
|
||||
local nearestDistance = JTAC_maxDistance
|
||||
|
||||
local redGroups = coalition.getGroups(1, Group.Category.GROUND)
|
||||
|
||||
local jtacPoint = jtacUnit:getPoint()
|
||||
local jtacPosition = jtacUnit:getPosition()
|
||||
|
||||
local tempPoint = nil
|
||||
local tempPosition = nil
|
||||
|
||||
local tempDist = nil
|
||||
|
||||
-- finish this function
|
||||
for i = 1, #redGroups do
|
||||
if redGroups[i] ~= nil then
|
||||
groupName = redGroups[i]:getName()
|
||||
units = getGroup(groupName)
|
||||
if #units > 0 then
|
||||
|
||||
for x = 1, #units do
|
||||
|
||||
--check to see if a JTAC has already targeted this unit
|
||||
local targeted = alreadyTarget(jtacUnit,units[x])
|
||||
local allowedTarget = true
|
||||
|
||||
if targetType == "vehicle" then
|
||||
|
||||
allowedTarget = isVehicle(units[x])
|
||||
|
||||
elseif targetType == "troop" then
|
||||
|
||||
allowedTarget = isInfantry(units[x])
|
||||
|
||||
end
|
||||
|
||||
|
||||
if units[x]:isActive() == true and targeted == false and allowedTarget == true then
|
||||
|
||||
-- calc distance
|
||||
tempPoint = units[x]:getPoint()
|
||||
-- tempPosition = units[x]:getPosition()
|
||||
|
||||
tempDist = getDistance(tempPoint.x, tempPoint.z, jtacPoint.x, jtacPoint.z)
|
||||
|
||||
-- env.info("tempDist" ..tempDist)
|
||||
-- env.info("JTAC_maxDistance" ..JTAC_maxDistance)
|
||||
|
||||
if tempDist < JTAC_maxDistance and tempDist < nearestDistance then
|
||||
|
||||
local offsetEnemyPos = { x = tempPoint.x, y = tempPoint.y + 2.0, z = tempPoint.z }
|
||||
local offsetJTACPos = { x = jtacPoint.x, y = jtacPoint.y + 2.0, z = jtacPoint.z }
|
||||
|
||||
|
||||
-- calc visible
|
||||
if land.isVisible(offsetEnemyPos, offsetJTACPos) then
|
||||
|
||||
nearestDistance = tempDist
|
||||
nearestUnit = units[x]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if nearestUnit == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
return nearestUnit
|
||||
end
|
||||
-- tests whether the unit is targeted by another JTAC
|
||||
function alreadyTarget(jtacUnit, enemyUnit)
|
||||
|
||||
for y , jtacTarget in pairs(GLOBAL_JTAC_CURRENT_TARGETS) do
|
||||
|
||||
if jtacTarget.unitId == enemyUnit:getID() then
|
||||
-- env.info("ALREADY TARGET")
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- Returns only alive units from group but the group / unit may not be active
|
||||
|
||||
function getGroup(groupName)
|
||||
|
||||
local groupUnits = Group.getByName(groupName)
|
||||
|
||||
local filteredUnits = {} --contains alive units
|
||||
local x = 1
|
||||
|
||||
if groupUnits ~= nil then
|
||||
|
||||
groupUnits = groupUnits:getUnits()
|
||||
|
||||
if groupUnits ~= nil and #groupUnits > 0 then
|
||||
for x = 1, #groupUnits do
|
||||
if groupUnits[x]:getLife() > 0 then
|
||||
table.insert(filteredUnits, groupUnits[x])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return filteredUnits
|
||||
end
|
||||
|
||||
-- Distance measurement between two positions, assume flat world
|
||||
|
||||
function getDistance(xUnit, yUnit, xZone, yZone)
|
||||
local xDiff = xUnit - xZone
|
||||
local yDiff = yUnit - yZone
|
||||
|
||||
return math.sqrt(xDiff * xDiff + yDiff * yDiff)
|
||||
end
|
||||
|
||||
-- gets the JTAC status and displays to coalition units
|
||||
function getJTACStatus()
|
||||
|
||||
--returns the status of all JTAC units
|
||||
|
||||
local jtacGroupName = nil
|
||||
local jtacUnit = nil
|
||||
local jtacUnitName = nil
|
||||
|
||||
local message = "JTAC STATUS: \n\n"
|
||||
|
||||
for jtacGroupName, jtacUnitName in pairs(GLOBAL_JTAC_UNITS) do
|
||||
|
||||
--look up units
|
||||
jtacUnit = Unit.getByName(jtacUnitName)
|
||||
|
||||
if jtacUnit ~= nil and jtacUnit:getLife() > 0 and jtacUnit:isActive() == true then
|
||||
|
||||
local enemyUnit = getCurrentUnit(jtacUnit, jtacGroupName)
|
||||
|
||||
local laserCode = GLOBAL_JTAC_LASER_CODES[jtacGroupName]
|
||||
|
||||
if laserCode == nil then
|
||||
laserCode = "UNKNOWN"
|
||||
end
|
||||
|
||||
if enemyUnit ~= nil and enemyUnit:getLife() > 0 and enemyUnit:isActive() == true then
|
||||
message = message .. "" .. jtacGroupName .. " targeting " .. enemyUnit:getTypeName().. " CODE: ".. laserCode .. getPositionString(enemyUnit) .. "\n"
|
||||
else
|
||||
message = message .. "" .. jtacGroupName .. " searching for targets" .. getPositionString(jtacUnit) .."\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
notify(message, 60)
|
||||
end
|
||||
|
||||
|
||||
-- Radio command for players (F10 Menu)
|
||||
|
||||
function addRadioCommands()
|
||||
|
||||
--looop over all players and add command
|
||||
-- missionCommands.addCommandForCoalition( coalition.side.BLUE, "JTAC Status" ,nil, getJTACStatus ,nil)
|
||||
|
||||
timer.scheduleFunction(addRadioCommands, nil, timer.getTime() + 10)
|
||||
|
||||
local blueGroups = coalition.getGroups(coalition.side.BLUE)
|
||||
local x = 1
|
||||
|
||||
if blueGroups ~= nil then
|
||||
for x, tmpGroup in pairs(blueGroups) do
|
||||
|
||||
|
||||
local index = "GROUP_" .. Group.getID(tmpGroup)
|
||||
-- env.info("adding command for "..index)
|
||||
if GLOBAL_JTAC_RADIO_ADDED[index] == nil then
|
||||
-- env.info("about command for "..index)
|
||||
missionCommands.addCommandForGroup(Group.getID(tmpGroup), "JTAC Status", nil, getJTACStatus, nil)
|
||||
GLOBAL_JTAC_RADIO_ADDED[index] = true
|
||||
-- env.info("Added command for " .. index)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function isInfantry(unit)
|
||||
|
||||
local typeName = unit:getTypeName()
|
||||
|
||||
--type coerce tostring
|
||||
typeName = string.lower(typeName.."")
|
||||
|
||||
local soldierType = { "infantry","paratrooper","stinger","manpad"}
|
||||
|
||||
for key,value in pairs(soldierType) do
|
||||
if string.match(typeName, value) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
-- assume anything that isnt soldier is vehicle
|
||||
function isVehicle(unit)
|
||||
|
||||
if isInfantry(unit) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
|
||||
function getPositionString(unit)
|
||||
|
||||
if JTAC_location == false then
|
||||
return ""
|
||||
end
|
||||
|
||||
local latLngStr = latLngString(unit,3)
|
||||
|
||||
local mgrsString = MGRSString(coord.LLtoMGRS(coord.LOtoLL(unit:getPosition().p)),5)
|
||||
|
||||
return " @ " .. latLngStr .. " - MGRS "..mgrsString
|
||||
|
||||
end
|
||||
|
||||
-- source of Function MIST - https://github.com/mrSkortch/MissionScriptingTools/blob/master/mist.lua
|
||||
function latLngString(unit, acc)
|
||||
|
||||
local lat, lon = coord.LOtoLL(unit:getPosition().p)
|
||||
|
||||
local latHemi, lonHemi
|
||||
if lat > 0 then
|
||||
latHemi = 'N'
|
||||
else
|
||||
latHemi = 'S'
|
||||
end
|
||||
|
||||
if lon > 0 then
|
||||
lonHemi = 'E'
|
||||
else
|
||||
lonHemi = 'W'
|
||||
end
|
||||
|
||||
lat = math.abs(lat)
|
||||
lon = math.abs(lon)
|
||||
|
||||
local latDeg = math.floor(lat)
|
||||
local latMin = (lat - latDeg)*60
|
||||
|
||||
local lonDeg = math.floor(lon)
|
||||
local lonMin = (lon - lonDeg)*60
|
||||
|
||||
-- degrees, decimal minutes.
|
||||
latMin = roundNumber(latMin, acc)
|
||||
lonMin = roundNumber(lonMin, acc)
|
||||
|
||||
if latMin == 60 then
|
||||
latMin = 0
|
||||
latDeg = latDeg + 1
|
||||
end
|
||||
|
||||
if lonMin == 60 then
|
||||
lonMin = 0
|
||||
lonDeg = lonDeg + 1
|
||||
end
|
||||
|
||||
local minFrmtStr -- create the formatting string for the minutes place
|
||||
if acc <= 0 then -- no decimal place.
|
||||
minFrmtStr = '%02d'
|
||||
else
|
||||
local width = 3 + acc -- 01.310 - that's a width of 6, for example.
|
||||
minFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
|
||||
end
|
||||
|
||||
return string.format('%02d', latDeg) .. ' ' .. string.format(minFrmtStr, latMin) .. '\'' .. latHemi .. ' '
|
||||
.. string.format('%02d', lonDeg) .. ' ' .. string.format(minFrmtStr, lonMin) .. '\'' .. lonHemi
|
||||
|
||||
end
|
||||
|
||||
-- source of Function MIST - https://github.com/mrSkortch/MissionScriptingTools/blob/master/mist.lua
|
||||
function MGRSString(MGRS, acc)
|
||||
if acc == 0 then
|
||||
return MGRS.UTMZone .. ' ' .. MGRS.MGRSDigraph
|
||||
else
|
||||
return MGRS.UTMZone .. ' ' .. MGRS.MGRSDigraph .. ' ' .. string.format('%0' .. acc .. 'd', roundNumber(MGRS.Easting/(10^(5-acc)), 0))
|
||||
.. ' ' .. string.format('%0' .. acc .. 'd', roundNumber(MGRS.Northing/(10^(5-acc)), 0))
|
||||
end
|
||||
end
|
||||
-- From http://lua-users.org/wiki/SimpleRound
|
||||
function roundNumber(num, idp)
|
||||
local mult = 10^(idp or 0)
|
||||
return math.floor(num * mult + 0.5) / mult
|
||||
end
|
||||
|
||||
-- add the radio commands
|
||||
if JTAC_jtacStatusF10 == true then
|
||||
timer.scheduleFunction(addRadioCommands, nil, timer.getTime() + 1)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--DEBUG FUNCTIONS - IGNORE
|
||||
--function print_functions(o)
|
||||
--
|
||||
-- for key,value in pairs(getmetatable(o)) do
|
||||
-- env.info(tostring(key) .." ".. tostring(value))
|
||||
-- end
|
||||
--end
|
||||
--
|
||||
--function dump_table(o)
|
||||
-- if type(o) == 'table' then
|
||||
-- local s = '{ '
|
||||
-- for k,v in pairs(o) do
|
||||
-- if type(k) ~= 'number' then k = '"'..k..'"' end
|
||||
-- s = s .. '['..k..'] = ' .. dump_table(v) .. ','
|
||||
-- end
|
||||
-- return s .. '} '
|
||||
-- else
|
||||
-- return tostring(o)
|
||||
-- end
|
||||
--end
|
||||
@ -1,46 +0,0 @@
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- configuration file for the JTAC Autolase framework
|
||||
--
|
||||
-- This configuration is tailored for a mission generated by DCS Liberation
|
||||
-- see https://github.com/dcs-liberation/dcs_liberation
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- JTACAutolase plugin - configuration
|
||||
env.info("DCSLiberation|JTACAutolase plugin - configuration")
|
||||
|
||||
if dcsLiberation then
|
||||
env.info("DCSLiberation|JTACAutolase plugin - dcsLiberation")
|
||||
|
||||
-- specific options
|
||||
local smoke = false
|
||||
local fc3LaserCode = false
|
||||
|
||||
-- retrieve specific options values
|
||||
if dcsLiberation.plugins then
|
||||
env.info("DCSLiberation|JTACAutolase plugin - dcsLiberation.plugins")
|
||||
|
||||
if dcsLiberation.plugins.jtacautolase then
|
||||
env.info("DCSLiberation|JTACAutolase plugin - dcsLiberation.plugins.jtacautolase")
|
||||
smoke = dcsLiberation.plugins.jtacautolase.smoke
|
||||
env.info(string.format("DCSLiberation|JTACAutolase plugin - smoke = %s",tostring(smoke)))
|
||||
|
||||
fc3LaserCode = dcsLiberation.plugins.jtacautolase.fc3LaserCode
|
||||
env.info(string.format("DCSLiberation|JTACAutolase plugin - fc3LaserCode = %s",tostring(fc3LaserCode)))
|
||||
end
|
||||
end
|
||||
|
||||
-- actual configuration code
|
||||
for _, jtac in pairs(dcsLiberation.JTACs) do
|
||||
env.info(string.format("DCSLiberation|JTACAutolase plugin - setting up %s",jtac.dcsUnit))
|
||||
if JTACAutoLase then
|
||||
if fc3LaserCode then
|
||||
-- If fc3LaserCode is enabled in the plugin configuration, force the JTAC
|
||||
-- laser code to 1113 to allow lasing for Su-25 Frogfoots and A-10A Warthogs.
|
||||
jtac.laserCode = 1113
|
||||
end
|
||||
env.info("DCSLiberation|JTACAutolase plugin - calling JTACAutoLase")
|
||||
JTACAutoLase(jtac.dcsUnit, jtac.laserCode, smoke, 'vehicle')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -1,28 +0,0 @@
|
||||
{
|
||||
"nameInUI": "JTAC Autolase",
|
||||
"defaultValue": true,
|
||||
"specificOptions": [
|
||||
{
|
||||
"nameInUI": "Use smoke",
|
||||
"mnemonic": "smoke",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"nameInUI": "Use FC3 laser code (1113)",
|
||||
"mnemonic": "fc3LaserCode",
|
||||
"defaultValue": false
|
||||
}
|
||||
],
|
||||
"scriptsWorkOrders": [
|
||||
{
|
||||
"file": "JTACAutoLase.lua",
|
||||
"mnemonic": "jtacautolase-script"
|
||||
}
|
||||
],
|
||||
"configurationWorkOrders": [
|
||||
{
|
||||
"file": "jtacautolase-config.lua",
|
||||
"mnemonic": "jtacautolase-config"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
[
|
||||
"base",
|
||||
"jtacautolase",
|
||||
"ctld",
|
||||
"skynetiads",
|
||||
"ewrs",
|
||||
"herculescargo",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user