Added new Mission Editor Functions

Crates in Zone
Troop Extract Zones
Radio Beacon Spawn using Mission Editor
This commit is contained in:
Ciaran Fisher 2015-06-17 17:27:50 +01:00
parent f718296a72
commit ae74c4934c
3 changed files with 310 additions and 87 deletions

354
CTLD.lua
View File

@ -10,7 +10,16 @@
See https://github.com/ciribob/DCS-CTLD for a user manual and the latest version
Version: 1.12 - 14/06/2015 - Deployable Radio Beacons with FM radio
Version: 1.13 - 16/06/2015 - Added CountInZone for Cargo
- Added Extract Zone with Flag trigger
TODO Support for Spotter Groups
- Spotter group will deploy smoke at their position with Radio Beacon
- Wont engage unless fired upon
- Report status via F10 Radio
- Report status every 5 minutes or when targets first appear
- Report vague status like 5 armoured vehicles, soldiers and support trucks ??
]]
@ -109,6 +118,7 @@ ctld.dropOffZones = {
{ "dropzone10", "none" },
}
-- ******************** Transports names **********************
-- Use any of the predefined names or set your own ones
@ -356,6 +366,135 @@ function ctld.preLoadTransport(_unitName, _number, _troops)
end
-- Continuously counts the number of crates in a zone and sets the value of the passed in flag
-- to the count amount
-- This means you can trigger actions based on the count and also trigger messages before the count is reached
-- Just pass in the zone name and flag number like so as a single (NOT Continuous) Trigger
-- e.g. ctld.cratesInZone("DropZone1", 5)
function ctld.cratesInZone(_zone, _flagNumber)
local _triggerZone = trigger.misc.getZone(_zone) -- trigger to use as reference position
if _triggerZone == nil then
trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zone, 10)
return
end
local _zonePos = mist.utils.zoneToVec3(_zone)
--ignore side, if crate has been used its discounted from the count
local _crateTables = {ctld.spawnedCratesRED,ctld.spawnedCratesBLUE }
local _crateCount = 0
for _,_crates in pairs(_crateTables) do
for _crateName, _details in pairs(_crates) do
--get crate
local _crate = StaticObject.getByName(_crateName)
--in air seems buggy with crates so if in air is true, get the height above ground and the speed magnitude
if _crate ~= nil and _crate:getLife() > 0
and (_crate:inAir() == false or (land.getHeight(_crate:getPoint()) < 200 and mist.vec.mag(_crate:getVelocity()) < 1.0)) then
local _dist = ctld.getDistance(_crate:getPoint(),_zonePos)
if _dist <= _triggerZone.radius then
_crateCount = _crateCount + 1
end
end
end
end
--set flag stuff
trigger.action.setUserFlag(_flagNumber, _crateCount)
-- env.info("FLAG ".._flagNumber.." crates ".._crateCount)
--retrigger in 5 seconds
timer.scheduleFunction(function(_args)
ctld.cratesInZone(_args[1], _args[2])
end, {_zone,_flagNumber}, timer.getTime() + 5)
end
-- Creates an extraction zone
-- any Soldiers (not vehicles) dropped at this zone by a helicopter will disappear
-- and be added to a running total of soldiers for a set flag number
-- The idea is you can then drop say 20 troops in a zone and trigger an action using the mission editor triggers
-- and the flag value
--
-- The ctld.createExtractZone function needs to be called once in a trigger action do script.
-- if you dont want smoke, pass -1 to the function.
--Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4, NO SMOKE = -1
--
-- e.g. ctld.createExtractZone("extractzone1", 2, -1) will create an extraction zone at trigger zone "extractzone1", store the number of troops dropped at
-- the zone in flag 2 and not have smoke
--
--
--
function ctld.createExtractZone(_zone, _flagNumber, _smoke)
local _triggerZone = trigger.misc.getZone(_zone) -- trigger to use as reference position
if _triggerZone == nil then
trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zone, 10)
return
end
local _zonePos = mist.utils.zoneToVec3(_zone)
trigger.action.setUserFlag(_flagNumber, 0) --start at 0
local _details = {point = _zonePos,name=_zone,smoke=_smoke,flag=_flagNumber, radius=_triggerZone.radius}
table.insert(ctld.extractZones, _details)
if _smoke ~=nil or _smoke > -1 then
local _smokeFunction
_smokeFunction = function (_args)
trigger.action.smoke(_args.point, _args.smoke)
timer.scheduleFunction(_smokeFunction, _args, timer.getTime() + 300)
end
--run local function
_smokeFunction(_details)
end
--refresh in 5 minutes
end
-- Creates a radio beacon on a random UHF - VHF and HF/FM frequency for homing
-- This WILL NOT WORK if you dont add beacon.ogg and beaconsilent.ogg to the mission!!!
-- e.g. ctld.createRadioBeaconAtZone("beaconZone","red", 1440) will create a beacon at trigger zone "beaconZone" for the Red side
-- that will last 1440 minutes (24 hours )
--
-- e.g. ctld.createRadioBeaconAtZone("beaconZoneBlue","blue", 20) will create a beacon at trigger zone "beaconZoneBlue" for the Blue side
-- that will last 20 minutes
function ctld.createRadioBeaconAtZone(_zone, _coalition,_batteryLife)
local _triggerZone = trigger.misc.getZone(_zone) -- trigger to use as reference position
if _triggerZone == nil then
trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zone, 10)
return
end
local _zonePos = mist.utils.zoneToVec3(_zone)
if _coalition == "red" then
ctld.createRadioBeacon(_zonePos,1, 0,false,_batteryLife) --1440
else
ctld.createRadioBeacon(_zonePos,2, 2,false,_batteryLife) --1440
end
end
-- ***************************************************************
-- **************** BE CAREFUL BELOW HERE ************************
@ -669,6 +808,23 @@ function ctld.getPlayerNameOrType(_heli)
end
end
function ctld.inExtractZone(_heli)
local _heliPoint = _heli:getPoint()
for _, _zoneDetails in pairs(ctld.extractZones) do
--get distance to center
local _dist = ctld.getDistance(_heliPoint, _zoneDetails.point)
if _dist <= _zoneDetails.radius then
return _zoneDetails
end
end
return false
end
function ctld.deployTroops(_heli, _troops)
@ -679,19 +835,39 @@ function ctld.deployTroops(_heli, _troops)
if _onboard.troops ~= nil and #_onboard.troops.units > 0 then
local _droppedTroops = ctld.spawnDroppedGroup(_heli:getPoint(), _onboard.troops, false)
-- check we're not in extract zone
local _extractZone = ctld.inExtractZone(_heli)
if _heli:getCoalition() == 1 then
if _extractZone == false then
local _droppedTroops = ctld.spawnDroppedGroup(_heli:getPoint(), _onboard.troops, false)
if _heli:getCoalition() == 1 then
table.insert(ctld.droppedTroopsRED, _droppedTroops:getName())
else
table.insert(ctld.droppedTroopsBLUE, _droppedTroops:getName())
end
ctld.inTransitTroops[_heli:getName()].troops = nil
trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " dropped troops from " .. _heli:getTypeName() .. " into combat", 10)
table.insert(ctld.droppedTroopsRED, _droppedTroops:getName())
else
--extract zone!
local _droppedCount = trigger.misc.getUserFlag(_extractZone.flag)
_droppedCount = (#_onboard.troops.units) +_droppedCount
trigger.action.setUserFlag(_extractZone.flag,_droppedCount)
ctld.inTransitTroops[_heli:getName()].troops = nil
trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " dropped troops from " .. _heli:getTypeName() .. " into ".._extractZone.name, 10)
table.insert(ctld.droppedTroopsBLUE, _droppedTroops:getName())
end
ctld.inTransitTroops[_heli:getName()].troops = nil
trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " dropped troops from " .. _heli:getTypeName() .. " into combat", 10)
end
else
if _onboard.vehicles ~= nil and #_onboard.vehicles.units > 0 then
@ -1308,7 +1484,7 @@ function ctld.getFOBPositionString(_fob)
local _latLngStr = mist.tostringLL(_lat, _lon, 3, false)
-- local _mgrsString = mist.tostringMGRS(coord.LLtoMGRS(coord.LOtoLL(_fob:getPosition().p)), 5)
-- local _mgrsString = mist.tostringMGRS(coord.LLtoMGRS(coord.LOtoLL(_fob:getPosition().p)), 5)
local _message = _latLngStr
@ -1594,7 +1770,7 @@ end
--spawns a radio beacon made up of two units,
-- one for VHF and one for UHF
-- The units are set to to NOT engage
function ctld.createRadioBeacon(_point, _coalition, _country,_isFOB)
function ctld.createRadioBeacon(_point, _coalition, _country,_isFOB,_batteryTime)
local _uhfGroup = ctld.spawnRadioBeaconUnit(_point, _country, "UHF")
local _vhfGroup = ctld.spawnRadioBeaconUnit(_point, _country, "VHF")
@ -1603,7 +1779,13 @@ function ctld.createRadioBeacon(_point, _coalition, _country,_isFOB)
local _freq = ctld.generateADFFrequencies()
--create timeout
local _battery = timer.getTime()+ (ctld.deployedBeaconBattery *60)
local _battery
if _batteryTime == nil then
_battery = timer.getTime()+ (ctld.deployedBeaconBattery *60)
else
_battery = timer.getTime()+ (_batteryTime *60)
end
local _lat, _lon = coord.LOtoLL(_point)
@ -1678,7 +1860,7 @@ function ctld.generateADFFrequencies()
local _fm = table.remove(ctld.freeFMFrequencies,math.random(#ctld.freeFMFrequencies))
table.insert(ctld.usedFMFrequencies,_fm)
return {uhf=_uhf,vhf=_vhf,fm=_fm}
return {uhf=_uhf,vhf=_vhf,fm=_fm}
---return {uhf=_uhf,vhf=_vhf}
end
@ -1756,86 +1938,86 @@ function ctld.updateRadioBeacon(_beaconDetails)
end
--fobs have unlimited battery life
-- if _battery ~= -1 then
-- _text = _text.." "..mist.utils.round(_batLife).." seconds of battery"
-- end
-- if _battery ~= -1 then
-- _text = _text.." "..mist.utils.round(_batLife).." seconds of battery"
-- end
for _,_radio in pairs(_radioLoop) do
-- if _radio.silent then
-- local _setFrequency = {
-- ["enabled"] = true,
-- ["auto"] = false,
-- ["id"] = "WrappedAction",
-- ["number"] = 1, -- first task
-- ["params"] = {
-- ["action"] = {
-- ["id"] = "SetFrequency",
-- ["params"] = {
-- ["modulation"] = _radio.mode, -- 0 is AM 1 is FM --if FM you cant read the message... might be the only fix to stop FC3 aircraft hearing it... :(
-- ["frequency"] = _radio.freq,
-- },
-- },
-- },
-- }
--
--
-- local _radioText = _text
-- local _sound = ctld.radioSound
-- --dont show radio text on UHF as that should hide it from FC3 aircraft
-- if _radio.silent then
-- _radioText = ""
-- _sound = ctld.radioSoundFC3
-- end
--
--
-- local _setupDetails = {
-- ["enabled"] = true,
-- ["auto"] = false,
-- ["id"] = "WrappedAction",
-- ["number"] = 2, -- second task
-- ["params"] = {
-- ["action"] = {
-- ["id"] = "TransmitMessage",
-- ["params"] = {
-- ["loop"] = true, --false works too
-- ["subtitle"] = "", --_text
-- ["duration"] = 60, -- reset every 60 seconds --used to have timer.getTime() +60
-- ["file"] = _sound,
-- },
-- },
-- }
-- }
--
-- local _groupController = _radio.group:getController()
--
-- --reset!
-- _groupController:resetTask()
--
-- _groupController:setTask(_setFrequency)
-- _groupController:setTask(_setupDetails)
--
-- --Make the unit NOT engage as its simulating a radio...!
--
--
-- --env.info("Radio Beacon: ".. _text)
-- else
-- Above function doesnt work for simulating VHF in multiplayer but DOES in single player.... WHY DCS WHY!?!?!
-- if _radio.silent then
-- local _setFrequency = {
-- ["enabled"] = true,
-- ["auto"] = false,
-- ["id"] = "WrappedAction",
-- ["number"] = 1, -- first task
-- ["params"] = {
-- ["action"] = {
-- ["id"] = "SetFrequency",
-- ["params"] = {
-- ["modulation"] = _radio.mode, -- 0 is AM 1 is FM --if FM you cant read the message... might be the only fix to stop FC3 aircraft hearing it... :(
-- ["frequency"] = _radio.freq,
-- },
-- },
-- },
-- }
--
--
-- local _radioText = _text
-- local _sound = ctld.radioSound
-- --dont show radio text on UHF as that should hide it from FC3 aircraft
-- if _radio.silent then
-- _radioText = ""
-- _sound = ctld.radioSoundFC3
-- end
--
--
-- local _setupDetails = {
-- ["enabled"] = true,
-- ["auto"] = false,
-- ["id"] = "WrappedAction",
-- ["number"] = 2, -- second task
-- ["params"] = {
-- ["action"] = {
-- ["id"] = "TransmitMessage",
-- ["params"] = {
-- ["loop"] = true, --false works too
-- ["subtitle"] = "", --_text
-- ["duration"] = 60, -- reset every 60 seconds --used to have timer.getTime() +60
-- ["file"] = _sound,
-- },
-- },
-- }
-- }
--
-- local _groupController = _radio.group:getController()
--
-- --reset!
-- _groupController:resetTask()
--
-- _groupController:setTask(_setFrequency)
-- _groupController:setTask(_setupDetails)
--
-- --Make the unit NOT engage as its simulating a radio...!
--
--
-- --env.info("Radio Beacon: ".. _text)
-- else
-- Above function doesnt work for simulating VHF in multiplayer but DOES in single player.... WHY DCS WHY!?!?!
local _groupController = _radio.group:getController()
local _groupController = _radio.group:getController()
local _sound = ctld.radioSound
if _radio.silent then
_sound = ctld.radioSoundFC3
end
_groupController:setOption(AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.WEAPON_HOLD)
local _sound = ctld.radioSound
if _radio.silent then
_sound = ctld.radioSoundFC3
end
_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
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
--
--
end
return true
@ -2866,7 +3048,7 @@ function ctld.addF10MenuOptions()
ctld.addJTACRadioCommand(1)
end
end
)
)
timer.scheduleFunction(ctld.addF10MenuOptions, nil, timer.getTime() + 5)
end
@ -3704,6 +3886,8 @@ ctld.freeFMFrequencies = {}
--used to lookup what the crate will contain
ctld.crateLookupTable = {}
ctld.extractZones = {} -- stored extract zones
-- Remove intransit troops when heli / cargo plane dies
--ctld.eventHandler = {}
--function ctld.eventHandler:onEvent(_event)

View File

@ -26,9 +26,13 @@ The script supports:
* BRMD-2
* FOB Building
* Homing using FM Radio Beacon
* Easy Beacon Creation using Mission Editor
* Radio Beacon Deployment
* Ability to deploy a homing beacon that the A10C, Ka-50, Mi-8 and Huey can home on
* Pre loading of units into AI vehicles via a DO SCRIPT
* Mission Editor Trigger functions - They store the numbers in flags for use by triggers
* Count Crates in Zone
* Count soldiers extracted to a zone (the soldiers disappear)
A complete test mission is included.
@ -149,7 +153,8 @@ Example showing what happens if you dont have enough crates:
**Make sure that after making any changes to the script you remove and re-add the script to the mission. **
###Other Script Functions
###Mission Editor Script Functions
####Preload Troops into Transport
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
* number of troops / vehicles to load
@ -159,9 +164,10 @@ If you try to load vehicles into anything other than a unit listed in ```ctld.ve
```lua
ctld.preLoadTransport("helicargo1", 10,true)
```
####Create Extractable Groups without Pickup Zone
You can also make existing mission editor groups extractable by adding their group name to the ```ctld.extractableGroups``` list
####Spawn Extractable Groups without Pickup Zone
You can also spawn extractable infantry groups at a specified trigger zone using the code below.
The parameters are:
@ -178,6 +184,39 @@ or
ctld.spawnGroupAtTrigger("blue", 5, "spawnTrigger2", 2000)
```
####Create Radio Beacon at Zone
A radio beacon can be spawned at any zone by adding a Trigger Once with a Time More set to any time after the CTLD script has been loaded and a DO SCRIPT action of ```ctld.createRadioBeaconAtZone("beaconZone","red", 1440)```
Where ```"beaconZone"``` is the name of a Trigger Zone added using the mission editor, ```"red"``` is the side to add the beacon for and ```1440``` the time in minutes for the beacon to broadcast for.
```ctld.createRadioBeaconAtZone("beaconZoneBlue","blue", 20)``` will create a beacon at trigger zone named ```"beaconZoneBlue"``` for the Blue coalition that will last 20 minutes.
Spawned beacons will broadcast on HF/FM, UHF and VHF until their battery runs out and can be used by most aircraft for ADF. The frequencies used on each frequency will be random.
**Again, beacons will not work if beacon.ogg and beaconsilent.ogg are not in the mission!**
####Create Extract Zone
An extact zone is a zone where troops (not vehicles) can be dropped by transports and used to trigger another action based on the number of troops dropped. The radius of the zone sets how big the extract zone will be.
When troops are dropped, the troops disappear and the number of troops dropped added to the flag number configured by the function. This means you can make a trigger such that 10 troops have to be rescued and dropped at the extract zone, and when this happens you can trigger another action.
An Extraction zone can be created by adding a Trigger Once with a Time More set to any time after the CTLD script has been loaded and a DO SCRIPT action of ```ctld.createExtractZone("extractzone1", 2, -1)```
Where ```"extractzone1"``` is the name of a Trigger Zone added using the mission editor, ```2``` is the flag where we want the total number of troops dropped in a zone added and ```-1``` the smoke colour.
The settings for smoke are: Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4, NO SMOKE = -1
####Create Crate Drop Zone
A crate drop zone is a zone where the number of crates in a zone in counted every 5 seconds and the current amount stored in a flag specified by the script.
The flag number can be used to trigger other actions added using the mission editor, i.e only activate vehicles once a certain number of crates have been dropped in a zone. The radius of the zone in the mission editor sets how big the crate drop zone will be.
**The script doesnt differentiate between crates, any crate spawned by the CTLD script can be dropped there and it will count as 1 but if a crate is unpacked in a zone it will no longer count!**
A crate drop zone can be added to any zone by adding a Trigger Once with a Time More set to any time after the CTLD script has been loaded and a DO SCRIPT action of ```ctld.cratesInZone("crateZone",1)```
Where ```"crateZone"``` is the name of a Trigger Zone added using the mission editor, and ```1``` is the number of the flag where the current number of crates in the zone will be stored.
####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.

Binary file not shown.