@jtff/miztemplate-lib 3.10.14 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lua/lib/HoundElint.lua +11378 -11415
- package/lua/lib/Moose_.lua +35746 -44020
- package/lua/src/010-root_menus.lua +4 -3
- package/lua/src/020-mission_functions.lua +905 -217
- package/lua/src/110-set_clients.lua +53 -43
- package/lua/src/115-airbases.lua +191 -0
- package/lua/src/120-tankers.lua +590 -461
- package/lua/src/130-airboss.lua +1982 -440
- package/lua/src/150-awacs.lua +551 -445
- package/lua/src/160-atis.lua +136 -73
- package/lua/src/170-cap_zone_training.lua +176 -73
- package/lua/src/172-cap_zone_war.lua +383 -226
- package/lua/src/173-fox_zone_training.lua +142 -67
- package/lua/src/174-qra-scenario.lua +417 -362
- package/lua/src/176-random_air_traffic.lua +101 -12
- package/lua/src/178-training-intercept.lua +312 -261
- package/lua/src/180-logistics.lua +2 -2
- package/lua/src/190-ranges.lua +104 -37
- package/lua/src/191-sams.lua +4 -4
- package/lua/src/193-training_ranges.lua +2 -2
- package/lua/src/195-reaper-ondemand.lua +29 -29
- package/lua/src/196-fac_ranges.lua +2 -2
- package/lua/src/197-elint-ondemand.lua +53 -53
- package/lua/src/199-skynet.lua +55 -55
- package/package.json +1 -1
- package/scripts/inject-scripts.js +3 -31
- package/lua/src/135-pedro.lua +0 -21
- package/lua/src/140-beacons.lua +0 -19
|
@@ -2,42 +2,46 @@
|
|
|
2
2
|
-- * Mission functions *
|
|
3
3
|
-- *****************************************************************************
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
--
|
|
7
6
|
-- Generic Spawn object functions
|
|
8
7
|
--
|
|
9
8
|
env.info('JTFF-SHAREDLIB: shared library loading...')
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
{ name = "trace", color = "\27[34m", },
|
|
13
|
-
{ name = "debug", color = "\27[36m", },
|
|
14
|
-
{ name = "info", color = "\27[32m", },
|
|
15
|
-
{ name = "warn", color = "\27[33m", },
|
|
16
|
-
{ name = "error", color = "\27[31m", },
|
|
17
|
-
{ name = "fatal", color = "\27[35m", },
|
|
10
|
+
Log_modes = {
|
|
11
|
+
{ name = "trace", color = "\27[34m", verbosity = 10},
|
|
12
|
+
{ name = "debug", color = "\27[36m", verbosity = 5},
|
|
13
|
+
{ name = "info", color = "\27[32m", verbosity = 1},
|
|
14
|
+
{ name = "warn", color = "\27[33m", verbosity = 0},
|
|
15
|
+
{ name = "error", color = "\27[31m", verbosity = 0},
|
|
16
|
+
{ name = "fatal", color = "\27[35m", verbosity = 0},
|
|
18
17
|
}
|
|
19
|
-
|
|
20
|
-
for i, v in ipairs(
|
|
21
|
-
|
|
18
|
+
Log_levels = {}
|
|
19
|
+
for i, v in ipairs(Log_modes) do
|
|
20
|
+
Log_levels[v.name] = i
|
|
22
21
|
end
|
|
23
22
|
JTFF_LOGLEVEL = 'info'
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
for
|
|
24
|
+
JTFF_verbosity_levels = {}
|
|
25
|
+
for i, v in ipairs(Log_modes) do
|
|
26
|
+
JTFF_verbosity_levels[v.name] = v.verbosity
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
Jtff_log = {}
|
|
30
|
+
for index, mode in ipairs(Log_modes) do
|
|
27
31
|
local nameupper = mode.name:upper()
|
|
28
|
-
|
|
32
|
+
Jtff_log[mode.name] = function(message, category)
|
|
29
33
|
-- Return early if we're below the log level
|
|
30
|
-
if index <
|
|
34
|
+
if index < Log_levels[JTFF_LOGLEVEL] then
|
|
31
35
|
return
|
|
32
36
|
end
|
|
33
37
|
env.info(string.format("[JTFF-%s]--%s-- %s", mode.name, category, message))
|
|
34
38
|
end
|
|
35
39
|
end
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
Use_jtff_sound_mod = false
|
|
38
42
|
|
|
39
43
|
if (not(FunkmanConfig)) then
|
|
40
|
-
|
|
44
|
+
Jtff_log.error(string.format("Local Funkman Bot config not specified ! Initializing empty values for Funkman"), "Initialization")
|
|
41
45
|
FunkmanConfig = {
|
|
42
46
|
ip= "127.0.0.1",
|
|
43
47
|
port = 10042,
|
|
@@ -45,7 +49,7 @@ if (not(FunkmanConfig)) then
|
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
if (not(SRSConfig)) then
|
|
48
|
-
|
|
52
|
+
Jtff_log.error(string.format("Local SRS config not specified ! Initializing empty values for SRS"), "Initialization")
|
|
49
53
|
SRSConfig= {
|
|
50
54
|
port = 5002,
|
|
51
55
|
path = "C:/Program Files/DCS-SimpleRadio-Standalone/ExternalAudio",
|
|
@@ -53,10 +57,10 @@ if (not(SRSConfig)) then
|
|
|
53
57
|
}
|
|
54
58
|
end
|
|
55
59
|
|
|
56
|
-
|
|
60
|
+
SpawnStandardDelay = 15
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
Jtff_sead = SEAD:New({})
|
|
63
|
+
Jtff_map_marker = {}
|
|
60
64
|
|
|
61
65
|
AAMAxRange = {
|
|
62
66
|
MAX_RANGE = 0,
|
|
@@ -70,21 +74,41 @@ if (pcall(
|
|
|
70
74
|
function ()
|
|
71
75
|
dofile(lfs.writedir() .. 'Scripts/net/DCSServerBot/DCSServerBot.lua')
|
|
72
76
|
end)) then
|
|
73
|
-
|
|
77
|
+
Jtff_log.debug(string.format("DCSServerBot present on server ! Including NetLibrary..."), "Initialization")
|
|
78
|
+
Jtff_dcsbot = dcsbot
|
|
74
79
|
else
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
Jtff_log.error(string.format("DCSServerBot NOT present on server ! Preventing use of it..."), "Initialization")
|
|
81
|
+
Jtff_dcsbot = nil
|
|
77
82
|
end
|
|
78
83
|
|
|
79
|
-
function
|
|
80
|
-
status = not BASE:GetState(group, "isImmortal")
|
|
81
|
-
|
|
84
|
+
function SwitchGroupImmortalStatus(group)
|
|
85
|
+
local status = not BASE:GetState(group, "isImmortal")
|
|
86
|
+
Jtff_log.info(string.format("switch group %s to immortal status %s", group:GetName(), tostring(status)), "GENERAL")
|
|
82
87
|
group:SetCommandImmortal(status)
|
|
83
88
|
BASE:SetState(group, "isImmortal", status)
|
|
84
89
|
MESSAGE:NewType("Immortal status of your group : " .. tostring(status) , MESSAGE.Type.Update):ToGroup(group)
|
|
85
90
|
end
|
|
86
91
|
|
|
87
|
-
function
|
|
92
|
+
function SwitchGroupUnlimitedFuelStatus(group)
|
|
93
|
+
local status = not BASE:GetState(group, "isUnlimitedFuel")
|
|
94
|
+
Jtff_log.info(
|
|
95
|
+
string.format(
|
|
96
|
+
"switch group %s to unlimited fuel status %s",
|
|
97
|
+
group:GetName(),
|
|
98
|
+
tostring(status)
|
|
99
|
+
),
|
|
100
|
+
"GENERAL"
|
|
101
|
+
)
|
|
102
|
+
group:CommandSetUnlimitedFuel(status)
|
|
103
|
+
BASE:SetState(group, "isUnlimitedFuel", status)
|
|
104
|
+
MESSAGE:NewType(
|
|
105
|
+
"Unlimited fuel status of your group : " .. tostring(status) ,
|
|
106
|
+
MESSAGE.Type.Update
|
|
107
|
+
):ToGroup(group)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
function SwitchGroupAirbossSubtitlesStatus(group)
|
|
88
112
|
for index, airbossObject in ipairs(AIRBOSSArray) do
|
|
89
113
|
for playerindex, player in ipairs(group:GetPlayerUnits()) do
|
|
90
114
|
airbossObject:_SubtitlesOnOff(player:Name())
|
|
@@ -92,7 +116,7 @@ function switchGroupAirbossSubtitlesStatus(group)
|
|
|
92
116
|
end
|
|
93
117
|
end
|
|
94
118
|
|
|
95
|
-
function
|
|
119
|
+
function Give_bra_of_air_group(param)
|
|
96
120
|
local target_group = param[1]
|
|
97
121
|
local client_group = param[2]
|
|
98
122
|
local settings = param[3]
|
|
@@ -104,7 +128,7 @@ function give_bra_of_air_group(param)
|
|
|
104
128
|
)
|
|
105
129
|
end
|
|
106
130
|
|
|
107
|
-
function
|
|
131
|
+
function Give_heading_speed(param)
|
|
108
132
|
local target_group = param[1]
|
|
109
133
|
local settings = param[2]
|
|
110
134
|
local heading_target = target_group:GetHeading()
|
|
@@ -124,16 +148,18 @@ function give_heading_speed(param)
|
|
|
124
148
|
)
|
|
125
149
|
end
|
|
126
150
|
|
|
127
|
-
function
|
|
151
|
+
function TankerStatusMessage(tanker, PlayerUnit, PlayerGroup)
|
|
128
152
|
local client = CLIENT:Find(PlayerUnit:GetDCSObject())
|
|
129
153
|
local setting = _DATABASE:GetPlayerSettings(client:GetPlayerName())
|
|
130
154
|
|
|
131
|
-
local tankerrefuelsystemName = "
|
|
132
|
-
|
|
133
|
-
|
|
155
|
+
local tankerrefuelsystemName = "PROBE_AND_DROGUE"
|
|
156
|
+
|
|
157
|
+
local isrefuelable, playerrefuelsystem=PlayerUnit:IsRefuelable()
|
|
158
|
+
if ((playerrefuelsystem or 0) == 0) and isrefuelable then
|
|
159
|
+
tankerrefuelsystemName = "BOOM_AND_RECEPTACLE"
|
|
134
160
|
end
|
|
135
|
-
local braa_message =
|
|
136
|
-
local aspect_message =
|
|
161
|
+
local braa_message = Give_bra_of_air_group({tanker:GetGroup(), PlayerGroup, setting})
|
|
162
|
+
local aspect_message = Give_heading_speed({tanker:GetGroup(), setting})
|
|
137
163
|
local fuelState = string.format("%s Lbs", tanker:GetTemplateFuel() * 2.205)
|
|
138
164
|
if setting:IsMetric() then
|
|
139
165
|
fuelState = string.format("%s Kg", tanker:GetTemplateFuel())
|
|
@@ -142,35 +168,20 @@ function tankerStatusMessage(tanker, PlayerUnit, PlayerGroup)
|
|
|
142
168
|
local timeInTheAir = 0
|
|
143
169
|
local timeLeftInTheAir = 0
|
|
144
170
|
local timeLeftString = "Time left : "
|
|
145
|
-
local groupName = tanker:
|
|
146
|
-
for index, value in pairs(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
timeLeftInTheAir = value.customconfig.missionmaxduration * 60 - timeInTheAir
|
|
151
|
-
if (UTILS.SecondsToClock(timeLeftInTheAir, true) ~= nil) then
|
|
152
|
-
timeLeftString = timeLeftString .. UTILS.SecondsToClock(timeLeftInTheAir, true)
|
|
153
|
-
end
|
|
154
|
-
jtff_log.debug(string.format("%s found in %s, time in the air : %i sec, time left %i sec",
|
|
155
|
-
value.tanker.GroupName, groupName, timeInTheAir, timeLeftInTheAir), "TANKER")
|
|
156
|
-
else
|
|
157
|
-
jtff_log.warn(string.format("%s not found in %s", value.tanker.GroupName, groupName),"TANKER")
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
for index, value in pairs(tankersOnDemandArray) do
|
|
162
|
-
if( value ~= nil) then
|
|
163
|
-
jtff_log.info(string.format("%s spawned in tankersOnDemandArray", value:GetName()),"TANKER")
|
|
164
|
-
if (string.find(groupName, value:GetName(), 1, true) ~= nil) then
|
|
171
|
+
local groupName = tanker:GetCallsign()
|
|
172
|
+
for index, value in pairs(TankersArray or {}) do
|
|
173
|
+
if( type(value) ~= 'nil') then
|
|
174
|
+
Jtff_log.info(string.format("%s-%d-1 is in TankersArray", value.customconfig.callsign.name, value.customconfig.callsign.number),"TANKER")
|
|
175
|
+
if (string.find(groupName, string.format("%s-%d", value.customconfig.callsign.name, value.customconfig.callsign.number), 1, true) ~= nil) then
|
|
165
176
|
timeInTheAir = timer.getAbsTime() - value.spawnAbsTime
|
|
166
177
|
timeLeftInTheAir = value.missionmaxduration * 60 - timeInTheAir
|
|
167
178
|
if (UTILS.SecondsToClock(timeLeftInTheAir, true) ~= nil) then
|
|
168
179
|
timeLeftString = timeLeftString .. UTILS.SecondsToClock(timeLeftInTheAir, true)
|
|
169
180
|
end
|
|
170
|
-
|
|
181
|
+
Jtff_log.debug(string.format("%s found in %s, time in the air : %i sec, time left %i sec",
|
|
171
182
|
value:GetName(), groupName, timeInTheAir, timeLeftInTheAir),"TANKER")
|
|
172
183
|
else
|
|
173
|
-
|
|
184
|
+
Jtff_log.warn(string.format("%s not found in %s", value:GetName(), groupName),"TANKER")
|
|
174
185
|
end
|
|
175
186
|
end
|
|
176
187
|
end
|
|
@@ -181,7 +192,7 @@ function tankerStatusMessage(tanker, PlayerUnit, PlayerGroup)
|
|
|
181
192
|
MESSAGE:NewType(message, MESSAGE.Type.Overview):ToGroup(PlayerGroup)
|
|
182
193
|
end
|
|
183
194
|
|
|
184
|
-
function
|
|
195
|
+
function GetNearestTankerfromPlayerUnit(PlayerUnit, Radius)
|
|
185
196
|
Radius=UTILS.NMToMeters(Radius or 50)
|
|
186
197
|
|
|
187
198
|
local isrefuelable, playerrefuelsystem=PlayerUnit:IsRefuelable()
|
|
@@ -212,14 +223,14 @@ function getNearestTankerfromPlayerUnit(PlayerUnit, Radius)
|
|
|
212
223
|
return nil
|
|
213
224
|
end
|
|
214
225
|
|
|
215
|
-
function
|
|
216
|
-
local tanker =
|
|
226
|
+
function FindNearestTanker(PlayerUnit, PlayerGroup, Radius)
|
|
227
|
+
local tanker = GetNearestTankerfromPlayerUnit(PlayerUnit)
|
|
217
228
|
if (type(tanker) ~= "nil") then
|
|
218
|
-
|
|
229
|
+
TankerStatusMessage(tanker, PlayerUnit, PlayerGroup)
|
|
219
230
|
end
|
|
220
231
|
end
|
|
221
232
|
|
|
222
|
-
function
|
|
233
|
+
function FindAllTanker(PlayerUnit, PlayerGroup, Radius)
|
|
223
234
|
|
|
224
235
|
Radius=UTILS.NMToMeters(Radius or 50)
|
|
225
236
|
|
|
@@ -239,7 +250,7 @@ function findAllTanker(PlayerUnit, PlayerGroup, Radius)
|
|
|
239
250
|
coalition == unit:GetCoalition() and
|
|
240
251
|
unit:IsAlive() then
|
|
241
252
|
tanker=unit
|
|
242
|
-
|
|
253
|
+
TankerStatusMessage(tanker, PlayerUnit, PlayerGroup)
|
|
243
254
|
end
|
|
244
255
|
end
|
|
245
256
|
end
|
|
@@ -247,7 +258,7 @@ function findAllTanker(PlayerUnit, PlayerGroup, Radius)
|
|
|
247
258
|
end
|
|
248
259
|
|
|
249
260
|
function NearestTankerInfo(param)
|
|
250
|
-
|
|
261
|
+
FindNearestTanker(
|
|
251
262
|
param[1],
|
|
252
263
|
param[2],
|
|
253
264
|
200
|
|
@@ -255,10 +266,10 @@ function NearestTankerInfo(param)
|
|
|
255
266
|
end
|
|
256
267
|
|
|
257
268
|
function AllTankersInfo(param)
|
|
258
|
-
|
|
269
|
+
FindAllTanker(param[1],param[2], 200)
|
|
259
270
|
end
|
|
260
271
|
|
|
261
|
-
function
|
|
272
|
+
function TaskTankerEscort(param)
|
|
262
273
|
local recoveryTankerObject = param[1]
|
|
263
274
|
local EscortGroup = param[2]
|
|
264
275
|
EscortGroup:OptionAlarmStateRed()
|
|
@@ -295,10 +306,10 @@ function taskTankerEscort(param)
|
|
|
295
306
|
)
|
|
296
307
|
}
|
|
297
308
|
)
|
|
298
|
-
|
|
309
|
+
Jtff_log.info('Escort group spawned : '.. EscortGroup.GroupName..'. Escorting '..recoveryTankerObject.tanker.GroupName,"TANKER")
|
|
299
310
|
end
|
|
300
311
|
|
|
301
|
-
function
|
|
312
|
+
function TaskGroupEscort(param)
|
|
302
313
|
local GroupToEscortObject = param[1]
|
|
303
314
|
local EscortingGroup = param[2]
|
|
304
315
|
EscortingGroup:OptionAlarmStateRed()
|
|
@@ -335,10 +346,10 @@ function taskGroupEscort(param)
|
|
|
335
346
|
)
|
|
336
347
|
}
|
|
337
348
|
)
|
|
338
|
-
|
|
349
|
+
Jtff_log.info('Escort group spawned : '.. EscortingGroup.GroupName..'. Escorting '.. GroupToEscortObject.GroupName,"GENERAL")
|
|
339
350
|
end
|
|
340
351
|
|
|
341
|
-
function
|
|
352
|
+
function SpawnRecoveryTankerEscort(escortSpawnObject,customconfig)
|
|
342
353
|
if (customconfig.airspawn) then
|
|
343
354
|
return escortSpawnObject
|
|
344
355
|
:SpawnFromCoordinate(UNIT:FindByName(customconfig.baseUnit):GetCoordinate():SetAltitude(UTILS.FeetToMeters(customconfig.altitude)))
|
|
@@ -352,7 +363,7 @@ function LeaveRecovery(objAirboss)
|
|
|
352
363
|
local shipID = UNIT:FindByName(objAirboss.carrier:Name()):GetDCSObject():getID()
|
|
353
364
|
end
|
|
354
365
|
|
|
355
|
-
function
|
|
366
|
+
function ResetRecoveryTanker(recoveryTankerObject)
|
|
356
367
|
recoveryTankerObject:SetRespawnOnOff(true)
|
|
357
368
|
recoveryTankerObject.tanker:Destroy()
|
|
358
369
|
recoveryTankerObject:SetRespawnOnOff(recoveryTankerObject.customconfig.autorespawn)
|
|
@@ -362,37 +373,28 @@ function resetRecoveryTanker(recoveryTankerObject)
|
|
|
362
373
|
end
|
|
363
374
|
end
|
|
364
375
|
|
|
365
|
-
function
|
|
366
|
-
local GroupPlane, Index = objSpawn:GetFirstAliveGroup()
|
|
367
|
-
while GroupPlane ~= nil do
|
|
368
|
-
-- Do actions with the GroupPlane object.
|
|
369
|
-
GroupPlane:Destroy(true)
|
|
370
|
-
GroupPlane, Index = objSpawn:GetNextAliveGroup( Index )
|
|
371
|
-
end
|
|
372
|
-
end
|
|
373
|
-
|
|
374
|
-
function getMaxThreatUnit(setUnits)
|
|
376
|
+
function GetMaxThreatUnit(setUnits)
|
|
375
377
|
local setUnitsSorted = SET_UNIT:New()
|
|
376
378
|
setUnits:ForEachUnitPerThreatLevel(10, 0, function(unit)
|
|
377
379
|
setUnitsSorted:AddUnit(unit)
|
|
378
380
|
end)
|
|
379
|
-
|
|
381
|
+
Jtff_log.debug(string.format("Max priority unit : %s", setUnitsSorted:GetFirst():GetName()), "GENERAL")
|
|
380
382
|
return setUnitsSorted:GetFirst()
|
|
381
383
|
end
|
|
382
384
|
|
|
383
|
-
function
|
|
385
|
+
function DestroyGroup(group_name)
|
|
384
386
|
local set_group_alive = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
|
|
385
387
|
set_group_alive:ForEachGroupAlive(
|
|
386
388
|
function(group_alive)
|
|
387
|
-
|
|
388
|
-
if (
|
|
389
|
-
COORDINATE:RemoveMark(
|
|
389
|
+
Jtff_log.info(string.format("Group %s just removed", group_alive:GetName()),"GENERAL")
|
|
390
|
+
if (Jtff_map_marker[group_alive:GetName()]) then
|
|
391
|
+
COORDINATE:RemoveMark(Jtff_map_marker[group_alive:GetName()])
|
|
390
392
|
end
|
|
391
393
|
group_alive:Destroy()
|
|
392
394
|
end )
|
|
393
395
|
end
|
|
394
396
|
|
|
395
|
-
function
|
|
397
|
+
function DestroyStatic(staticToDelete, subRangeName, index)
|
|
396
398
|
if (staticToDelete.name ~= nil) then
|
|
397
399
|
local staticNameToDelete = string.format("%s", staticToDelete.name)
|
|
398
400
|
if (subRangeName ~= nil and index ~= nil) then
|
|
@@ -400,28 +402,28 @@ function destroyStatic(staticToDelete, subRangeName, index)
|
|
|
400
402
|
end
|
|
401
403
|
local staticUnitToDelete = STATIC:FindByName(staticNameToDelete, false)
|
|
402
404
|
if (staticUnitToDelete ~= nil) then
|
|
403
|
-
|
|
405
|
+
Jtff_log.info(string.format("Delete static %s", staticUnitToDelete:GetDCSObject():getName()),"GENERAL")
|
|
404
406
|
staticUnitToDelete:Destroy()
|
|
405
407
|
end
|
|
406
408
|
elseif (staticToDelete.type ~= nil and staticToDelete.category ~= nil and index ~= nil) then
|
|
407
409
|
local staticNameToDelete = string.format("%s_%s_%i", subRangeName, staticToDelete.type, index)
|
|
408
410
|
local staticUnitToDelete = STATIC:FindByName(staticNameToDelete, false)
|
|
409
411
|
if (staticUnitToDelete ~= nil) then
|
|
410
|
-
|
|
412
|
+
Jtff_log.info(string.format("Delete Static %s", staticUnitToDelete:GetDCSObject():getName()),"GENERAL")
|
|
411
413
|
staticUnitToDelete:Destroy()
|
|
412
414
|
end
|
|
413
415
|
else
|
|
414
|
-
|
|
416
|
+
Jtff_log.error(string.format("Static to delete has no name or type!"), "GENERAL")
|
|
415
417
|
end
|
|
416
418
|
end
|
|
417
419
|
|
|
418
|
-
function
|
|
420
|
+
function DestroyStatics(staticsToDelete, subRangeName)
|
|
419
421
|
for index, staticToDelete in ipairs(staticsToDelete) do
|
|
420
|
-
|
|
422
|
+
DestroyStatic(staticToDelete, subRangeName, index)
|
|
421
423
|
end
|
|
422
424
|
end
|
|
423
425
|
|
|
424
|
-
function
|
|
426
|
+
function DeleteSubRangeUnits(param)
|
|
425
427
|
--parameters :
|
|
426
428
|
-- 1 : groups to be destroyed
|
|
427
429
|
-- 2 : Root range config Object
|
|
@@ -437,43 +439,43 @@ function deleteSubRangeUnits(param)
|
|
|
437
439
|
local staticsToDelete = subRangeConfig.staticsToSpawn
|
|
438
440
|
if (subRangeConfig.groupsToSpawn ~= nil) then
|
|
439
441
|
for i = 1, #groupsToSpawn do
|
|
440
|
-
|
|
442
|
+
DestroyGroup(groupsToSpawn[i])
|
|
441
443
|
end
|
|
442
444
|
else
|
|
443
|
-
|
|
445
|
+
Jtff_log.warn(string.format("No Groups in %s", subRangeName), "RANGE")
|
|
444
446
|
end
|
|
445
447
|
if (subRangeConfig.randomGroupsToSpawn ~= nil) then
|
|
446
448
|
local groupsToDestroy = subRangeConfig.randomGroupsToSpawn
|
|
447
449
|
for i = 1, #groupsToDestroy do
|
|
448
|
-
|
|
450
|
+
DestroyGroup(subRangeConfig.randomGroupsToSpawn[i])
|
|
449
451
|
end
|
|
450
452
|
else
|
|
451
|
-
|
|
453
|
+
Jtff_log.warn(string.format("No random*W Groups in %s", subRangeName), "RANGE")
|
|
452
454
|
end
|
|
453
455
|
|
|
454
456
|
if (staticsToDelete ~= nil)then
|
|
455
|
-
|
|
457
|
+
DestroyStatics(staticsToDelete, subRangeName)
|
|
456
458
|
else
|
|
457
|
-
|
|
459
|
+
Jtff_log.warn(string.format("No static in %s", subRangeName), "RANGE")
|
|
458
460
|
end
|
|
459
461
|
|
|
460
462
|
MESSAGE:NewType(string.format("Remove the site : %s-%s", rangeConfig.name, subRangeConfig.name),
|
|
461
463
|
MESSAGE.Type.Information):ToBlue()
|
|
462
464
|
if (not(blnMute)) then
|
|
463
|
-
|
|
465
|
+
Sound2Bip:ToAll()
|
|
464
466
|
end
|
|
465
467
|
if radioCommandSubRange then
|
|
466
468
|
radioCommandSubRange:RemoveSubMenus()
|
|
467
|
-
|
|
469
|
+
AddSubRangeRadioMenus(radioCommandSubRange, rangeConfig, subRangeConfig)
|
|
468
470
|
end
|
|
469
471
|
end
|
|
470
472
|
|
|
471
|
-
function
|
|
473
|
+
function DeleteWholeRangeUnits(param)
|
|
472
474
|
local rangeConfig = param[1]
|
|
473
475
|
local rangeCoalitionMenu = param[2]
|
|
474
476
|
rangeCoalitionMenu:RemoveSubMenus()
|
|
475
477
|
if (rangeConfig.subRange ~= nil ) then
|
|
476
|
-
|
|
478
|
+
Sound2Bip:ToAll()
|
|
477
479
|
MESSAGE:NewType(string.format("Removing the whole site : %s", rangeConfig.name),
|
|
478
480
|
MESSAGE.Type.Information):ToCoalition(rangeConfig.benefit_coalition)
|
|
479
481
|
for subIndex, subRangeConfig in ipairs(rangeConfig.subRange) do
|
|
@@ -481,38 +483,38 @@ function deleteWholeRangeUnits(param)
|
|
|
481
483
|
if (subRangeConfig.subsubRange ~= nil) then
|
|
482
484
|
for subsubIndex, subsubRangeConfig in ipairs(subRangeConfig.subsubRange) do
|
|
483
485
|
local radioMenuSubSubRange = MENU_COALITION:New(rangeConfig.benefit_coalition, subsubRangeConfig.name, radioMenuSubRange)
|
|
484
|
-
|
|
486
|
+
DeleteSubRangeUnits({
|
|
485
487
|
subsubRangeConfig.groupsToSpawn,
|
|
486
488
|
rangeConfig,
|
|
487
489
|
subsubRangeConfig,
|
|
488
490
|
nil,
|
|
489
491
|
true
|
|
490
492
|
})
|
|
491
|
-
|
|
493
|
+
AddSubRangeRadioMenus(radioMenuSubSubRange, rangeConfig, subsubRangeConfig)
|
|
492
494
|
end
|
|
493
495
|
else
|
|
494
|
-
|
|
496
|
+
DeleteSubRangeUnits({
|
|
495
497
|
subRangeConfig.groupsToSpawn,
|
|
496
498
|
rangeConfig,
|
|
497
499
|
subRangeConfig,
|
|
498
500
|
nil,
|
|
499
501
|
true
|
|
500
502
|
})
|
|
501
|
-
|
|
503
|
+
AddSubRangeRadioMenus(radioMenuSubRange, rangeConfig, subRangeConfig)
|
|
502
504
|
end
|
|
503
505
|
end
|
|
504
506
|
end
|
|
505
507
|
AddWholeRangeCoalitionCommandMenus(rangeCoalitionMenu, rangeConfig)
|
|
506
508
|
end
|
|
507
509
|
|
|
508
|
-
function
|
|
510
|
+
function SetROE(param)
|
|
509
511
|
local groupsToSpawn = param[1]
|
|
510
512
|
local ROEvalue = param[2]
|
|
511
513
|
for groupIndex = 1, #groupsToSpawn do
|
|
512
514
|
local group_name = string.format("%s", groupsToSpawn[groupIndex])
|
|
513
515
|
local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
|
|
514
516
|
dcs_groups:ForEachGroupAlive(function(group_alive)
|
|
515
|
-
|
|
517
|
+
Jtff_log.info(string.format("SET ROE of group %s at %i", group_alive:GetName(), ROEvalue), "GENERAL")
|
|
516
518
|
if (ROEvalue ~= ENUMS.ROE.WeaponHold) then
|
|
517
519
|
group_alive:SetAIOn()
|
|
518
520
|
end
|
|
@@ -521,7 +523,7 @@ function setROE(param)
|
|
|
521
523
|
end
|
|
522
524
|
end
|
|
523
525
|
|
|
524
|
-
function
|
|
526
|
+
function SetAlarmState(param)
|
|
525
527
|
local groupsToSpawn = param[1]
|
|
526
528
|
local AlarmStateValue = param[2]
|
|
527
529
|
for groupIndex = 1, #groupsToSpawn do
|
|
@@ -530,27 +532,27 @@ function setAlarmState(param)
|
|
|
530
532
|
dcs_groups:ForEachGroupAlive(function(group_alive)
|
|
531
533
|
group_alive:SetAIOn()
|
|
532
534
|
if AlarmStateValue == ENUMS.AlarmState.Auto then
|
|
533
|
-
|
|
535
|
+
Jtff_log.info(string.format("SET Alarm State of group %s at AUTO", group_alive:GetName()),"GENERAL")
|
|
534
536
|
group_alive:OptionAlarmStateAuto()
|
|
535
537
|
elseif AlarmStateValue == ENUMS.AlarmState.Green then
|
|
536
|
-
|
|
538
|
+
Jtff_log.info(string.format("SET Alarm State of group %s at Green", group_alive:GetName()),"GENERAL")
|
|
537
539
|
group_alive:OptionAlarmStateGreen()
|
|
538
540
|
elseif AlarmStateValue == ENUMS.AlarmState.Red then
|
|
539
|
-
|
|
541
|
+
Jtff_log.info(string.format("SET Alarm State of group %s at Red", group_alive:GetName()),"GENERAL")
|
|
540
542
|
group_alive:OptionAlarmStateRed()
|
|
541
543
|
end
|
|
542
544
|
end)
|
|
543
545
|
end
|
|
544
546
|
end
|
|
545
547
|
|
|
546
|
-
function
|
|
548
|
+
function SetEngageAirWeapons(param)
|
|
547
549
|
local groupsToSpawn = param[1]
|
|
548
550
|
local value = param[2]
|
|
549
551
|
for groupIndex = 1, #groupsToSpawn do
|
|
550
552
|
local group_name = string.format("%s", groupsToSpawn[groupIndex])
|
|
551
553
|
local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
|
|
552
554
|
dcs_groups:ForEachGroupAlive(function(group_alive)
|
|
553
|
-
|
|
555
|
+
Jtff_log.info(string.format("SET Engage Air Weapons of group %s at %s", group_alive:GetName(), tostring(value)),"GENERAL")
|
|
554
556
|
if (value) then
|
|
555
557
|
group_alive:SetAIOn()
|
|
556
558
|
end
|
|
@@ -559,14 +561,14 @@ function setEngageAirWeapons(param)
|
|
|
559
561
|
end
|
|
560
562
|
end
|
|
561
563
|
|
|
562
|
-
function
|
|
564
|
+
function SmokeOnSubRange(param)
|
|
563
565
|
local groupsToSpawn = param[1]
|
|
564
566
|
local displayToCoalition = param[2]
|
|
565
567
|
for groupIndex = 1, #groupsToSpawn do
|
|
566
568
|
local group_name = string.format("%s", groupsToSpawn[groupIndex])
|
|
567
569
|
local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
|
|
568
570
|
dcs_groups:ForEachGroupAlive(function(group_alive)
|
|
569
|
-
|
|
571
|
+
Jtff_log.info(string.format("Smoke on group %s", group_alive:GetName()),"GENERAL")
|
|
570
572
|
local list_units = group_alive:GetUnits()
|
|
571
573
|
local set_units_red = SET_UNIT:New()
|
|
572
574
|
local set_units_blue = SET_UNIT:New()
|
|
@@ -577,14 +579,14 @@ function smokeOnSubRange(param)
|
|
|
577
579
|
end
|
|
578
580
|
end
|
|
579
581
|
if (set_units_red:CountAlive() > 0) then
|
|
580
|
-
local unit_red_to_smoke =
|
|
582
|
+
local unit_red_to_smoke = GetMaxThreatUnit(set_units_red)
|
|
581
583
|
if (unit_red_to_smoke) then
|
|
582
584
|
unit_red_to_smoke:SmokeRed()
|
|
583
585
|
MESSAGE:NewType(string.format("[%s] Red smoke on : %s", group_alive:GetName(),
|
|
584
586
|
unit_red_to_smoke:GetTypeName()), MESSAGE.Type.Overview):ToCoalition(displayToCoalition)
|
|
585
587
|
end
|
|
586
588
|
elseif (set_units_blue:CountAlive() > 0) then
|
|
587
|
-
local unit_blue_to_smoke =
|
|
589
|
+
local unit_blue_to_smoke = GetMaxThreatUnit(set_units_blue)
|
|
588
590
|
if (unit_blue_to_smoke) then
|
|
589
591
|
unit_blue_to_smoke:SmokeBlue()
|
|
590
592
|
MESSAGE:NewType(string.format("[%s] Blue smoke on : %s", group_alive:GetName(),
|
|
@@ -595,78 +597,78 @@ function smokeOnSubRange(param)
|
|
|
595
597
|
end
|
|
596
598
|
end
|
|
597
599
|
|
|
598
|
-
function
|
|
600
|
+
function GiveToClientGroupCoordinates(param)
|
|
599
601
|
local groupsToSpawn = param[1]
|
|
600
602
|
for i = 1, #groupsToSpawn do
|
|
601
603
|
local group_name = string.format("%s", groupsToSpawn[i])
|
|
602
|
-
|
|
604
|
+
Jtff_log.debug(string.format("Coordinates of all groups with name prefix %s", group_name),"GENERAL")
|
|
603
605
|
local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
|
|
604
|
-
|
|
606
|
+
Set_AllClients:ForEachClient(function(client)
|
|
605
607
|
if (client:IsActive()) then
|
|
606
|
-
|
|
608
|
+
Jtff_log.debug(string.format("For Client %s ", client:GetName()),"GENERAL")
|
|
607
609
|
local coordinate_txt = ""
|
|
608
610
|
dcs_groups:ForEachGroupAlive(function(group_alive)
|
|
609
|
-
|
|
611
|
+
Jtff_log.debug(string.format("Coordinates of the group %s", group_alive:GetName()),"GENERAL")
|
|
610
612
|
local coordinate = group_alive:GetCoordinate()
|
|
611
613
|
local setting = _DATABASE:GetPlayerSettings(client:GetPlayerName())
|
|
612
614
|
local coordinate_string = ""
|
|
613
615
|
if (setting:IsA2G_LL_DDM()) then
|
|
614
616
|
coordinate_string = coordinate:ToStringLLDDM(setting)
|
|
615
|
-
|
|
617
|
+
Jtff_log.debug(string.format("%s IsA2G_LL_DDM", client:GetName()),"GENERAL")
|
|
616
618
|
elseif (setting:IsA2G_MGRS()) then
|
|
617
619
|
coordinate_string = coordinate:ToStringMGRS(setting)
|
|
618
|
-
|
|
620
|
+
Jtff_log.debug(string.format("%s IsA2G_MGRS", client:GetName()),"GENERAL")
|
|
619
621
|
elseif (setting:IsA2G_LL_DMS()) then
|
|
620
622
|
coordinate_string = coordinate:ToStringLLDMS(setting)
|
|
621
|
-
|
|
623
|
+
Jtff_log.debug(string.format("%s IsA2G_LL_DMS", client:GetName()),"GENERAL")
|
|
622
624
|
elseif (setting:IsA2G_BR()) then
|
|
623
625
|
coordinate_string = coordinate:ToStringBR(client:GetCoordinate(), setting)
|
|
624
|
-
|
|
626
|
+
Jtff_log.debug(string.format("%s IsA2G_BR", client:GetName()),"GENERAL")
|
|
625
627
|
end
|
|
626
|
-
|
|
628
|
+
Jtff_log.debug(string.format("coordinate_txt [%s] : %s", group_alive:GetName(), coordinate_string),"GENERAL")
|
|
627
629
|
coordinate_txt = string.format("%s[%s] : %s\n", coordinate_txt, group_alive:GetName(),
|
|
628
630
|
coordinate_string)
|
|
629
631
|
end)
|
|
630
|
-
|
|
632
|
+
Jtff_log.debug(string.format("Message to Client %s : %s", client:GetName(), coordinate_txt),"GENERAL")
|
|
631
633
|
MESSAGE:NewType(coordinate_txt, MESSAGE.Type.Detailed):ToClient(client)
|
|
632
634
|
end
|
|
633
635
|
end)
|
|
634
636
|
end
|
|
635
637
|
end
|
|
636
638
|
|
|
637
|
-
function
|
|
639
|
+
function GiveListOfGroupsAliveInRange(param)
|
|
638
640
|
local groupsToSpawn = param[1]
|
|
639
641
|
local rangeConfig = param[2]
|
|
640
642
|
local subRangeConfig = param[3]
|
|
641
|
-
|
|
643
|
+
Jtff_log.debug(string.format("List of groups in range %s-%s", rangeConfig.name, subRangeConfig.name),"RANGE")
|
|
642
644
|
local message = string.format("Targets groups in Range %s-%s :", rangeConfig.name, subRangeConfig.name)
|
|
643
645
|
for i = 1, #groupsToSpawn do
|
|
644
646
|
local group_name = string.format("%s", groupsToSpawn[i])
|
|
645
647
|
local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
|
|
646
648
|
dcs_groups:ForEachGroupAlive(function(group_alive)
|
|
647
|
-
|
|
649
|
+
Jtff_log.debug(string.format("group %s", group_alive:GetName()),"RANGE")
|
|
648
650
|
message = string.format("%s %s | ", message, group_alive:GetName());
|
|
649
651
|
end)
|
|
650
652
|
end
|
|
651
|
-
|
|
653
|
+
Set_AllClients:ForEachClient(function(client)
|
|
652
654
|
if (client:IsActive()) then
|
|
653
655
|
MESSAGE:NewType(message, MESSAGE.Type.Information):ToClient(client)
|
|
654
656
|
end
|
|
655
657
|
end)
|
|
656
658
|
end
|
|
657
659
|
|
|
658
|
-
function
|
|
660
|
+
function GiveListOfUnitsAliveInGroup(param)
|
|
659
661
|
local groupsToSpawn = param[1]
|
|
660
662
|
local side = param[2]
|
|
661
663
|
local number_to_display = param[3]
|
|
662
664
|
for i = 1, #groupsToSpawn do
|
|
663
665
|
local group_name = string.format("%s", groupsToSpawn[i])
|
|
664
|
-
|
|
666
|
+
Jtff_log.debug(string.format("List of units of all groups with name prefix %s", group_name),"GENERAL")
|
|
665
667
|
local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
|
|
666
668
|
dcs_groups:ForEachGroupAlive(function(group_alive)
|
|
667
|
-
|
|
669
|
+
Jtff_log.debug(string.format("List of units of the group %s", group_alive:GetName()),"GENERAL")
|
|
668
670
|
local info_unit_header = string.format("Units list of the group [%s]:", group_name)
|
|
669
|
-
|
|
671
|
+
Set_AllClients:ForEachClient(function(client)
|
|
670
672
|
if (client:IsActive()) then
|
|
671
673
|
MESSAGE:NewType(info_unit_header, MESSAGE.Type.Overview):ToClient(client)
|
|
672
674
|
end
|
|
@@ -677,7 +679,7 @@ function giveListOfUnitsAliveInGroup(param)
|
|
|
677
679
|
local unit_tmp = list_units[index]
|
|
678
680
|
if (unit_tmp:IsAlive() and unit_tmp:GetCoalition() ~= side) then
|
|
679
681
|
set_units:AddUnit(unit_tmp)
|
|
680
|
-
|
|
682
|
+
Jtff_log.debug(string.format("Type : %s", unit_tmp:GetTypeName()),"GENERAL")
|
|
681
683
|
end
|
|
682
684
|
end
|
|
683
685
|
local increment = 0;
|
|
@@ -689,7 +691,7 @@ function giveListOfUnitsAliveInGroup(param)
|
|
|
689
691
|
local unit_coordinate_for_client = ""
|
|
690
692
|
local unit_altitude_for_client = 0
|
|
691
693
|
local unit_altitude_for_client_unit = ""
|
|
692
|
-
|
|
694
|
+
Set_AllClients:ForEachClient(function(client)
|
|
693
695
|
if (client:IsActive()) then
|
|
694
696
|
local setting = _DATABASE:GetPlayerSettings(client:GetPlayerName())
|
|
695
697
|
unit_coordinate_for_client = ""
|
|
@@ -723,17 +725,17 @@ function giveListOfUnitsAliveInGroup(param)
|
|
|
723
725
|
end
|
|
724
726
|
end
|
|
725
727
|
|
|
726
|
-
function
|
|
728
|
+
function MarkGroupOnMap(param)
|
|
727
729
|
local groupsToSpawn = param[1]
|
|
728
730
|
local side = param[2]
|
|
729
731
|
for index = 1, #groupsToSpawn do
|
|
730
732
|
local group_name = string.format("%s", groupsToSpawn[index])
|
|
731
|
-
|
|
733
|
+
Jtff_log.info(string.format("Mark on map all groups with name prefix %s", group_name),"MARK")
|
|
732
734
|
local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
|
|
733
735
|
dcs_groups:ForEachGroupAlive(function(group_alive)
|
|
734
|
-
|
|
736
|
+
Jtff_log.info(string.format("Mark on map the group %s", group_alive:GetName()),"MARK")
|
|
735
737
|
local coordinate = group_alive:GetCoordinate()
|
|
736
|
-
|
|
738
|
+
Jtff_map_marker[group_alive:GetName()] = coordinate:MarkToCoalition(group_alive:GetName(), side)
|
|
737
739
|
end)
|
|
738
740
|
end
|
|
739
741
|
end
|
|
@@ -749,7 +751,7 @@ function SpawnRangesDelay(param)
|
|
|
749
751
|
-- 7 : boolean for message warning
|
|
750
752
|
local rangeConfig = param[2]
|
|
751
753
|
local subRangeConfig = param[3]
|
|
752
|
-
local delay = param[4] or
|
|
754
|
+
local delay = param[4] or SpawnStandardDelay
|
|
753
755
|
local myfunc = param[5]
|
|
754
756
|
local sound_warning = true
|
|
755
757
|
if (type(param[6]) ~= "nil") then
|
|
@@ -760,7 +762,7 @@ function SpawnRangesDelay(param)
|
|
|
760
762
|
message_warning = param[7]
|
|
761
763
|
end
|
|
762
764
|
if ( sound_warning ) then
|
|
763
|
-
|
|
765
|
+
Sound2Bip:ToAll()
|
|
764
766
|
end
|
|
765
767
|
if ( message_warning ) then
|
|
766
768
|
MESSAGE:NewType(string.format("Warning, Range Units %s(%s) will spawn in %d sec", rangeConfig.name, subRangeConfig.name, delay), MESSAGE.Type.Update):ToAll()
|
|
@@ -778,7 +780,7 @@ function SpawnWholeRangesDelay(param)
|
|
|
778
780
|
-- 6 : boolean for message warning
|
|
779
781
|
local parentRangeMenu = param[1]
|
|
780
782
|
local rangeConfig = param[2]
|
|
781
|
-
local delay = param[3] or
|
|
783
|
+
local delay = param[3] or SpawnStandardDelay
|
|
782
784
|
local myfunc = param[4]
|
|
783
785
|
local sound_warning = true
|
|
784
786
|
if (type(param[5]) ~= "nil") then
|
|
@@ -790,7 +792,7 @@ function SpawnWholeRangesDelay(param)
|
|
|
790
792
|
end
|
|
791
793
|
parentRangeMenu:RemoveSubMenus()
|
|
792
794
|
if (rangeConfig.subRange) then
|
|
793
|
-
|
|
795
|
+
Sound2Bip:ToAll()
|
|
794
796
|
for subIndex, subRangeConfig in ipairs(rangeConfig.subRange) do
|
|
795
797
|
local radioMenuSubRange = MENU_COALITION:New(
|
|
796
798
|
rangeConfig.benefit_coalition,
|
|
@@ -834,7 +836,7 @@ function SpawnWholeRangesDelay(param)
|
|
|
834
836
|
rangeConfig.benefit_coalition,
|
|
835
837
|
"Delete whole Range",
|
|
836
838
|
parentRangeMenu,
|
|
837
|
-
|
|
839
|
+
DeleteWholeRangeUnits,
|
|
838
840
|
{
|
|
839
841
|
rangeConfig,
|
|
840
842
|
parentRangeMenu
|
|
@@ -863,28 +865,28 @@ function SpawnRanges(param)
|
|
|
863
865
|
local activateAI = subRangeConfig.AI
|
|
864
866
|
local redAlert = subRangeConfig.redAlert
|
|
865
867
|
|
|
866
|
-
|
|
868
|
+
Jtff_log.info(string.format("SpawnRanges : Range %s - Targets %s", rangeName, subRangeName),"RANGE")
|
|
867
869
|
if (staticsToSpawn ~= nil) then
|
|
868
870
|
for index, staticToSpawn in ipairs(staticsToSpawn) do
|
|
869
|
-
local spawnStatic =
|
|
870
|
-
if (staticToSpawn.name ~= nil) then
|
|
871
|
+
local spawnStatic = {}
|
|
872
|
+
if (type(staticToSpawn.name) ~= 'nil') then
|
|
871
873
|
local staticNameToSpawn = string.format("%s", staticToSpawn.name)
|
|
872
|
-
spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn)
|
|
874
|
+
spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn) or {}
|
|
873
875
|
if (staticToSpawn.coalition ~= nil) then
|
|
874
876
|
if (staticToSpawn.coalition == coalition.side.BLUE) then
|
|
875
|
-
spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn, country.id.CJTF_BLUE)
|
|
877
|
+
spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn, country.id.CJTF_BLUE) or {}
|
|
876
878
|
elseif (staticToSpawn.coalition == coalition.side.RED) then
|
|
877
|
-
spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn, country.id.CJTF_RED)
|
|
879
|
+
spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn, country.id.CJTF_RED) or {}
|
|
878
880
|
else
|
|
879
|
-
spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn, country.id.UN_PEACEKEEPERS)
|
|
881
|
+
spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn, country.id.UN_PEACEKEEPERS) or {}
|
|
880
882
|
end
|
|
881
883
|
end
|
|
882
884
|
local x = staticToSpawn.x
|
|
883
885
|
local y = staticToSpawn.y
|
|
884
886
|
local heading = staticToSpawn.heading
|
|
885
887
|
local name = string.format("%s_%s_%i", subRangeName, staticNameToSpawn,index)
|
|
886
|
-
local static = spawnStatic:SpawnFromCoordinate( COORDINATE:NewFromVec2(
|
|
887
|
-
|
|
888
|
+
local static = spawnStatic:SpawnFromCoordinate( COORDINATE:NewFromVec2( x, y ), heading, name )
|
|
889
|
+
Jtff_log.info(string.format("Static to spawn %s at %i,%i -> %s", static:GetDCSObject():getTypeName(), x, y, static:GetDCSObject():getName()),"RANGE")
|
|
888
890
|
elseif (staticToSpawn.type ~= nil and staticToSpawn.category ~= nil) then
|
|
889
891
|
local staticTypeToSpawn = string.format("%s", staticToSpawn.type)
|
|
890
892
|
local staticCategoryToSpawn = string.format("%s", staticToSpawn.category)
|
|
@@ -892,16 +894,16 @@ function SpawnRanges(param)
|
|
|
892
894
|
local y = staticToSpawn.y
|
|
893
895
|
--spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn)
|
|
894
896
|
if (staticToSpawn.type == "big_smoke" and staticToSpawn.category == "Effects") then
|
|
895
|
-
local landAltitude = COORDINATE:NewFromVec2( {x
|
|
897
|
+
local landAltitude = COORDINATE:NewFromVec2( {x=x, y=y} ):GetLandHeight()
|
|
896
898
|
trigger.action.effectSmokeBig({ x = x, y = landAltitude, z = y}, staticToSpawn.effectPreset or 1, staticToSpawn.effectTransparency or 1)
|
|
897
899
|
else
|
|
898
|
-
if (staticToSpawn.coalition ~= nil) then
|
|
900
|
+
if type(staticToSpawn.coalition ~= 'nil') then
|
|
899
901
|
if (staticToSpawn.coalition == coalition.side.BLUE) then
|
|
900
|
-
spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn, country.id.CJTF_BLUE)
|
|
902
|
+
spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn, country.id.CJTF_BLUE) or {}
|
|
901
903
|
elseif (staticToSpawn.coalition == coalition.side.RED) then
|
|
902
|
-
spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn, country.id.CJTF_RED)
|
|
904
|
+
spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn, country.id.CJTF_RED) or {}
|
|
903
905
|
else
|
|
904
|
-
spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn, country.id.UN_PEACEKEEPERS)
|
|
906
|
+
spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn, country.id.UN_PEACEKEEPERS) or {}
|
|
905
907
|
end
|
|
906
908
|
end
|
|
907
909
|
local heading = staticToSpawn.heading
|
|
@@ -912,15 +914,15 @@ function SpawnRanges(param)
|
|
|
912
914
|
if (staticToSpawn.dead ~= nil) then
|
|
913
915
|
spawnStatic:InitDead(staticToSpawn.dead)
|
|
914
916
|
end
|
|
915
|
-
local static = spawnStatic:SpawnFromCoordinate( COORDINATE:NewFromVec2({x
|
|
916
|
-
|
|
917
|
+
local static = spawnStatic:SpawnFromCoordinate( COORDINATE:NewFromVec2( {x=x, y=y} ), heading, name )
|
|
918
|
+
Jtff_log.info(string.format("Static type to spawn %s at %i,%i -> %s", static:GetDCSObject():getTypeName(), x, y, static:GetDCSObject():getName()),"RANGE")
|
|
917
919
|
end
|
|
918
920
|
else
|
|
919
|
-
|
|
921
|
+
Jtff_log.warn(string.format("Static to spawn has no name or type!"),"RANGE")
|
|
920
922
|
end
|
|
921
923
|
end
|
|
922
924
|
else
|
|
923
|
-
|
|
925
|
+
Jtff_log.warn(string.format("No static in %s", subRangeName),"RANGE")
|
|
924
926
|
end
|
|
925
927
|
|
|
926
928
|
if (randomGroupsToSpawn ~= nil) then
|
|
@@ -940,14 +942,14 @@ function SpawnRanges(param)
|
|
|
940
942
|
|
|
941
943
|
if (GROUP:FindByName(groupNameToSpawn) ~= nil) then
|
|
942
944
|
local spawnGroup = SPAWN:New(groupNameToSpawn)
|
|
943
|
-
|
|
945
|
+
Jtff_log.info(string.format("SPAWN %s", groupNameToSpawn), "RANGE")
|
|
944
946
|
local groupSpawning
|
|
945
947
|
if (subRangeConfig.spawnZone) then
|
|
946
948
|
groupSpawning = spawnGroup:SpawnInZone(ZONE:New(subRangeConfig.spawnZone),true)
|
|
947
949
|
else
|
|
948
950
|
groupSpawning = spawnGroup:Spawn()
|
|
949
951
|
end
|
|
950
|
-
|
|
952
|
+
MarkGroupOnMap({{groupNameToSpawn}, rangeConfig.benefit_coalition})
|
|
951
953
|
if (holdFire) then
|
|
952
954
|
groupSpawning:OptionROEHoldFire()
|
|
953
955
|
else
|
|
@@ -969,11 +971,11 @@ function SpawnRanges(param)
|
|
|
969
971
|
groupSpawning:OptionAlarmStateAuto()
|
|
970
972
|
end
|
|
971
973
|
if (string.find(groupNameToSpawn, "SAM") ~= nil) then
|
|
972
|
-
|
|
973
|
-
|
|
974
|
+
Jtff_sead:UpdateSet(groupNameToSpawn)
|
|
975
|
+
Jtff_log.info(string.format("SEAD for %s", groupNameToSpawn),"RANGE")
|
|
974
976
|
end
|
|
975
977
|
else
|
|
976
|
-
|
|
978
|
+
Jtff_log.error(string.format("GROUP to spawn %s not found in mission", groupNameToSpawn),"RANGE")
|
|
977
979
|
end
|
|
978
980
|
end
|
|
979
981
|
end
|
|
@@ -983,7 +985,7 @@ function SpawnRanges(param)
|
|
|
983
985
|
local groupNameToSpawn = string.format("%s", groupsToSpawn[i])
|
|
984
986
|
if (GROUP:FindByName(groupNameToSpawn) ~= nil) then
|
|
985
987
|
local spawnGroup = SPAWN:New(groupNameToSpawn)
|
|
986
|
-
|
|
988
|
+
Jtff_log.info(string.format("SPAWN %s", groupNameToSpawn), "RANGE")
|
|
987
989
|
local groupSpawning
|
|
988
990
|
if (subRangeConfig.spawnZone) then
|
|
989
991
|
groupSpawning = spawnGroup:SpawnInZone(ZONE:New(subRangeConfig.spawnZone),true)
|
|
@@ -1011,49 +1013,49 @@ function SpawnRanges(param)
|
|
|
1011
1013
|
groupSpawning:OptionAlarmStateAuto()
|
|
1012
1014
|
end
|
|
1013
1015
|
if (string.find(groupNameToSpawn, "SAM") ~= nil) then
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
+
Jtff_sead:UpdateSet(groupNameToSpawn)
|
|
1017
|
+
Jtff_log.info(string.format("SEAD for %s", groupNameToSpawn),"RANGE")
|
|
1016
1018
|
end
|
|
1017
1019
|
else
|
|
1018
|
-
|
|
1020
|
+
Jtff_log.error(string.format("GROUP to spawn %s not found in mission", groupNameToSpawn),"RANGE")
|
|
1019
1021
|
end
|
|
1020
1022
|
end
|
|
1021
|
-
|
|
1023
|
+
MarkGroupOnMap({groupsToSpawn, rangeConfig.benefit_coalition})
|
|
1022
1024
|
else
|
|
1023
|
-
|
|
1025
|
+
Jtff_log.warn(string.format("No GROUP to spawn in subRange %s settings !",subRangeName),"RANGE")
|
|
1024
1026
|
end
|
|
1025
1027
|
|
|
1026
1028
|
|
|
1027
1029
|
radioCommandSubRange:RemoveSubMenus()
|
|
1028
1030
|
local CommandZoneDetroy = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Delete", radioCommandSubRange,
|
|
1029
|
-
|
|
1031
|
+
DeleteSubRangeUnits, {groupsToSpawn, rangeConfig, subRangeConfig, radioCommandSubRange, true})
|
|
1030
1032
|
local ROE = MENU_COALITION:New(rangeConfig.benefit_coalition, "ROE", radioCommandSubRange)
|
|
1031
|
-
local ROEOpenFire = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Open Fire", ROE,
|
|
1033
|
+
local ROEOpenFire = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Open Fire", ROE, SetROE,
|
|
1032
1034
|
{groupsToSpawn, ENUMS.ROE.OpenFire})
|
|
1033
|
-
local ROEReturnFire = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Return Fire", ROE,
|
|
1035
|
+
local ROEReturnFire = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Return Fire", ROE, SetROE,
|
|
1034
1036
|
{groupsToSpawn, ENUMS.ROE.ReturnFire})
|
|
1035
|
-
local ROEHoldFire = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Hold Fire", ROE,
|
|
1037
|
+
local ROEHoldFire = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Hold Fire", ROE, SetROE,
|
|
1036
1038
|
{groupsToSpawn, ENUMS.ROE.WeaponHold})
|
|
1037
1039
|
local AlarmState = MENU_COALITION:New(rangeConfig.benefit_coalition, "Alarm State", radioCommandSubRange)
|
|
1038
|
-
local AlarmStateAuto = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Auto", AlarmState,
|
|
1040
|
+
local AlarmStateAuto = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Auto", AlarmState, SetAlarmState,
|
|
1039
1041
|
{groupsToSpawn, ENUMS.AlarmState.Auto})
|
|
1040
|
-
local AlarmStateGreen = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Green", AlarmState,
|
|
1042
|
+
local AlarmStateGreen = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Green", AlarmState, SetAlarmState,
|
|
1041
1043
|
{groupsToSpawn, ENUMS.AlarmState.Green})
|
|
1042
|
-
local AlarmStateRed = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Red", AlarmState,
|
|
1044
|
+
local AlarmStateRed = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Red", AlarmState, SetAlarmState,
|
|
1043
1045
|
{groupsToSpawn, ENUMS.AlarmState.Red})
|
|
1044
1046
|
local Engage_Air_Weapons = MENU_COALITION:New(rangeConfig.benefit_coalition, "Engage Air Weapons", radioCommandSubRange)
|
|
1045
|
-
local Engage_Air_Weapons_True = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "True", Engage_Air_Weapons,
|
|
1047
|
+
local Engage_Air_Weapons_True = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "True", Engage_Air_Weapons, SetEngageAirWeapons,
|
|
1046
1048
|
{groupsToSpawn, true})
|
|
1047
|
-
local Engage_Air_Weapons_False = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "False", Engage_Air_Weapons,
|
|
1049
|
+
local Engage_Air_Weapons_False = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "False", Engage_Air_Weapons, SetEngageAirWeapons,
|
|
1048
1050
|
{groupsToSpawn, false})
|
|
1049
1051
|
local CommandZoneFumigene = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Smoke", radioCommandSubRange,
|
|
1050
|
-
|
|
1052
|
+
SmokeOnSubRange, {groupsToSpawn, rangeConfig.benefit_coalition})
|
|
1051
1053
|
local CommandZoneCoord = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Coordinates",
|
|
1052
|
-
radioCommandSubRange,
|
|
1054
|
+
radioCommandSubRange, GiveToClientGroupCoordinates, {groupsToSpawn})
|
|
1053
1055
|
local CommandZoneListGroup = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "List Groups",
|
|
1054
|
-
radioCommandSubRange,
|
|
1056
|
+
radioCommandSubRange, GiveListOfGroupsAliveInRange, {groupsToSpawn, rangeConfig, subRangeConfig})
|
|
1055
1057
|
local CommandZoneList = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "List Units",
|
|
1056
|
-
radioCommandSubRange,
|
|
1058
|
+
radioCommandSubRange, GiveListOfUnitsAliveInGroup, {groupsToSpawn, rangeConfig.benefit_coalition, 5})
|
|
1057
1059
|
MESSAGE:NewType(string.format("Units in range %s(%s) in place", rangeName, subRangeName), MESSAGE.Type.Information)
|
|
1058
1060
|
:ToCoalition(rangeConfig.benefit_coalition)
|
|
1059
1061
|
end
|
|
@@ -1075,12 +1077,12 @@ function SpawnFacRanges(param)
|
|
|
1075
1077
|
local groupsToSpawn = facSubRangeConfig.groupsToSpawn
|
|
1076
1078
|
local staticsToSpawn = facSubRangeConfig.staticsToSpawn
|
|
1077
1079
|
|
|
1078
|
-
|
|
1080
|
+
Jtff_log.info(string.format("SpawnFacRanges : %s-%s", facRangeName, facSubRangeName),"RANGE")
|
|
1079
1081
|
for i = 1, #groupsToSpawn do
|
|
1080
1082
|
local groupNameToSpawn = string.format("%s", groupsToSpawn[i])
|
|
1081
1083
|
if (GROUP:FindByName(groupNameToSpawn) ~= nil) then
|
|
1082
1084
|
local spawnGroup = SPAWN:New(groupNameToSpawn)
|
|
1083
|
-
|
|
1085
|
+
Jtff_log.info(string.format("SPAWN %s", groupNameToSpawn),"RANGE")
|
|
1084
1086
|
local groupSpawning
|
|
1085
1087
|
if (facSubRangeConfig.spawnZone) then
|
|
1086
1088
|
groupSpawning = spawnGroup:SpawnInZone(ZONE:New(facSubRangeConfig.spawnZone),true)
|
|
@@ -1089,27 +1091,27 @@ function SpawnFacRanges(param)
|
|
|
1089
1091
|
end
|
|
1090
1092
|
groupSpawning:SetCommandInvisible(true)
|
|
1091
1093
|
else
|
|
1092
|
-
|
|
1094
|
+
Jtff_log.warn(string.format("GROUP to spawn %s not found in mission", groupNameToSpawn),"RANGE")
|
|
1093
1095
|
end
|
|
1094
1096
|
end
|
|
1095
1097
|
|
|
1096
1098
|
radioCommandSubRange:RemoveSubMenus()
|
|
1097
1099
|
local CommandZoneDetroy = MENU_COALITION_COMMAND:New(facRangeConfig.benefit_coalition, "Delete", radioCommandSubRange,
|
|
1098
|
-
|
|
1100
|
+
DeleteSubRangeUnits, { groupsToSpawn, facRangeConfig, facSubRangeConfig, radioCommandSubRange, true})
|
|
1099
1101
|
local CommandZoneFumigene = MENU_COALITION_COMMAND:New(facRangeConfig.benefit_coalition, "Smoke", radioCommandSubRange,
|
|
1100
|
-
|
|
1102
|
+
SmokeOnSubRange, { groupsToSpawn, facRangeConfig.benefit_coalition})
|
|
1101
1103
|
local CommandZoneCoord = MENU_COALITION_COMMAND:New(facRangeConfig.benefit_coalition, "Coordinates",
|
|
1102
|
-
radioCommandSubRange,
|
|
1104
|
+
radioCommandSubRange, GiveToClientGroupCoordinates, {groupsToSpawn})
|
|
1103
1105
|
local CommandZoneListGroup = MENU_COALITION_COMMAND:New(facRangeConfig.benefit_coalition, "List Groups",
|
|
1104
|
-
radioCommandSubRange,
|
|
1106
|
+
radioCommandSubRange, GiveListOfGroupsAliveInRange, { groupsToSpawn, facRangeConfig, facSubRangeConfig })
|
|
1105
1107
|
local CommandZoneList = MENU_COALITION_COMMAND:New(facRangeConfig.benefit_coalition, "List Units",
|
|
1106
|
-
radioCommandSubRange,
|
|
1108
|
+
radioCommandSubRange, GiveListOfUnitsAliveInGroup, { groupsToSpawn, facRangeConfig.benefit_coalition, 5})
|
|
1107
1109
|
MESSAGE:NewType(string.format("FAC in range %s(%s) in place", facRangeName, facSubRangeName), MESSAGE.Type.Information)
|
|
1108
1110
|
:ToBlue()
|
|
1109
|
-
|
|
1111
|
+
MarkGroupOnMap({ groupsToSpawn, facRangeConfig.benefit_coalition})
|
|
1110
1112
|
end
|
|
1111
1113
|
|
|
1112
|
-
function
|
|
1114
|
+
function AddSubRangeRadioMenus(radioCommandSubRange, rangeConfig, subRangeConfig)
|
|
1113
1115
|
local RadioCommandAdd = MENU_COALITION_COMMAND:New(
|
|
1114
1116
|
rangeConfig.benefit_coalition,
|
|
1115
1117
|
"Spawn",
|
|
@@ -1119,8 +1121,8 @@ function addSubRangeRadioMenus(radioCommandSubRange, rangeConfig, subRangeConfig
|
|
|
1119
1121
|
radioCommandSubRange,
|
|
1120
1122
|
rangeConfig,
|
|
1121
1123
|
subRangeConfig,
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
+
SpawnStandardDelay,
|
|
1125
|
+
AddSubRangeRadioMenus
|
|
1124
1126
|
}
|
|
1125
1127
|
)
|
|
1126
1128
|
end
|
|
@@ -1134,7 +1136,7 @@ function AddWholeRangeCoalitionCommandMenus(radioCommandRange, rangeConfig)
|
|
|
1134
1136
|
{
|
|
1135
1137
|
radioCommandRange,
|
|
1136
1138
|
rangeConfig,
|
|
1137
|
-
|
|
1139
|
+
SpawnStandardDelay,
|
|
1138
1140
|
AddWholeRangeCoalitionCommandMenus
|
|
1139
1141
|
}
|
|
1140
1142
|
)
|
|
@@ -1142,7 +1144,7 @@ function AddWholeRangeCoalitionCommandMenus(radioCommandRange, rangeConfig)
|
|
|
1142
1144
|
rangeConfig.benefit_coalition,
|
|
1143
1145
|
"Delete whole Range",
|
|
1144
1146
|
radioCommandRange,
|
|
1145
|
-
|
|
1147
|
+
DeleteWholeRangeUnits,
|
|
1146
1148
|
{
|
|
1147
1149
|
rangeConfig,
|
|
1148
1150
|
radioCommandRange
|
|
@@ -1161,7 +1163,7 @@ function AddFacFunction(radioCommandSubRange, facRangeConfig, facSubRangeConfig)
|
|
|
1161
1163
|
radioCommandSubRange,
|
|
1162
1164
|
facRangeConfig,
|
|
1163
1165
|
facSubRangeConfig,
|
|
1164
|
-
|
|
1166
|
+
SpawnStandardDelay,
|
|
1165
1167
|
AddFacFunction
|
|
1166
1168
|
}
|
|
1167
1169
|
)
|
|
@@ -1175,10 +1177,10 @@ function GetTableLng(tbl)
|
|
|
1175
1177
|
return getN
|
|
1176
1178
|
end
|
|
1177
1179
|
|
|
1178
|
-
function
|
|
1180
|
+
function GetSoundFilesPrefix()
|
|
1179
1181
|
local strPrefix
|
|
1180
1182
|
local lfs = require("lfs")
|
|
1181
|
-
if (
|
|
1183
|
+
if (Use_jtff_sound_mod) then
|
|
1182
1184
|
strPrefix = lfs.writedir() .. 'Sounds/JTFF-Missions/'
|
|
1183
1185
|
else
|
|
1184
1186
|
strPrefix = ""
|
|
@@ -1186,7 +1188,7 @@ function getSoundFilesPrefix()
|
|
|
1186
1188
|
return strPrefix
|
|
1187
1189
|
end
|
|
1188
1190
|
|
|
1189
|
-
function
|
|
1191
|
+
function SpawnStaticListWithUnitLink(layoutData, namePrefix, unitID, countryID)
|
|
1190
1192
|
for index, layoutObject in pairs(layoutData) do
|
|
1191
1193
|
local staticToSpawn = {
|
|
1192
1194
|
["name"] = namePrefix .. "-" .. index,
|
|
@@ -1209,10 +1211,684 @@ function spawnStaticListWithUnitLink(layoutData, namePrefix, unitID, countryID)
|
|
|
1209
1211
|
end
|
|
1210
1212
|
|
|
1211
1213
|
function ClientIsOnGround(client)
|
|
1212
|
-
|
|
1214
|
+
Jtff_log.trace(string.format("Client %s is tested if alive and OnGround", client:GetPlayer() or ""),"QRA")
|
|
1213
1215
|
return UNIT:Find(client:GetDCSObject()):IsAlive() and not(UNIT:Find(client:GetDCSObject()):InAir(true))
|
|
1214
1216
|
end
|
|
1215
1217
|
|
|
1218
|
+
--- find a #AIRWING object by its AirbaseName.
|
|
1219
|
+
-- @param #string airbaseName Airbase name.
|
|
1220
|
+
-- @return #AIRWING _airbase Found AIRWING object.
|
|
1221
|
+
-- @return #nil nil if no AIRWING object found.
|
|
1222
|
+
function FindAirwingByAirbaseName(airbaseName)
|
|
1223
|
+
if type(UNIT:FindByName(airbaseName)) ~= 'nil' then
|
|
1224
|
+
if type(AIRBOSSArray) ~= 'table' then
|
|
1225
|
+
return nil
|
|
1226
|
+
end
|
|
1227
|
+
for _key,_airboss in pairs(AIRBOSSArray) do
|
|
1228
|
+
if (_airboss.customconfig.carriername == airbaseName) then
|
|
1229
|
+
return _airboss.airwing
|
|
1230
|
+
end
|
|
1231
|
+
end
|
|
1232
|
+
end
|
|
1233
|
+
if type(AirbasesArray) ~= 'table' then
|
|
1234
|
+
return nil
|
|
1235
|
+
end
|
|
1236
|
+
for _key,_airbase in pairs(AirbasesArray) do
|
|
1237
|
+
if (_airbase.customconfig.name == airbaseName) then
|
|
1238
|
+
return _airbase.airwing
|
|
1239
|
+
end
|
|
1240
|
+
end
|
|
1241
|
+
return nil
|
|
1242
|
+
end
|
|
1243
|
+
|
|
1244
|
+
--- find a #AIRBOSS object by its alias.
|
|
1245
|
+
-- @param #string airbossUnitName Airboss unit name.
|
|
1246
|
+
-- @return #AIRBOSS value Found Airboss object.
|
|
1247
|
+
-- @return #nil nil if no Airboss object found.
|
|
1248
|
+
function FindAirbossByUnitName(airbossUnitName)
|
|
1249
|
+
if type(AIRBOSSArray) ~= 'table' then
|
|
1250
|
+
return nil
|
|
1251
|
+
end
|
|
1252
|
+
for key,value in pairs(AIRBOSSArray) do
|
|
1253
|
+
if (value.customconfig.carriername == airbossUnitName) then
|
|
1254
|
+
return value
|
|
1255
|
+
end
|
|
1256
|
+
end
|
|
1257
|
+
return nil
|
|
1258
|
+
end
|
|
1259
|
+
|
|
1260
|
+
--- find a #AIRBOSS object by its alias.
|
|
1261
|
+
-- @param #string airbossAlias Airboss alias.
|
|
1262
|
+
-- @return #AIRBOSS Found Airboss object.
|
|
1263
|
+
-- @return #nil if no Airboss object found.
|
|
1264
|
+
function FindAirbossByAlias(airbossAlias)
|
|
1265
|
+
if type(AIRBOSSArray) ~= 'table' then
|
|
1266
|
+
return nil
|
|
1267
|
+
end
|
|
1268
|
+
for index,value in pairs(AIRBOSSArray) do
|
|
1269
|
+
if (value.customconfig.alias == airbossAlias) then
|
|
1270
|
+
return value
|
|
1271
|
+
end
|
|
1272
|
+
end
|
|
1273
|
+
return nil
|
|
1274
|
+
end
|
|
1275
|
+
|
|
1276
|
+
-- @type AirwingConfig
|
|
1277
|
+
-- @field #string name Airwing name.
|
|
1278
|
+
-- @field #SquadronConfig[] squadrons Squadrons for the airwing.
|
|
1279
|
+
|
|
1280
|
+
|
|
1281
|
+
--- Parse an Airwing config Object.
|
|
1282
|
+
-- @param #JsonObject config Config object to parse
|
|
1283
|
+
-- @param #string parser_name Parser name ("AIRBASE", "AIRBOSS", etc...).
|
|
1284
|
+
-- @return #AirwingConfig airwingConfigJson Parsed Airwing object
|
|
1285
|
+
function ParseAirwingConfigJson(config, parser_name)
|
|
1286
|
+
local airwingConfigJson = {}
|
|
1287
|
+
-- **************************************************************************
|
|
1288
|
+
-- name
|
|
1289
|
+
-- **************************************************************************
|
|
1290
|
+
if type(config.name) == "string" then
|
|
1291
|
+
airwingConfigJson.name = config.name
|
|
1292
|
+
else
|
|
1293
|
+
Jtff_log.error("Airwing name is not a string, skipping airwing configuration", parser_name)
|
|
1294
|
+
return {}
|
|
1295
|
+
end
|
|
1296
|
+
-- **************************************************************************
|
|
1297
|
+
-- squadrons
|
|
1298
|
+
-- **************************************************************************
|
|
1299
|
+
if type(config.squadrons) == "table" then
|
|
1300
|
+
airwingConfigJson.squadrons = {}
|
|
1301
|
+
for _, _squadconfig in ipairs(config.squadrons) do
|
|
1302
|
+
table.insert(
|
|
1303
|
+
airwingConfigJson.squadrons,
|
|
1304
|
+
ParseSquadronConfigJson(_squadconfig, parser_name)
|
|
1305
|
+
)
|
|
1306
|
+
end
|
|
1307
|
+
else
|
|
1308
|
+
Jtff_log.error("Airwing squadrons is not a table, skipping airwing configuration", "AIRWING")
|
|
1309
|
+
config.squadrons = {}
|
|
1310
|
+
return config
|
|
1311
|
+
end
|
|
1312
|
+
return airwingConfigJson
|
|
1313
|
+
end
|
|
1314
|
+
|
|
1315
|
+
-- @type RadioConfig
|
|
1316
|
+
-- @field #number freq Frequency for the radio.
|
|
1317
|
+
-- @field #number modulation Modulation for the radio.
|
|
1318
|
+
-- @field #number power Radio power in Watts
|
|
1319
|
+
|
|
1320
|
+
--- Parse an Radio config Object.
|
|
1321
|
+
-- @param #JsonObject config Config object to parse
|
|
1322
|
+
-- @param #string parser_name Parser name ("AIRBASE", "AIRBOSS", etc...).
|
|
1323
|
+
-- @return #RadioConfig radioConfigJson Parsed Radio object
|
|
1324
|
+
function ParseRadioConfigJson(config, parser_name)
|
|
1325
|
+
local radioConfigJson = {}
|
|
1326
|
+
local default_freq = 251.000
|
|
1327
|
+
local default_power = 100
|
|
1328
|
+
local default_modulation = radio.modulation.AM
|
|
1329
|
+
-- **************************************************************************
|
|
1330
|
+
-- freq
|
|
1331
|
+
-- **************************************************************************
|
|
1332
|
+
radioConfigJson.freq = config.freq or default_freq
|
|
1333
|
+
-- **************************************************************************
|
|
1334
|
+
-- modulation
|
|
1335
|
+
-- **************************************************************************
|
|
1336
|
+
radioConfigJson.modulation = config.modulation or default_modulation
|
|
1337
|
+
-- **************************************************************************
|
|
1338
|
+
-- power
|
|
1339
|
+
-- **************************************************************************
|
|
1340
|
+
radioConfigJson.power = config.power or default_power
|
|
1341
|
+
return radioConfigJson
|
|
1342
|
+
end
|
|
1343
|
+
|
|
1344
|
+
-- @type tacanConfig
|
|
1345
|
+
-- @field #number channel Channel for the TACAN.
|
|
1346
|
+
-- @field #string morse Morse code for the TACAN.
|
|
1347
|
+
-- @field #string band Band for the TACAN.
|
|
1348
|
+
|
|
1349
|
+
--- Parse an TACAN config Object.
|
|
1350
|
+
-- @param #JsonObject config Config object to parse
|
|
1351
|
+
-- @param #string parser_name Parser name ("AIRBASE", "AIRBOSS", etc...).
|
|
1352
|
+
-- @return #tacanConfig tacanConfigJson Parsed Radio object
|
|
1353
|
+
function ParseTacanConfigJson(config, parser_name)
|
|
1354
|
+
local tacanConfigJson = {}
|
|
1355
|
+
local default_channel = 100
|
|
1356
|
+
local default_morse = 'TEX'
|
|
1357
|
+
local default_band = 'Y'
|
|
1358
|
+
if type(config) == "table" then
|
|
1359
|
+
-- **********************************************************************
|
|
1360
|
+
-- channel
|
|
1361
|
+
-- **********************************************************************
|
|
1362
|
+
tacanConfigJson.channel = config.channel or default_channel
|
|
1363
|
+
-- **************************************************************************
|
|
1364
|
+
-- morse
|
|
1365
|
+
-- **************************************************************************
|
|
1366
|
+
tacanConfigJson.morse = config.morse or default_morse
|
|
1367
|
+
-- **************************************************************************
|
|
1368
|
+
-- band
|
|
1369
|
+
-- **************************************************************************
|
|
1370
|
+
tacanConfigJson.band = config.band or default_band
|
|
1371
|
+
else
|
|
1372
|
+
Jtff_log.error("TACAN config is not a table, skipping TACAN configuration", parser_name)
|
|
1373
|
+
return {}
|
|
1374
|
+
end
|
|
1375
|
+
return tacanConfigJson
|
|
1376
|
+
end
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
-- @type SquadronConfig
|
|
1380
|
+
-- @field #string name Squadron name.
|
|
1381
|
+
-- @field #number fuellowthreshold Low Fuel threshold in percent.
|
|
1382
|
+
-- @field #boolean lowfuelrtb Enable Low Fuel RTB.
|
|
1383
|
+
-- @field #number grouping Grouping for the squadron.
|
|
1384
|
+
-- @field #number modex Modex for the squadron.
|
|
1385
|
+
-- @field #RadioConfig radio Radio configuration for the squadron.
|
|
1386
|
+
-- @field #number skill Skill for the squadron.
|
|
1387
|
+
-- @field #number turnovertime Turnover time in seconds.
|
|
1388
|
+
-- @field #number repairtime Repair time in seconds.
|
|
1389
|
+
-- @field #string livery Livery for the squadron.
|
|
1390
|
+
-- @field #PayloadConfig[] payloads Templates for the squadron.
|
|
1391
|
+
-- @field #number nb_aircrafts Number of aircrafts in the squadron.
|
|
1392
|
+
|
|
1393
|
+
--- Parse an Squadron config Object.
|
|
1394
|
+
-- @param #JsonObject config Config object to parse
|
|
1395
|
+
-- @param #string parser_name Parser name ("AIRBASE", "AIRBOSS", etc...).
|
|
1396
|
+
-- @return #SquadronConfig squadronConfigJson Parsed Squadron object
|
|
1397
|
+
function ParseSquadronConfigJson(config, parser_name)
|
|
1398
|
+
local squadronConfigJson = {}
|
|
1399
|
+
local default_nb_aircrafts = 6
|
|
1400
|
+
local default_fuellowthreshold = 25
|
|
1401
|
+
local default_lowfuelrtb = false
|
|
1402
|
+
local default_grouping = 1
|
|
1403
|
+
local default_modex = 400
|
|
1404
|
+
local default_radio = {freq = 251.000, modulation = radio.modulation.AM, power = 100}
|
|
1405
|
+
local default_skill = AI.Skill.GOOD
|
|
1406
|
+
local default_turnovertime = 10
|
|
1407
|
+
local default_repairtime = (default_turnovertime *2)
|
|
1408
|
+
local default_livery = ""
|
|
1409
|
+
-- **************************************************************************
|
|
1410
|
+
-- template
|
|
1411
|
+
-- **************************************************************************
|
|
1412
|
+
if type(config.template) == "string" then
|
|
1413
|
+
if type(GROUP:FindByName(config.template)) == 'nil' then
|
|
1414
|
+
Jtff_log.error(
|
|
1415
|
+
string.format(
|
|
1416
|
+
"Squadron template %s not found, skipping squadron template configuration",
|
|
1417
|
+
config.template
|
|
1418
|
+
),
|
|
1419
|
+
parser_name
|
|
1420
|
+
)
|
|
1421
|
+
return {}
|
|
1422
|
+
else
|
|
1423
|
+
squadronConfigJson.template = config.template
|
|
1424
|
+
end
|
|
1425
|
+
else
|
|
1426
|
+
Jtff_log.error("Squadron template is not a string, skipping squadron configuration", parser_name)
|
|
1427
|
+
return {}
|
|
1428
|
+
end
|
|
1429
|
+
-- **************************************************************************
|
|
1430
|
+
-- name
|
|
1431
|
+
-- **************************************************************************
|
|
1432
|
+
if type(config.name) == "string" then
|
|
1433
|
+
squadronConfigJson.name = config.name
|
|
1434
|
+
else
|
|
1435
|
+
Jtff_log.error("Squadron name is not a string, skipping squadron configuration", parser_name)
|
|
1436
|
+
return {}
|
|
1437
|
+
end
|
|
1438
|
+
-- **************************************************************************
|
|
1439
|
+
-- fuellowthreshold
|
|
1440
|
+
-- **************************************************************************
|
|
1441
|
+
squadronConfigJson.fuellowthreshold = config.fuellowthreshold or default_fuellowthreshold
|
|
1442
|
+
-- **************************************************************************
|
|
1443
|
+
-- lowfuelrtb
|
|
1444
|
+
-- **************************************************************************
|
|
1445
|
+
squadronConfigJson.lowfuelrtb = config.lowfuelrtb or default_lowfuelrtb
|
|
1446
|
+
-- **************************************************************************
|
|
1447
|
+
-- grouping
|
|
1448
|
+
-- **************************************************************************
|
|
1449
|
+
squadronConfigJson.grouping = config.grouping or default_grouping
|
|
1450
|
+
-- **************************************************************************
|
|
1451
|
+
-- modex
|
|
1452
|
+
-- **************************************************************************
|
|
1453
|
+
squadronConfigJson.modex = config.modex or default_modex
|
|
1454
|
+
-- **************************************************************************
|
|
1455
|
+
-- radio
|
|
1456
|
+
-- **************************************************************************
|
|
1457
|
+
if type(config.radio) == "table" then
|
|
1458
|
+
squadronConfigJson.radio = ParseRadioConfigJson(config.radio, parser_name)
|
|
1459
|
+
if next(squadronConfigJson.radio) == nil then
|
|
1460
|
+
Jtff_log.warn("Squadron radio is not a valid Radio object, skipping tanker configuration", parser_name)
|
|
1461
|
+
squadronConfigJson.radio = default_radio
|
|
1462
|
+
end
|
|
1463
|
+
else
|
|
1464
|
+
Jtff_log.warn(
|
|
1465
|
+
string.format(
|
|
1466
|
+
"Squadron %s radio config is not a table, apply default radio config",
|
|
1467
|
+
squadronConfigJson.name
|
|
1468
|
+
),
|
|
1469
|
+
parser_name
|
|
1470
|
+
)
|
|
1471
|
+
squadronConfigJson.radio = default_radio
|
|
1472
|
+
end
|
|
1473
|
+
-- **************************************************************************
|
|
1474
|
+
-- skill
|
|
1475
|
+
-- **************************************************************************
|
|
1476
|
+
squadronConfigJson.skill = config.skill or default_skill
|
|
1477
|
+
-- **************************************************************************
|
|
1478
|
+
-- turnovertime
|
|
1479
|
+
-- **************************************************************************
|
|
1480
|
+
squadronConfigJson.turnovertime = config.turnovertime or default_turnovertime
|
|
1481
|
+
-- **************************************************************************
|
|
1482
|
+
-- repairtime
|
|
1483
|
+
-- **************************************************************************
|
|
1484
|
+
squadronConfigJson.repairtime = config.repairtime or default_repairtime
|
|
1485
|
+
-- **************************************************************************
|
|
1486
|
+
-- livery
|
|
1487
|
+
-- **************************************************************************
|
|
1488
|
+
squadronConfigJson.livery = config.livery or default_livery
|
|
1489
|
+
-- **************************************************************************
|
|
1490
|
+
-- payloads
|
|
1491
|
+
-- **************************************************************************
|
|
1492
|
+
if type(config.payloads) == "table" then
|
|
1493
|
+
squadronConfigJson.payloads = {}
|
|
1494
|
+
for _, _payload in ipairs(config.payloads) do
|
|
1495
|
+
table.insert(
|
|
1496
|
+
squadronConfigJson.payloads,
|
|
1497
|
+
ParseSquadPayloadConfigJson(
|
|
1498
|
+
_payload,
|
|
1499
|
+
parser_name
|
|
1500
|
+
)
|
|
1501
|
+
)
|
|
1502
|
+
end
|
|
1503
|
+
if #(squadronConfigJson.payloads) == 0 then
|
|
1504
|
+
Jtff_log.error(
|
|
1505
|
+
string.format(
|
|
1506
|
+
"Squadron %s has no payloads, skipping squadron configuration",
|
|
1507
|
+
squadronConfigJson.name
|
|
1508
|
+
),
|
|
1509
|
+
parser_name
|
|
1510
|
+
)
|
|
1511
|
+
return {}
|
|
1512
|
+
end
|
|
1513
|
+
else
|
|
1514
|
+
Jtff_log.error("Airwing squadrons is not a table, skipping airwing configuration", "AIRWING")
|
|
1515
|
+
return {}
|
|
1516
|
+
end
|
|
1517
|
+
-- **************************************************************************
|
|
1518
|
+
-- nb_aircrafts
|
|
1519
|
+
-- **************************************************************************
|
|
1520
|
+
if type(config.nb_aircrafts) == "number" then
|
|
1521
|
+
squadronConfigJson.nb_aircrafts = config.nb_aircrafts
|
|
1522
|
+
else
|
|
1523
|
+
Jtff_log.warn(
|
|
1524
|
+
string.format(
|
|
1525
|
+
"Squadron %s nb_aircrafts is not a number, defaulting to %d",
|
|
1526
|
+
squadronConfigJson.name,
|
|
1527
|
+
default_nb_aircrafts
|
|
1528
|
+
),
|
|
1529
|
+
parser_name
|
|
1530
|
+
)
|
|
1531
|
+
squadronConfigJson.nb_aircrafts = default_nb_aircrafts
|
|
1532
|
+
end
|
|
1533
|
+
return squadronConfigJson
|
|
1534
|
+
end
|
|
1535
|
+
|
|
1536
|
+
-- @type PayloadRoleConfig
|
|
1537
|
+
-- @field #AUFTRAG.Type[] roles Roles for the payload.
|
|
1538
|
+
-- @field #number perf Performance for the payload (between 1 and 100).
|
|
1539
|
+
-- @field #number qty Quantity of the payload. (-1 is unlimited)
|
|
1540
|
+
|
|
1541
|
+
-- @type PayloadConfig
|
|
1542
|
+
-- @field #string name Payload name.
|
|
1543
|
+
-- @field #PayloadRoleConfig[] payloadconfigs Payload roles config for the payload.
|
|
1544
|
+
|
|
1545
|
+
--- Parse a PayloadConfig config Object.
|
|
1546
|
+
-- @param #JsonObject config Config object to parse
|
|
1547
|
+
-- @param #string parser_name Parser name ("AIRBASE", "AIRBOSS", etc...).
|
|
1548
|
+
-- @return #PayloadConfig squadronPayloadConfigJson Parsed PayloadConfig object
|
|
1549
|
+
function ParsePayloadConfigJson(config, parser_name)
|
|
1550
|
+
local payloadConfigJson = {}
|
|
1551
|
+
local default_perf = 70
|
|
1552
|
+
local default_qty = 50
|
|
1553
|
+
-- **************************************************************************
|
|
1554
|
+
-- roles
|
|
1555
|
+
-- **************************************************************************
|
|
1556
|
+
if type(config.roles) == "table" then
|
|
1557
|
+
payloadConfigJson.roles = {}
|
|
1558
|
+
for _, _role in ipairs(config.roles) do
|
|
1559
|
+
table.insert(payloadConfigJson.roles, _role)
|
|
1560
|
+
end
|
|
1561
|
+
else
|
|
1562
|
+
Jtff_log.error("Payload roles is not a table, skipping payload configuration", parser_name)
|
|
1563
|
+
return {}
|
|
1564
|
+
end
|
|
1565
|
+
-- **************************************************************************
|
|
1566
|
+
-- perf
|
|
1567
|
+
-- **************************************************************************
|
|
1568
|
+
payloadConfigJson.perf = config.perf or default_perf
|
|
1569
|
+
-- **************************************************************************
|
|
1570
|
+
-- qty
|
|
1571
|
+
-- **************************************************************************
|
|
1572
|
+
payloadConfigJson.qty = config.qty or default_qty
|
|
1573
|
+
return payloadConfigJson
|
|
1574
|
+
|
|
1575
|
+
end
|
|
1576
|
+
|
|
1577
|
+
--- Parse an SquadronPayload config Object.
|
|
1578
|
+
-- @param #JsonObject config Config object to parse
|
|
1579
|
+
-- @param #string parser_name Parser name ("AIRBASE", "AIRBOSS", etc...).
|
|
1580
|
+
-- @return #PayloadConfig squadronPayloadConfigJson Parsed PayloadConfig object
|
|
1581
|
+
function ParseSquadPayloadConfigJson(config, parser_name)
|
|
1582
|
+
local squadronPayloadConfigJson = {}
|
|
1583
|
+
-- **************************************************************************
|
|
1584
|
+
-- name
|
|
1585
|
+
-- **************************************************************************
|
|
1586
|
+
if type(config.name) == "string" then
|
|
1587
|
+
if type(GROUP:FindByName(config.name)) == 'nil' then
|
|
1588
|
+
Jtff_log.error(
|
|
1589
|
+
string.format(
|
|
1590
|
+
"SquadronPayload %s not found, skipping squadron payload configuration",
|
|
1591
|
+
config.name
|
|
1592
|
+
),
|
|
1593
|
+
parser_name
|
|
1594
|
+
)
|
|
1595
|
+
return {}
|
|
1596
|
+
else
|
|
1597
|
+
squadronPayloadConfigJson.name = config.name
|
|
1598
|
+
end
|
|
1599
|
+
else
|
|
1600
|
+
Jtff_log.error(
|
|
1601
|
+
"SquadronPayloadTemplate name is not a string, skipping squadron Payload configuration",
|
|
1602
|
+
parser_name
|
|
1603
|
+
)
|
|
1604
|
+
return {}
|
|
1605
|
+
end
|
|
1606
|
+
-- **************************************************************************
|
|
1607
|
+
-- payloadconfigs
|
|
1608
|
+
-- **************************************************************************
|
|
1609
|
+
if type(config.payloadconfigs) == "table" then
|
|
1610
|
+
squadronPayloadConfigJson.payloadconfigs = {}
|
|
1611
|
+
for _, _payloadconfig in ipairs(config.payloadconfigs) do
|
|
1612
|
+
if type(_payloadconfig) == "table" then
|
|
1613
|
+
table.insert(
|
|
1614
|
+
squadronPayloadConfigJson.payloadconfigs,
|
|
1615
|
+
ParsePayloadConfigJson(_payloadconfig, parser_name)
|
|
1616
|
+
)
|
|
1617
|
+
else
|
|
1618
|
+
Jtff_log.error(
|
|
1619
|
+
string.format(
|
|
1620
|
+
"SquadronPayload is not a valid PayloadRoleConfig object, skipping squadron payload configuration"
|
|
1621
|
+
),
|
|
1622
|
+
parser_name
|
|
1623
|
+
)
|
|
1624
|
+
return {}
|
|
1625
|
+
end
|
|
1626
|
+
end
|
|
1627
|
+
if #(squadronPayloadConfigJson.payloadconfigs) == 0 then
|
|
1628
|
+
Jtff_log.error(
|
|
1629
|
+
string.format(
|
|
1630
|
+
"SquadronPayload %s has no payloads, skipping squadron Payload configuration",
|
|
1631
|
+
squadronPayloadConfigJson.name
|
|
1632
|
+
),
|
|
1633
|
+
parser_name
|
|
1634
|
+
)
|
|
1635
|
+
return {}
|
|
1636
|
+
end
|
|
1637
|
+
else
|
|
1638
|
+
Jtff_log.error(
|
|
1639
|
+
string.format(
|
|
1640
|
+
"SquadronPayload %s payloadconfigs is not a table, skipping squadron Payload configuration",
|
|
1641
|
+
squadronPayloadConfigJson.name
|
|
1642
|
+
),
|
|
1643
|
+
parser_name
|
|
1644
|
+
)
|
|
1645
|
+
return {}
|
|
1646
|
+
end
|
|
1647
|
+
return squadronPayloadConfigJson
|
|
1648
|
+
end
|
|
1649
|
+
|
|
1650
|
+
-- @type RelativeRacetrackConfig
|
|
1651
|
+
-- @field #WRAPPER.Unit patternUnit Unit name to use for the pattern.
|
|
1652
|
+
-- @field #number front number of nm in the racetrack before the unit.
|
|
1653
|
+
-- @field #number back number of nm in the racetrack behind of the unit.
|
|
1654
|
+
-- @field #number fl Racetrack flight level.
|
|
1655
|
+
-- @field #number speed Racetrack speed in knots.
|
|
1656
|
+
|
|
1657
|
+
--- Parse an RelativeRacetrackConfig config Object.
|
|
1658
|
+
-- @param #JsonObject config Config object to parse
|
|
1659
|
+
-- @param #string parser_name Parser name ("AIRBASE", "AIRBOSS", etc...).
|
|
1660
|
+
-- @return #RelativeRacetrackConfig racetrackConfigJson Parsed RacetrackConfig object
|
|
1661
|
+
function ParseRelativeRacetrackConfigJson(config, parser_name)
|
|
1662
|
+
local relativeRacetrackConfigJson = {}
|
|
1663
|
+
local default_front = 30
|
|
1664
|
+
local default_back = 30
|
|
1665
|
+
local default_fl = 080
|
|
1666
|
+
local default_speed = 320
|
|
1667
|
+
-- **************************************************************************
|
|
1668
|
+
-- patternUnit
|
|
1669
|
+
-- **************************************************************************
|
|
1670
|
+
if type(config.patternUnit) == "string" then
|
|
1671
|
+
if type(UNIT:FindByName(config.patternUnit)) == 'nil' then
|
|
1672
|
+
Jtff_log.error(
|
|
1673
|
+
string.format(
|
|
1674
|
+
"Racetrack patternUnit %s not found, skipping racetrack configuration",
|
|
1675
|
+
config.patternUnit
|
|
1676
|
+
),
|
|
1677
|
+
parser_name
|
|
1678
|
+
)
|
|
1679
|
+
return {}
|
|
1680
|
+
else
|
|
1681
|
+
relativeRacetrackConfigJson.patternUnit = UNIT:FindByName(config.patternUnit)
|
|
1682
|
+
end
|
|
1683
|
+
else
|
|
1684
|
+
Jtff_log.error(
|
|
1685
|
+
string.format(
|
|
1686
|
+
"Racetrack patternUnit %s is not a string, skipping racetrack configuration",
|
|
1687
|
+
config.patternUnit
|
|
1688
|
+
),
|
|
1689
|
+
parser_name
|
|
1690
|
+
)
|
|
1691
|
+
return {}
|
|
1692
|
+
end
|
|
1693
|
+
-- **************************************************************************
|
|
1694
|
+
-- front
|
|
1695
|
+
-- **************************************************************************
|
|
1696
|
+
relativeRacetrackConfigJson.front = config.front or default_front
|
|
1697
|
+
-- **************************************************************************
|
|
1698
|
+
-- back
|
|
1699
|
+
-- **************************************************************************
|
|
1700
|
+
relativeRacetrackConfigJson.back = config.back or default_back
|
|
1701
|
+
-- **************************************************************************
|
|
1702
|
+
-- fl
|
|
1703
|
+
-- **************************************************************************
|
|
1704
|
+
relativeRacetrackConfigJson.fl = config.fl or default_fl
|
|
1705
|
+
-- **************************************************************************
|
|
1706
|
+
-- speed
|
|
1707
|
+
-- **************************************************************************
|
|
1708
|
+
relativeRacetrackConfigJson.speed = config.speed or default_speed
|
|
1709
|
+
return relativeRacetrackConfigJson
|
|
1710
|
+
end
|
|
1711
|
+
|
|
1712
|
+
-- @type RacetrackConfig
|
|
1713
|
+
-- @field #string coordinate MGRS Racetrack coordinates.
|
|
1714
|
+
-- @field #number fl Racetrack flight level.
|
|
1715
|
+
-- @field #number speed Racetrack speed in knots.
|
|
1716
|
+
-- @field #number heading Racetrack heading in degrees.
|
|
1717
|
+
-- @field #number leg Racetrack leg in nm.
|
|
1718
|
+
|
|
1719
|
+
--- Parse an Racetrack config Object.
|
|
1720
|
+
-- @param #JsonObject config Config object to parse
|
|
1721
|
+
-- @param #string parser_name Parser name ("AIRBASE", "AIRBOSS", etc...).
|
|
1722
|
+
-- @return #RacetrackConfig racetrackConfigJson Parsed RacetrackConfig object
|
|
1723
|
+
function ParseRacetrackConfigJson(config, parser_name)
|
|
1724
|
+
local racetrackConfigJson = {}
|
|
1725
|
+
local default_fl = 250
|
|
1726
|
+
local default_speed = 320
|
|
1727
|
+
local default_heading = 090
|
|
1728
|
+
local default_leg = 30
|
|
1729
|
+
-- **************************************************************************
|
|
1730
|
+
-- coordinate
|
|
1731
|
+
-- **************************************************************************
|
|
1732
|
+
if type(config.coordinate) == "string" then
|
|
1733
|
+
racetrackConfigJson.coordinate = config.coordinate
|
|
1734
|
+
else
|
|
1735
|
+
Jtff_log.error("Racetrack coordinates is not a table, skipping racetrack configuration", parser_name)
|
|
1736
|
+
return {}
|
|
1737
|
+
end
|
|
1738
|
+
-- **************************************************************************
|
|
1739
|
+
-- fl
|
|
1740
|
+
-- **************************************************************************
|
|
1741
|
+
racetrackConfigJson.fl = config.fl or default_fl
|
|
1742
|
+
-- **************************************************************************
|
|
1743
|
+
-- speed
|
|
1744
|
+
-- **************************************************************************
|
|
1745
|
+
racetrackConfigJson.speed = config.speed or default_speed
|
|
1746
|
+
-- **************************************************************************
|
|
1747
|
+
-- heading
|
|
1748
|
+
-- **************************************************************************
|
|
1749
|
+
racetrackConfigJson.heading = config.heading or default_heading
|
|
1750
|
+
-- **************************************************************************
|
|
1751
|
+
-- leg
|
|
1752
|
+
-- **************************************************************************
|
|
1753
|
+
racetrackConfigJson.leg = config.leg or default_leg
|
|
1754
|
+
return racetrackConfigJson
|
|
1755
|
+
end
|
|
1756
|
+
|
|
1757
|
+
-- @type AwacsCallsignConfig
|
|
1758
|
+
-- @field #string alias Alias for the awacs.
|
|
1759
|
+
-- @field #number name CallSign name for the awacs.
|
|
1760
|
+
-- @field #number number CallSign number (1-7) for the awacs.
|
|
1761
|
+
|
|
1762
|
+
--- Parse an Awacs Callsign config Object.
|
|
1763
|
+
-- @param #JsonObject config Config object to parse
|
|
1764
|
+
-- @param #string parser_name Parser name ("AIRBASE", "AIRBOSS", etc...).
|
|
1765
|
+
-- @return #RescueHeloCallsignConfig rescueHeloCallsignConfigJson Parsed CallSign object
|
|
1766
|
+
function ParseAwacsCallsignConfigJson(config, parser_name)
|
|
1767
|
+
local awacsCallsignConfigJson = {}
|
|
1768
|
+
local default_number = 1
|
|
1769
|
+
-- **************************************************************************
|
|
1770
|
+
-- name
|
|
1771
|
+
-- **************************************************************************
|
|
1772
|
+
if type(config.name) == "number" then
|
|
1773
|
+
if table.count_value(CALLSIGN.AWACS, config.name) > 0 then
|
|
1774
|
+
awacsCallsignConfigJson.name = config.name
|
|
1775
|
+
else
|
|
1776
|
+
Jtff_log.warn("AWACS Callsign name is not a valid CallSign name, skipping AWACS configuration",
|
|
1777
|
+
parser_name)
|
|
1778
|
+
awacsCallsignConfigJson.name = CALLSIGN.AWACS.Darkstar
|
|
1779
|
+
end
|
|
1780
|
+
else
|
|
1781
|
+
Jtff_log.error("AWACS Callsign name is not valid, skipping AWACS configuration", parser_name)
|
|
1782
|
+
return {}
|
|
1783
|
+
end
|
|
1784
|
+
-- **************************************************************************
|
|
1785
|
+
-- alias
|
|
1786
|
+
-- **************************************************************************
|
|
1787
|
+
if type(config.alias) == "string" then
|
|
1788
|
+
awacsCallsignConfigJson.alias = config.alias
|
|
1789
|
+
else
|
|
1790
|
+
Jtff_log.warn("AWACS Callsign alias is not a string, defaulting to AWACS name", parser_name)
|
|
1791
|
+
awacsCallsignConfigJson.alias = "Ford"
|
|
1792
|
+
end
|
|
1793
|
+
-- **************************************************************************
|
|
1794
|
+
-- number
|
|
1795
|
+
-- **************************************************************************
|
|
1796
|
+
if type(config.number) == "number" then
|
|
1797
|
+
if config.number >= 1 and config.number <= 7 then
|
|
1798
|
+
awacsCallsignConfigJson.number = config.number
|
|
1799
|
+
else
|
|
1800
|
+
Jtff_log.warn(
|
|
1801
|
+
string.format("AWACS Callsign number is not a valid number (1-7), defaulting number to %d", default_number),
|
|
1802
|
+
parser_name)
|
|
1803
|
+
awacsCallsignConfigJson.number = default_number
|
|
1804
|
+
end
|
|
1805
|
+
else
|
|
1806
|
+
Jtff_log.warn(string.format("AWACS Callsign number is not a number, defaulting number to %d", default_number),
|
|
1807
|
+
parser_name)
|
|
1808
|
+
awacsCallsignConfigJson.number = default_number
|
|
1809
|
+
end
|
|
1810
|
+
return awacsCallsignConfigJson
|
|
1811
|
+
end
|
|
1812
|
+
|
|
1813
|
+
-- @type SquawkConfig
|
|
1814
|
+
-- @field #string mode1 Mode1 code for the aircraft.
|
|
1815
|
+
-- @field #string mode2 Mode2 code for the aircraft.
|
|
1816
|
+
-- @field #string mode3 Mode3 code for the aircraft.
|
|
1817
|
+
-- @field #string mode4 Mode4 code for the aircraft.
|
|
1818
|
+
|
|
1819
|
+
--- Parse an SquawkConfig Object.
|
|
1820
|
+
-- @param #JsonObject config Config object to parse
|
|
1821
|
+
-- @param #string parser_name Parser name ("AIRBASE", "AIRBOSS", etc...).
|
|
1822
|
+
-- @return #SquawkConfig SquawkConfigJson Parsed SquawkConfig object
|
|
1823
|
+
function ParseSquawkConfigJson(config, parser_name)
|
|
1824
|
+
local squawkConfigJson = {}
|
|
1825
|
+
local default_mode4 = 'UN'
|
|
1826
|
+
local default_mode1 = ''
|
|
1827
|
+
local default_mode2 = ''
|
|
1828
|
+
local default_mode3 = ''
|
|
1829
|
+
-- **************************************************************************
|
|
1830
|
+
-- mode4
|
|
1831
|
+
-- **************************************************************************
|
|
1832
|
+
if type(config.mode4) == "string" then
|
|
1833
|
+
if string.upper(config.mode4) == "FR" or string.lower(config.mode4) == "friend" then
|
|
1834
|
+
squawkConfigJson.mode4 = 'FR'
|
|
1835
|
+
else
|
|
1836
|
+
squawkConfigJson.mode4 = 'UN'
|
|
1837
|
+
end
|
|
1838
|
+
else
|
|
1839
|
+
Jtff_log.warn(string.format("Squawk firendOrFoe is not a string, defaulting to %s", default_mode4), parser_name)
|
|
1840
|
+
squawkConfigJson.mode4 = default_mode4
|
|
1841
|
+
end
|
|
1842
|
+
-- **************************************************************************
|
|
1843
|
+
-- mode1
|
|
1844
|
+
-- **************************************************************************
|
|
1845
|
+
if type(config.mode1) == "number" then
|
|
1846
|
+
squawkConfigJson.mode1 = string.format("%02d", config.mode1)
|
|
1847
|
+
else
|
|
1848
|
+
Jtff_log.error("Squawk mode1 is not a number, skipping mode 1 configuration", parser_name)
|
|
1849
|
+
squawkConfigJson.mode1 = default_mode1
|
|
1850
|
+
end
|
|
1851
|
+
-- **************************************************************************
|
|
1852
|
+
-- mode2
|
|
1853
|
+
-- **************************************************************************
|
|
1854
|
+
if type(config.mode2) == "number" then
|
|
1855
|
+
squawkConfigJson.mode2 = string.format("%02d", config.mode2)
|
|
1856
|
+
else
|
|
1857
|
+
Jtff_log.error("Squawk mode2 is not a number, skipping mode 2 configuration", parser_name)
|
|
1858
|
+
squawkConfigJson.mode2 = default_mode2
|
|
1859
|
+
end
|
|
1860
|
+
-- **************************************************************************
|
|
1861
|
+
-- mode3
|
|
1862
|
+
-- **************************************************************************
|
|
1863
|
+
if type(config.mode3) == "number" then
|
|
1864
|
+
squawkConfigJson.mode3 = string.format("%02d", config.mode3)
|
|
1865
|
+
else
|
|
1866
|
+
Jtff_log.error("Squawk mode3 is not a number, skipping mode 3 configuration", parser_name)
|
|
1867
|
+
squawkConfigJson.mode3 = default_mode3
|
|
1868
|
+
end
|
|
1869
|
+
return squawkConfigJson
|
|
1870
|
+
end
|
|
1871
|
+
|
|
1872
|
+
--- Create a Squawk string understandable by LotATC based on a SquawkConfig Object
|
|
1873
|
+
-- @param #SquawkConfig config Config object to parse
|
|
1874
|
+
-- @return #string squawkString
|
|
1875
|
+
function CreateSquawkString(squawkConfigJson)
|
|
1876
|
+
local squawkString = "@IFF:"
|
|
1877
|
+
if squawkConfigJson.mode1 ~= '' then
|
|
1878
|
+
squawkString = string.format("%s(%s)", squawkString, squawkConfigJson.mode1)
|
|
1879
|
+
end
|
|
1880
|
+
if squawkConfigJson.mode2 ~= '' then
|
|
1881
|
+
squawkString = string.format("%s[%s]", squawkString, squawkConfigJson.mode2)
|
|
1882
|
+
end
|
|
1883
|
+
if squawkConfigJson.mode3 ~= '' then
|
|
1884
|
+
squawkString = string.format("%s%s", squawkString, squawkConfigJson.mode3)
|
|
1885
|
+
end
|
|
1886
|
+
if squawkConfigJson.mode4 ~= '' then
|
|
1887
|
+
squawkString = string.format("%s%s", squawkString, squawkConfigJson.mode4)
|
|
1888
|
+
end
|
|
1889
|
+
return squawkString
|
|
1890
|
+
end
|
|
1891
|
+
|
|
1216
1892
|
-- @field #JTFF_QRA JTFF_QRA
|
|
1217
1893
|
JTFF_QRA = {
|
|
1218
1894
|
ClassName = "JTFF_QRA",
|
|
@@ -1226,13 +1902,25 @@ JTFF_QRA.Type = {
|
|
|
1226
1902
|
Alpha = "Alpha Scramble",
|
|
1227
1903
|
}
|
|
1228
1904
|
|
|
1905
|
+
-- @field JTFF_INTERCEPT JTFF_INTERCEPT
|
|
1906
|
+
JTFF_INTERCEPT = {
|
|
1907
|
+
ClassName = "JTFF_INTERCEPT",
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
-- @type JTFF_INTERCEPT.Type
|
|
1911
|
+
JTFF_INTERCEPT.Type = {
|
|
1912
|
+
Civilian = "civil",
|
|
1913
|
+
Fighter = "fighter",
|
|
1914
|
+
Vampire = "bomber",
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1229
1917
|
env.info('JTFF-SHAREDLIB: shared library loaded succesfully')
|
|
1230
1918
|
|
|
1231
|
-
|
|
1919
|
+
SoundFilesPrefix = GetSoundFilesPrefix()
|
|
1232
1920
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1921
|
+
Sound2Bip = USERSOUND:New( SoundFilesPrefix .. "Misc/2_Bips.ogg" )
|
|
1922
|
+
Sound1Bip = USERSOUND:New( SoundFilesPrefix .. "Misc/Bip.ogg" )
|
|
1923
|
+
SoundCrashWood = USERSOUND:New( SoundFilesPrefix .. "Misc/crash_wood.ogg" )
|
|
1924
|
+
SoundQRA = USERSOUND:New( SoundFilesPrefix .. "Misc/SCRAMBLE QRA.ogg" )
|
|
1237
1925
|
|
|
1238
|
-
|
|
1926
|
+
Sound1Bip:ToAll()
|