14 Commits

Author SHA1 Message Date
Ciaran Fisher
f70c6a7131 Fixed HAWK
Increased default number of launchers
2021-11-13 22:23:45 +00:00
Ciaran Fisher
3717f0f11b Updated version and mission 2021-11-13 21:32:15 +00:00
Ciaran Fisher
1911c608bb Fixed HAWK not firing
Thanks to Grimes!
2021-11-13 21:18:41 +00:00
Ciaran Fisher
1ddaabcfbb Added HAWK CWAR
Added Hawk CWAR - thanks to PaulBrockbank
2021-08-27 08:17:18 +01:00
Ciaran Fisher
381a124a86 Tidy Up Mission 2021-06-27 17:55:17 +01:00
Ciaran Fisher
1a55b1d52e Tidy up Repo 2021-06-27 17:54:37 +01:00
Ciaran Fisher
c48ab69e20 Merge pull request #64 from VEAF/jtac-stop-resume
reproduced edits by guimcdo
2021-06-24 08:33:45 +01:00
David Pierron
ec0cee3671 reproduced edits by guimcdo 2021-06-23 15:41:50 +02:00
Ciaran Fisher
627b8323d4 Merge pull request #62 from VEAF/JTAC-talk-over-SRS
Jtac talk over srs
2021-06-22 08:15:38 +01:00
David Pierron
853ae0e727 Made a reference to DCS-SimpleTextToSpeech instead of including it 2021-06-22 09:05:26 +02:00
David Pierron
4ce0c1f656 rebase from Origin/master (Ciribob) and edited 2021-06-21 18:30:29 +02:00
David Pierron
821dc1e13c Merge branch 'master' into JTAC-talk-over-SRS 2021-06-21 18:24:02 +02:00
Ciaran Fisher
4b25289eb5 Merge pull request #63 from ciribob/pr-61-local
Pr 61 local
2021-06-19 14:11:39 +01:00
David Pierron
0668e12c39 JTAC now talks over SRS 2021-06-17 18:37:44 +02:00
11 changed files with 858 additions and 247 deletions

Binary file not shown.

136
CTLD.lua
View File

