diff --git a/CTLD.lua b/CTLD.lua index 55ab84d..f38c111 100644 --- a/CTLD.lua +++ b/CTLD.lua @@ -6,18 +6,20 @@ Supports some of the original CTTS functionality such as AI auto troop load and unload as well as group spawning and preloading of troops into units. + Supports deployment of Auto Lasing JTAC to the field + See https://github.com/ciribob/DCS-CTLD for a user manual and the latest version + Version: 1.01 - 16/05/2015 ]] -ctld = {} +ctld = {} -- DONT REMOVE! -- ************************************************************************ -- ********************* USER CONFIGURATION ****************************** -- ************************************************************************ - -ctld.disableAllSmoke = false -- if true, all smoke is diabled regardless of settings below. Leave false to respect settings below +ctld.disableAllSmoke = false -- if true, all smoke is diabled at pickup and drop off zones regardless of settings below. Leave false to respect settings below ctld.enableCrates = true -- if false, Helis will not be able to spawn or unpack crates so will be normal CTTS ctld.enableSmokeDrop = true -- if false, helis and c-130 will not be able to drop smoke @@ -28,32 +30,30 @@ ctld.maximumMoveDistance = 1000 -- max distance for troops to move from drop poi ctld.numberOfTroops = 10 -- default number of troops to load on a transport heli or C-130 -ctld.vehiclesForTransport = { "M1045 HMMWV TOW", "M1043 HMMWV Armament" } -- vehicles to load onto c130 +ctld.vehiclesForTransport = { "M1045 HMMWV TOW", "M1043 HMMWV Armament" } -- vehicles to load onto c130 ctld.spawnRPGWithCoalition = true --spawns a friendly RPG unit with Coalition forces + -- ***************** JTAC CONFIGURATION ***************** ctld.JTAC_LIMIT_RED = 5 -- max number of JTAC Crates for the RED Side - ctld.JTAC_LIMIT_BLUE = 5 -- max number of JTAC Crates for the BLUE Side -ctld.JTAC_dropEnabled = true -- allow JTAC SPAWN +ctld.JTAC_dropEnabled = true -- allow JTAC Crate spawn from F10 menu -ctld.JTAC_maxDistance = 2500 -- How far a JTAC can "see" in meters (with Line of Sight) +ctld.JTAC_maxDistance = 4000 -- How far a JTAC can "see" in meters (with Line of Sight) -ctld.JTAC_smokeOn_RED = true -- enables marking of target with smoke - -ctld.JTAC_smokeOn_BLUE = true -- enables marking of target with smoke - -ctld.JTAC_smokeColour_RED = 1 -- RED side smoke colour -- Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4 +ctld.JTAC_smokeOn_RED = true -- enables marking of target with smoke for RED forces +ctld.JTAC_smokeOn_BLUE = true -- enables marking of target with smoke for BLUE forces +ctld.JTAC_smokeColour_RED = 4 -- RED side smoke colour -- Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4 ctld.JTAC_smokeColour_BLUE = 1 -- BLUE side smoke colour -- Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4 ctld.JTAC_jtacStatusF10 = true -- enables F10 JTAC Status menu -ctld.JTAC_location = true -- shows location in JTAC message +ctld.JTAC_location = true -- shows location of target in JTAC message ctld.JTAC_lock = "all" -- "vehicle" OR "troop" OR "all" forces JTAC to only lock vehicles or troops or all ground units @@ -193,6 +193,7 @@ ctld.extractableGroups = { -- ************** Logistics UNITS FOR CRATE SPAWNING ****************** -- Use any of the predefined names or set your own ones +-- When a logistic unit is destroyed, you will no longer be able to spawn crates ctld.logisticUnits = { "logistic1", @@ -208,38 +209,20 @@ ctld.logisticUnits = { } -- ************** UNITS ABLE TO TRANSPORT VEHICLES ****************** - +-- Add the model name of the unit that you want to be able to transport and deploy vehicles +-- units db has all the names or you can extract a mission.miz file by making it a zip and looking +-- in the contained mission file ctld.vehicleTransportEnabled = { "C-130", } - --- *************************************************************** --- **************** BE CAREFUL BELOW HERE ************************ --- *************************************************************** - -assert(mist ~= nil, "\n\n** HEY MISSION-DESIGNER! **\n\nMiST has not been loaded!\n\nMake sure MiST 3.6 or higher is running\n*before* running this script!\n") - -ctld.addedTo = {} -ctld.spawnedCratesRED = {} -- use to store crates that have been spawned -ctld.spawnedCratesBLUE = {} -- use to store crates that have been spawned - -ctld.droppedTroopsRED = {} -- stores dropped troop groups -ctld.droppedTroopsBLUE = {} -- stores dropped troop groups - -ctld.droppedVehiclesRED = {} -- stores vehicle groups for c-130 / hercules -ctld.droppedVehiclesBLUE = {} -- stores vehicle groups for c-130 / hercules - -ctld.inTransitTroops = {} - -ctld.completeHawkSystems = {} -- stores complete spawned groups from multiple crates - +-- ************** SPAWNABLE CRATES ****************** -- Weights must be unique as we use the weight to change the cargo to the correct unit -- when we unpack -- ctld.spawnableCrates = { - -- name of the sub menu for spawning crates + -- name of the sub menu on F10 for spawning crates ["Ground Forces"] = { --crates you can spawn @@ -248,7 +231,7 @@ ctld.spawnableCrates = { -- unit is the model name of the unit to spawn { weight = 1400, desc = "HMMWV - TOW", unit = "M1045 HMMWV TOW" }, { weight = 1200, desc = "HMMWV - MG", unit = "M1043 HMMWV Armament" }, - { weight = 1100, desc = "HMMWV - JTAC", unit = "Hummer" }, -- used as jtac, not on the crate list if JTAC is disabled + { weight = 1100, desc = "HMMWV - JTAC", unit = "Hummer" }, -- used as jtac and unarmed, not on the crate list if JTAC is disabled { weight = 200, desc = "2B11 Mortar", unit = "2B11 mortar" }, }, @@ -263,69 +246,13 @@ ctld.spawnableCrates = { } - ---used to lookup what the crate will contain -ctld.crateLookupTable = {} - -for _subMenuName, _crates in pairs(ctld.spawnableCrates) do - - for _, _crate in pairs(_crates) do - -- convert number to string otherwise we'll have a pointless giant - -- table. String means 'hashmap' so it will only contain the right number of elements - ctld.crateLookupTable[tostring(_crate.weight)] = _crate - end -end - - - - ---sort out pickup zones -for _, _zone in pairs(ctld.pickupZones) do - - local _zoneName = _zone[1] - local _zoneColor = _zone[2] - - if _zoneColor == "green" then - _zone[2] = trigger.smokeColor.Green - elseif _zoneColor == "red" then - _zone[2] = trigger.smokeColor.Red - elseif _zoneColor == "white" then - _zone[2] = trigger.smokeColor.White - elseif _zoneColor == "orange" then - _zone[2] = trigger.smokeColor.Orange - elseif _zoneColor == "blue" then - _zone[2] = trigger.smokeColor.Blue - else - _zone[2] = -1 -- no smoke colour - end -end - - ---- - Sort out extractable groups - -for _, _groupName in pairs(ctld.extractableGroups) do - - local _group = Group.getByName(_groupName) - - if _group ~= nil then - - if _group:getCoalition() == 1 then - - table.insert(ctld.droppedTroopsRED, _group:getName()) - else - - table.insert(ctld.droppedTroopsBLUE, _group:getName()) - end - end -end - - ------------- EXTERNAL FUNCTIONS FOR MISSION EDITOR ----------- - +-- *************************************************************** +-- **************** Mission Editor Functions ********************* +-- *************************************************************** ----------------------------------------------------------------- --- Spawn group at a trigger and sets them as extractable. Usage: +-- Spawn group at a trigger and set them as extractable. Usage: -- ctld.spawnGroupAtTrigger("groupside", number, "triggerName", radius) -- Variables: -- "groupSide" = "red" for Russia "blue" for USA @@ -399,28 +326,12 @@ end +-- *************************************************************** +-- **************** BE CAREFUL BELOW HERE ************************ +-- *************************************************************** ---------------- INTERNAL FUNCTIONS ---------------- --- Remove intransit troops when heli / cargo plane dies -ctld.eventHandler = {} -function ctld.eventHandler:onEvent(_event) - - if _event == nil or _event.initiator == nil then - env.info("CTLD null event") - elseif _event.id == 9 then - -- Pilot dead - ctld.inTransitTroops[_event.initiator:getName()] = nil - - elseif world.event.S_EVENT_EJECTION == _event.id or _event.id == 8 then - -- env.info("Event unit - Pilot Ejected or Unit Dead") - ctld.inTransitTroops[_event.initiator:getName()] = nil - - -- env.info(_event.initiator:getName()) - end - -end - function ctld.getTransportUnit(_unitName) if _unitName == nil then @@ -503,7 +414,7 @@ function ctld.spawnCrate(_args) end if _limitHit then - ctld.displayMessageToGroup(_heli, "No more JTAC Crates Left!") + ctld.displayMessageToGroup(_heli, "No more JTAC Crates Left!",10) return end @@ -901,6 +812,7 @@ end function ctld.displayMessageToGroup(_unit, _text, _time) trigger.action.outTextForGroup(_unit:getGroup():getID(), _text, _time) + end function ctld.getCratesAndDistance(_heli) @@ -1688,7 +1600,7 @@ function ctld.addF10MenuOptions() local _groupId = _unit:getGroup():getID() - if ctld.addedTo[_groupId] == nil and _unit:getPlayerName() ~= nil then + if ctld.addedTo[tostring(_groupId)] == nil and _unit:getPlayerName() ~= nil then missionCommands.addSubMenuForGroup(_groupId, "Troop Transport") missionCommands.addCommandForGroup(_groupId, "Load / Unload Troops", { "Troop Transport" }, ctld.loadUnloadTroops, { _unitName,true }) @@ -1736,14 +1648,14 @@ function ctld.addF10MenuOptions() end end - ctld.addedTo[_groupId] = true + ctld.addedTo[tostring(_groupId)] = true end else -- env.info(string.format("unit nil %s",_unitName)) end end - if ctld.JTAC_dropEnabled then + if ctld.JTAC_jtacStatusF10 then -- get all BLUE players ctld.addJTACRadioCommand(coalition.side.BLUE) @@ -1765,10 +1677,10 @@ function ctld.addJTACRadioCommand(_side) local _groupId = _playerUnit:getGroup():getID() -- env.info("adding command for "..index) - if ctld.jtacRadioAdded[_groupId] == nil then + if ctld.jtacRadioAdded[tostring(_groupId)] == nil then -- env.info("about command for "..index) missionCommands.addCommandForGroup(_groupId, "JTAC Status", nil, ctld.getJTACStatus, _playerUnit:getCoalition()) - ctld.jtacRadioAdded[_groupId] = true + ctld.jtacRadioAdded[tostring(_groupId)] = true -- env.info("Added command for " .. index) end @@ -1803,6 +1715,7 @@ ctld.jtacUnits = {} -- list of JTAC units for f10 command ctld.jtacCurrentTargets = {} ctld.jtacRadioAdded = {} --keeps track of who's had the radio command added ctld.jtacGeneratedLaserCodes = {} -- keeps track of generated codes, cycles when they run out +ctld.jtacLaserPointCodes = {} function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour) @@ -2285,7 +2198,7 @@ function ctld.isInfantry(_unit) --type coerce tostring _typeName = string.lower(_typeName .."") - local _soldierType = { "infantry","paratrooper","stinger","manpad"} + local _soldierType = { "infantry","paratrooper","stinger","manpad","mortar"} for _key, _value in pairs(_soldierType) do if string.match(_typeName, _value) then @@ -2380,6 +2293,96 @@ function ctld.getPositionString(_unit) end +-- ***************** SETUP SCRIPT **************** + +assert(mist ~= nil, "\n\n** HEY MISSION-DESIGNER! **\n\nMiST has not been loaded!\n\nMake sure MiST 3.6 or higher is running\n*before* running this script!\n") + +ctld.addedTo = {} +ctld.spawnedCratesRED = {} -- use to store crates that have been spawned +ctld.spawnedCratesBLUE = {} -- use to store crates that have been spawned + +ctld.droppedTroopsRED = {} -- stores dropped troop groups +ctld.droppedTroopsBLUE = {} -- stores dropped troop groups + +ctld.droppedVehiclesRED = {} -- stores vehicle groups for c-130 / hercules +ctld.droppedVehiclesBLUE = {} -- stores vehicle groups for c-130 / hercules + +ctld.inTransitTroops = {} + +ctld.completeHawkSystems = {} -- stores complete spawned groups from multiple crates + + +--used to lookup what the crate will contain +ctld.crateLookupTable = {} + +-- Remove intransit troops when heli / cargo plane dies +ctld.eventHandler = {} +function ctld.eventHandler:onEvent(_event) + + if _event == nil or _event.initiator == nil then + env.info("CTLD null event") + elseif _event.id == 9 then + -- Pilot dead + ctld.inTransitTroops[_event.initiator:getName()] = nil + + elseif world.event.S_EVENT_EJECTION == _event.id or _event.id == 8 then + -- env.info("Event unit - Pilot Ejected or Unit Dead") + ctld.inTransitTroops[_event.initiator:getName()] = nil + + -- env.info(_event.initiator:getName()) + end + +end + +-- create crate lookup table +for _subMenuName, _crates in pairs(ctld.spawnableCrates) do + + for _, _crate in pairs(_crates) do + -- convert number to string otherwise we'll have a pointless giant + -- table. String means 'hashmap' so it will only contain the right number of elements + ctld.crateLookupTable[tostring(_crate.weight)] = _crate + end +end + + +--sort out pickup zones +for _, _zone in pairs(ctld.pickupZones) do + + local _zoneName = _zone[1] + local _zoneColor = _zone[2] + + if _zoneColor == "green" then + _zone[2] = trigger.smokeColor.Green + elseif _zoneColor == "red" then + _zone[2] = trigger.smokeColor.Red + elseif _zoneColor == "white" then + _zone[2] = trigger.smokeColor.White + elseif _zoneColor == "orange" then + _zone[2] = trigger.smokeColor.Orange + elseif _zoneColor == "blue" then + _zone[2] = trigger.smokeColor.Blue + else + _zone[2] = -1 -- no smoke colour + end +end + + +-- Sort out extractable groups +for _, _groupName in pairs(ctld.extractableGroups) do + + local _group = Group.getByName(_groupName) + + if _group ~= nil then + + if _group:getCoalition() == 1 then + table.insert(ctld.droppedTroopsRED, _group:getName()) + else + table.insert(ctld.droppedTroopsBLUE, _group:getName()) + end + end +end + + -- Scheduled functions (run cyclically) timer.scheduleFunction(ctld.refreshSmoke, nil, timer.getTime() + 5) @@ -2396,6 +2399,7 @@ env.info("Generating Laser Codes") ctld.generateLaserCode() env.info("Generated Laser Codes") +env.info("CTLD READY") --DEBUG FUNCTION -- for key, value in pairs(getmetatable(_spawnedCrate)) do -- env.info(tostring(key)) diff --git a/README.md b/README.md index 926f087..c2f5bbf 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ The script supports: * HAWK system can also be rearmed after construction by dropping another Hawk Launcher nearby and unpacking * HMMWV TOW * HMMWV MG + * HMMWV JTAC - Will Auto Lase and mark targets with smoke if enabled * Mortar * MANPAD * Pre loading of units into AI vehicles via a DO SCRIPT @@ -39,6 +40,65 @@ An example is shown below: ![alt text](http://i1056.photobucket.com/albums/t379/cfisher881/Launcher%202015-05-10%2015-25-14-00_zpsmoirc3nz.png~original "Script Setup") +###Script Configuration +The script has lots of configuration options that can be used to futher customise the behaviour. +```lua +-- ************************************************************************ +-- ********************* USER CONFIGURATION ****************************** +-- ************************************************************************ +ctld.disableAllSmoke = false -- if true, all smoke is diabled at pickup and drop off zones regardless of settings below. Leave false to respect settings below +ctld.enableCrates = true -- if false, Helis will not be able to spawn or unpack crates so will be normal CTTS +ctld.enableSmokeDrop = true -- if false, helis and c-130 will not be able to drop smoke + +ctld.maxExtractDistance = 125 -- max distance from vehicle to troops to allow a group extraction +ctld.maximumDistanceLogistic = 200 -- max distance from vehicle to logistics to allow a loading or spawning operation +ctld.maximumSearchDistance = 4000 -- max distance for troops to search for enemy +ctld.maximumMoveDistance = 1000 -- max distance for troops to move from drop point if no enemy is nearby + +ctld.numberOfTroops = 10 -- default number of troops to load on a transport heli or C-130 + +ctld.vehiclesForTransport = { "M1045 HMMWV TOW", "M1043 HMMWV Armament" } -- vehicles to load onto c130 + +ctld.spawnRPGWithCoalition = true --spawns a friendly RPG unit with Coalition forces +``` + +To change what units can be dropped from crates modify the spawnable crates section + +```lua + +-- ************** SPAWNABLE CRATES ****************** +-- Weights must be unique as we use the weight to change the cargo to the correct unit +-- when we unpack +-- +ctld.spawnableCrates = { + + -- name of the sub menu on F10 for spawning crates + ["Ground Forces"] = { + + --crates you can spawn + -- weight in KG + -- Desc is the description on the F10 MENU + -- unit is the model name of the unit to spawn + { weight = 1400, desc = "HMMWV - TOW", unit = "M1045 HMMWV TOW" }, + { weight = 1200, desc = "HMMWV - MG", unit = "M1043 HMMWV Armament" }, + { weight = 1100, desc = "HMMWV - JTAC", unit = "Hummer" }, -- used as jtac and unarmed, not on the crate list if JTAC is disabled + { weight = 200, desc = "2B11 Mortar", unit = "2B11 mortar" }, + }, + + ["AA Crates"] = { + + { weight = 210, desc = "MANPAD", unit = "Stinger manpad" }, + { weight = 1000, desc = "HAWK Launcher", unit = "Hawk ln" }, + { weight = 1010, desc = "HAWK Search Radar", unit = "Hawk sr" }, + { weight = 1020, desc = "HAWK Track Radar", unit = "Hawk tr" }, + }, + + +} +``` + +**Make sure that after making any changes to the script you remove and re-add the script to the mission. ** + ###Other Script Functions You can also preload troops into AI transports once the CTLD script has been loaded, instead of having the AI enter a pickup zone, using the code below where the parameters are: * Pilot name of the unit @@ -68,6 +128,94 @@ or ctld.spawnGroupAtTrigger("blue", 5, "spawnTrigger2", 2000) ``` +####JTAC Automatic Targeting and Laser +This script has been merged with https://github.com/ciribob/DCS-JTACAutoLaze . JTACs can either be deployed by Helicopters and configured with the options in the script or pre added to the mission. By default each side can drop 5 JTACs. + +The JTAC Script configuration is shown below and can easily be disabled using the ```ctld.JTAC_dropEnabled``` option. + +```lua +-- ***************** JTAC CONFIGURATION ***************** +ctld.JTAC_LIMIT_RED = 5 -- max number of JTAC Crates for the RED Side +ctld.JTAC_LIMIT_BLUE = 5 -- max number of JTAC Crates for the BLUE Side + +ctld.JTAC_dropEnabled = true -- allow JTAC Crate spawn from F10 menu + +ctld.JTAC_maxDistance = 4000 -- How far a JTAC can "see" in meters (with Line of Sight) + +ctld.JTAC_smokeOn_RED = true -- enables marking of target with smoke for RED forces +ctld.JTAC_smokeOn_BLUE = true -- enables marking of target with smoke for BLUE forces + +ctld.JTAC_smokeColour_RED = 4 -- RED side smoke colour -- Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4 +ctld.JTAC_smokeColour_BLUE = 1 -- BLUE side smoke colour -- Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4 + +ctld.JTAC_jtacStatusF10 = false -- enables F10 JTAC Status menu + +ctld.JTAC_location = false -- shows location of target in JTAC message + +ctld.JTAC_lock = "all" -- "vehicle" OR "troop" OR "all" forces JTAC to only lock vehicles or troops or all ground units + +``` + +The 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. + +The JTACs can be configured globally to target only vehicles or troops or all ground targets. + +***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. There is also an F10 menu option for units allowing the JTAC(s) to report their current status but if a JTAC is down it won't report in. + +To add JTACS to the mission using the editor place a JTAC unit on the map 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. + +Run the code below as a DO SCRIPT at the start of the mission, or after a delay if you prefer to activate a mission JTAC. + +**JTAC HMMWV units deployed by unpacking a crate will automatically activate and begin searching for targets immediately.** + +```lua +ctld.JTACAutoLase('JTAC1', 1688) +``` + +Where JTAC1 is the Group name of the JTAC Group with one and only one JTAC unit and the 1688 is the Laser code. + +You can also override global settings set in the script like so: + +```lua +ctld.JTACAutoLase('JTAC1', 1688, false,"all") +``` +This means no smoke marks for this JTAC and it will target all ground troops + +```lua +ctld.JTACAutoLase('JTAC1', 1688, true,"vehicle") +``` +This smoke marks for this JTAC and it will target ONLY ground vehicles + +```lua +ctld.JTACAutoLase('JTAC1', 1688, true,"troop") +``` +This means smoke marks are enabled for this JTAC and it will target ONLY ground troops + +```lua +ctld.JTACAutoLase('JTAC1', 1688, true,"troop",1) +``` +This means smoke marks are enabled for this JTAC and it will target ONLY ground troops AND smoke colour will be Red + +```lua +ctld.JTACAutoLase('JTAC1', 1688, true,"troop",0) +``` +This means smoke marks are enabled for this JTAC and it will target ONLY ground troops AND smoke colour will be Green + +```lua +ctld.JTACAutoLase('JTAC1', 1688, true,"all", 4) +``` +This means no smoke marks for this JTAC and it will target all ground troops AND mark with Blue smoke + +Smoke colours are: Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4 + +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. ###Pickup and Dropoff Zones Setup Pickup zones are used by transport aircraft and helicopters to load troops and vehicles. A transport unit must be inside of the radius of the trigger in order to load troops and vehicles. diff --git a/test-mission-night.miz b/test-mission-night.miz index 2be8ef3..4b3f3dd 100644 Binary files a/test-mission-night.miz and b/test-mission-night.miz differ diff --git a/test-mission.miz b/test-mission.miz index 264b96a..488d7c9 100644 Binary files a/test-mission.miz and b/test-mission.miz differ