@@ -15,7 +15,7 @@
- mvee - https://github.com/mvee
- jmontleon - https://github.com/jmontleon
- emilianomolina - https://github.com/emilianomolina
- davidp57 - https://github.com/davidp57
- davidp57 - https://github.com/veaf
- Allow minimum distance from friendly logistics to be set
]]
@@ -26,7 +26,7 @@ ctld = {} -- DONT REMOVE!
ctld.Id = "CTLD - "
--- Version.
ctld.Version = "20210617.01"
ctld.Version = "20211113.01"
-- debug level, specific to this module
ctld.Debug = true
@@ -74,7 +74,7 @@ ctld.vehiclesWeight = {
}
ctld.aaLaunchers = 3 -- controls how many launchers to add to the kub/buk when its spawned.
ctld.hawkLaunchers = 5 -- controls how many launchers to add to the hawk when its spawned.
ctld.hawkLaunchers = 8 -- controls how many launchers to add to the hawk when its spawned.
ctld.spawnRPGWithCoalition = true --spawns a friendly RPG unit with Coalition forces
ctld.spawnStinger = false -- spawns a stinger / igla soldier with a group of 6 or more soldiers!
@@ -542,6 +542,7 @@ ctld.spawnableCrates = {
{ weight = 545, desc = "HAWK Search Radar", unit = "Hawk sr", side = 2 },
{ weight = 546, desc = "HAWK Track Radar", unit = "Hawk tr", side = 2 },
{ weight = 547, desc = "HAWK PCP", unit = "Hawk pcp" , side = 2 }, -- Remove this if on 1.2
{ weight = 548, desc = "HAWK CWAR", unit = "Hawk cwar" , side = 2 }, -- Remove this if on 2.5
{ weight = 549, desc = "HAWK Repair", unit = "HAWK Repair" , side = 2 },
-- End of HAWK
@@ -1394,6 +1395,7 @@ ctld.AASystemTemplate = {
{name = "Hawk tr", desc = "HAWK Track Radar"},
{name = "Hawk sr", desc = "HAWK Search Radar"},
{name = "Hawk pcp", desc = "HAWK PCP"},
{name = "Hawk cwar", desc = "HAWK CWAR"},
},
repair = "HAWK Repair",
},
@@ -2365,7 +2367,7 @@ function ctld.unloadTroops(_args)
else
-- troops must be onboard to get here
if _zone.inZone == true then
if _zone.inZone == true then
if _troops then
ctld.displayMessageToGroup(_heli, "Dropped troops back to base", 20)
@@ -4170,15 +4172,6 @@ function ctld.spawnCrateGroup(_heli, _positions, _types)
local _spawnedGroup = Group.getByName(mist.dynAdd(_group).name)
--local _spawnedGroup = coalition.addGroup(_heli:getCountry(), Group.Category.GROUND, _group)
--activate by moving and so we can set ROE and Alarm state
local _dest = _spawnedGroup:getUnit(1):getPoint()
_dest = { x = _dest.x + 0.5, _y = _dest.y + 0.5, z = _dest.z + 0.5 }
ctld.orderGroupToMoveToPoint(_spawnedGroup:getUnit(1), _dest)
return _spawnedGroup
end
@@ -5139,9 +5132,32 @@ 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 = {}
ctld.jtacRadioData = {}
function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour, _radio)
ctld.logDebug(string.format("ctld.JTACAutoLase(_jtacGroupName=%s, _laserCode=%s", ctld.p(_jtacGroupName), ctld.p(_laserCode)))
function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
local _radio = _radio
if not _radio then
_radio = {}
if _laserCode then
local _laserCode = tonumber(_laserCode)
if _laserCode and _laserCode >= 1111 and _laserCode <= 1688 then
local _laserB = math.floor((_laserCode - 1000)/100)
local _laserCD = _laserCode - 1000 - _laserB*100
local _frequency = tostring(30+_laserB+_laserCD*0.05)
ctld.logTrace(string.format("_laserB=%s", ctld.p(_laserB)))
ctld.logTrace(string.format("_laserCD=%s", ctld.p(_laserCD)))
ctld.logTrace(string.format("_frequency=%s", ctld.p(_frequency)))
_radio.freq = _frequency
_radio.mod = "fm"
end
end
end
if _radio and not _radio.name then
_radio.name = _jtacGroupName
end
if ctld.jtacStop[_jtacGroupName] == true then
ctld.jtacStop[_jtacGroupName] = nil -- allow it to be started again
@@ -5156,6 +5172,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
ctld.jtacLaserPointCodes[_jtacGroupName] = _laserCode
ctld.jtacRadioData[_jtacGroupName] = _radio
local _jtacGroup = ctld.getGroup(_jtacGroupName)
local _jtacUnit
@@ -5172,7 +5189,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
ctld.cleanupJTAC(_jtacGroupName)
env.info(_jtacGroupName .. ' in Transport - Waiting 10 seconds')
timer.scheduleFunction(ctld.timerJTACAutoLase, { _jtacGroupName, _laserCode, _smoke, _lock, _colour }, timer.getTime() + 10)
timer.scheduleFunction(ctld.timerJTACAutoLase, { _jtacGroupName, _laserCode, _smoke, _lock, _colour, _radio }, timer.getTime() + 10)
return
end
@@ -5181,7 +5198,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
ctld.cleanupJTAC(_jtacGroupName)
env.info(_jtacGroupName .. ' in Transport - Waiting 10 seconds')
timer.scheduleFunction(ctld.timerJTACAutoLase, { _jtacGroupName, _laserCode, _smoke, _lock, _colour }, timer.getTime() + 10)
timer.scheduleFunction(ctld.timerJTACAutoLase, { _jtacGroupName, _laserCode, _smoke, _lock, _colour, _radio }, timer.getTime() + 10)
return
end
end
@@ -5190,7 +5207,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
if ctld.jtacUnits[_jtacGroupName] ~= nil then
ctld.notifyCoalition("JTAC Group " .. _jtacGroupName .. " KIA!", 10, ctld.jtacUnits[_jtacGroupName].side)
ctld.notifyCoalition("JTAC Group " .. _jtacGroupName .. " KIA!", 10, ctld.jtacUnits[_jtacGroupName].side, _radio)
end
--remove from list
@@ -5203,7 +5220,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
_jtacUnit = _jtacGroup[1]
--add to list
ctld.jtacUnits[_jtacGroupName] = { name = _jtacUnit:getName(), side = _jtacUnit:getCoalition() }
ctld.jtacUnits[_jtacGroupName] = { name = _jtacUnit:getName(), side = _jtacUnit:getCoalition(), radio = _radio }
-- work out smoke colour
if _colour == nil then
@@ -5234,7 +5251,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
ctld.cleanupJTAC(_jtacGroupName)
env.info(_jtacGroupName .. ' Not Active - Waiting 30 seconds')
timer.scheduleFunction(ctld.timerJTACAutoLase, { _jtacGroupName, _laserCode, _smoke, _lock, _colour }, timer.getTime() + 30)
timer.scheduleFunction(ctld.timerJTACAutoLase, { _jtacGroupName, _laserCode, _smoke, _lock, _colour, _radio }, timer.getTime() + 30)
return
end
@@ -5260,6 +5277,9 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
--remove from smoke list
ctld.jtacSmokeMarks[_tempUnitInfo.name] = nil
-- JTAC Unit: resume his route ------------
trigger.action.groupContinueMoving(Group.getByName(_jtacGroupName))
-- remove from target list
ctld.jtacCurrentTargets[_jtacGroupName] = nil
@@ -5286,8 +5306,11 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
local message = _jtacGroupName .. action .. _enemyUnit:getTypeName()
local fullMessage = message .. '. CODE: ' .. _laserCode .. ". POSITION: " .. ctld.getPositionString(_enemyUnit)
ctld.notifyCoalition(fullMessage, 10, _jtacUnit:getCoalition())
ctld.notifyCoalition(fullMessage, 10, _jtacUnit:getCoalition(), _radio, message)
-- JTAC Unit stop his route -----------------
trigger.action.groupStopMoving(Group.getByName(_jtacGroupName)) -- stop JTAC
-- create smoke
if _smoke == true then
@@ -5302,7 +5325,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
ctld.laseUnit(_enemyUnit, _jtacUnit, _jtacGroupName, _laserCode)
-- env.info('Timer timerSparkleLase '..jtacGroupName.." "..laserCode.." "..enemyUnit:getName())
timer.scheduleFunction(ctld.timerJTACAutoLase, { _jtacGroupName, _laserCode, _smoke, _lock, _colour }, timer.getTime() + 15)
timer.scheduleFunction(ctld.timerJTACAutoLase, { _jtacGroupName, _laserCode, _smoke, _lock, _colour, _radio }, timer.getTime() + 15)
if _smoke == true then
@@ -5322,13 +5345,13 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour)
ctld.cancelLase(_jtacGroupName)
-- env.info('Timer Slow timerSparkleLase '..jtacGroupName.." "..laserCode.." "..enemyUnit:getName())
timer.scheduleFunction(ctld.timerJTACAutoLase, { _jtacGroupName, _laserCode, _smoke, _lock, _colour }, timer.getTime() + 5)
timer.scheduleFunction(ctld.timerJTACAutoLase, { _jtacGroupName, _laserCode, _smoke, _lock, _colour, _radio }, timer.getTime() + 5)
end
if targetLost then
ctld.notifyCoalition(_jtacGroupName .. ", target lost.", 10, _jtacUnit:getCoalition())
ctld.notifyCoalition(_jtacGroupName .. ", target lost.", 10, _jtacUnit:getCoalition(), _radio)
elseif targetDestroyed then
ctld.notifyCoalition(_jtacGroupName .. ", target destroyed.", 10, _jtacUnit:getCoalition())
ctld.notifyCoalition(_jtacGroupName .. ", target destroyed.", 10, _jtacUnit:getCoalition(), _radio)
end
end
@@ -5339,7 +5362,7 @@ end
-- used by the timer function
function ctld.timerJTACAutoLase(_args)
ctld.JTACAutoLase(_args[1], _args[2], _args[3], _args[4], _args[5])
ctld.JTACAutoLase(_args[1], _args[2], _args[3], _args[4], _args[5], _args[6])
end
function ctld.cleanupJTAC(_jtacGroupName)
@@ -5350,11 +5373,42 @@ function ctld.cleanupJTAC(_jtacGroupName)
ctld.jtacUnits[_jtacGroupName] = nil
ctld.jtacCurrentTargets[_jtacGroupName] = nil
ctld.jtacRadioData[_jtacGroupName] = nil
end
function ctld.notifyCoalition(_message, _displayFor, _side)
--- send a message to the coalition
--- if _radio is set, the message will be read out loud via SRS
function ctld.notifyCoalition(_message, _displayFor, _side, _radio, _shortMessage)
ctld.logDebug(string.format("ctld.notifyCoalition(_message=%s)", ctld.p(_message)))
ctld.logTrace(string.format("_radio=%s", ctld.p(_radio)))
local _shortMessage = _shortMessage
if _shortMessage == nil then
_shortMessage = _message
end
if STTS and STTS.TextToSpeech and _radio and _radio.freq then
local _freq = _radio.freq
local _modulation = _radio.mod or "FM"
local _volume = _radio.volume or "1.0"
local _name = _radio.name or "JTAC"
local _gender = _radio.gender or "male"
local _culture = _radio.culture or "en-US"
local _voice = _radio.voice
local _googleTTS = _radio.googleTTS or false
ctld.logTrace(string.format("calling STTS.TextToSpeech(%s)", ctld.p(_shortMessage)))
ctld.logTrace(string.format("_freq=%s", ctld.p(_freq)))
ctld.logTrace(string.format("_modulation=%s", ctld.p(_modulation)))
ctld.logTrace(string.format("_volume=%s", ctld.p(_volume)))
ctld.logTrace(string.format("_name=%s", ctld.p(_name)))
ctld.logTrace(string.format("_gender=%s", ctld.p(_gender)))
ctld.logTrace(string.format("_culture=%s", ctld.p(_culture)))
ctld.logTrace(string.format("_voice=%s", ctld.p(_voice)))
ctld.logTrace(string.format("_googleTTS=%s", ctld.p(_googleTTS)))
STTS.TextToSpeech(_shortMessage, _freq, _modulation, _volume, _name, _side, nil, 1, _gender, _culture, _voice, _googleTTS)
end
trigger.action.outTextForCoalition(_side, _message, _displayFor)
trigger.action.outSoundForCoalition(_side, "radiobeep.ogg")
@@ -5576,18 +5630,33 @@ function ctld.findNearestVisibleEnemy(_jtacUnit, _targetType,_distance)
end
end
local result = nil
for _, _enemyUnit in ipairs(_unitList) do
local _enemyName = _enemyUnit.unit:getName()
--log.info(string.format("CTLD - checking _enemyName=%s", _enemyName))
-- check for air defenses
--log.info(string.format("CTLD - _enemyUnit.unit:getDesc()[attributes]=%s", ctld.p(_enemyUnit.unit:getDesc()["attributes"])))
local airdefense = (_enemyUnit.unit:getDesc()["attributes"]["Air Defence"] ~= nil)
--log.info(string.format("CTLD - airdefense=%s", tostring(airdefense)))
if (_targetType == "vehicle" and ctld.isVehicle(_enemyUnit.unit)) or _targetType == "all" then
return _enemyUnit.unit
if airdefense then
return _enemyUnit.unit
else
result = _enemyUnit.unit
end
elseif (_targetType == "troop" and ctld.isInfantry(_enemyUnit.unit)) or _targetType == "all" then
return _enemyUnit.unit
if airdefense then
return _enemyUnit.unit
else
result = _enemyUnit.unit
end
end
end
return nil
return result
end
@@ -5722,12 +5791,17 @@ function ctld.getJTACStatus(_args)
local _laserCode = ctld.jtacLaserPointCodes[_jtacGroupName]
local _start = _jtacGroupName
if (_jtacDetails.radio) then
_start = _start .. ", available on ".._jtacDetails.radio.freq.." ".._jtacDetails.radio.mod ..","
end
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 .. ctld.getPositionString(_enemyUnit) .. "\n"
_message = _message .. "" .. _start .. " targeting " .. _enemyUnit:getTypeName() .. " CODE: " .. _laserCode .. ctld.getPositionString(_enemyUnit) .. "\n"
local _list = ctld.listNearbyEnemies(_jtacUnit)
@@ -5741,7 +5815,7 @@ function ctld.getJTACStatus(_args)
end
else
_message = _message .. "" .. _jtacGroupName .. " searching for targets" .. ctld.getPositionString(_jtacUnit) .. "\n"
_message = _message .. "" .. _start .. " searching for targets" .. ctld.getPositionString(_jtacUnit) .. "\n"
end
end
end

Binary file not shown.

BIN
Il-76.zip

Binary file not shown.

Binary file not shown.

View File

@@ -740,6 +740,18 @@ the mission but there can be a delay of up to 30 seconds after activation for th
You can also change the **name of a unit*** (unit, not group) to include "**hpriority**" to make it high priority for the JTAC, or "**priority**" to set it to be medium priority. JTAC's will prioritize targets within view by first marking hpriority targets, then priority targets, and finally all others. This works seemlessly with the all/vehicle/troop functionality as well. In this way you can have them lase SAMS, then AAA, then armor, or any other order you decide is preferable.
If the `DCS-SimpleTextToSpeech.lua` script is loaded (you'll find it [here](https://github.com/ciribob/DCS-SimpleTextToSpeech)), and configured (i.e. the `STTS.DIRECTORY`, `STTS.SRS_PORT` and optionaly the `STTS.GOOGLE_CREDENTIALS` variables are set), the JTAC can talk over SRS.
To do this, you can specify the _radio parameter when calling ctld.JTACAutoLase like in this example :
```lua
ctld.JTACAutoLase('JTAC1', 1688, true,"all", 4, { freq = "251.50", mod = "AM", name = "JTAC one" })
```
If you don't use the _radio parameter, CTLD will compute a FM frequency based on the laser designator code : 30Mhz + [second figure of the code] + [last two figures of the code] * 0.05.
For example, if the laser code is *1688*, the frequency will be *40.40Mhz*.
JTAC frequency is available through the "JTAC Status" radio menu
# In Game
## Troop Loading and Unloading

957
mist.lua

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.