@jtff/miztemplate-lib 2.2.0 → 3.0.0-rc2

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.
Files changed (65) hide show
  1. package/index.js +4 -3
  2. package/lib/jtff-lib-ci.js +1 -307
  3. package/lib/mizlib.js +337 -0
  4. package/lua/lib/Hercules_Cargo.lua +686 -0
  5. package/lua/lib/Moose_.lua +117314 -0
  6. package/lua/lib/Splash_Damage_2_0.lua +472 -0
  7. package/lua/lib/gemman.lua +1 -0
  8. package/lua/lib/mist_4_5_107.lua +9084 -0
  9. package/lua/lib/skynet-iads-compiled.lua +3864 -0
  10. package/lua/settings/settings-RAT.lua +235 -0
  11. package/lua/settings/settings-airboss.lua +142 -0
  12. package/lua/settings/settings-atis.lua +31 -0
  13. package/lua/settings/settings-awacs.lua +58 -0
  14. package/lua/settings/settings-awacsondemand.lua +26 -0
  15. package/lua/settings/settings-beacons.lua +10 -0
  16. package/lua/settings/settings-capwarzone.lua +164 -0
  17. package/lua/settings/settings-capzone.lua +32 -0
  18. package/lua/settings/settings-fac_ranges.lua +17 -0
  19. package/lua/settings/settings-foxzone.lua +14 -0
  20. package/lua/settings/settings-gemman.lua +6 -0
  21. package/lua/settings/settings-global.lua +31 -0
  22. package/lua/settings/settings-intercept.lua +23 -0
  23. package/lua/settings/settings-logistics.lua +22 -0
  24. package/lua/settings/settings-ondemandawacs.lua +29 -0
  25. package/lua/settings/settings-ondemandtankers.lua +29 -0
  26. package/lua/settings/settings-pedros.lua +11 -0
  27. package/lua/settings/settings-ranges.lua +28 -0
  28. package/lua/settings/settings-reapers.lua +25 -0
  29. package/lua/settings/settings-sams.lua +19 -0
  30. package/lua/settings/settings-skynet.lua +239 -0
  31. package/lua/settings/settings-tankers.lua +32 -0
  32. package/lua/settings/settings-training_ranges.lua +37 -0
  33. package/lua/src/010-root_menus.lua +5 -0
  34. package/lua/src/020-mission_functions.lua +1059 -0
  35. package/lua/src/110-set_clients.lua +61 -0
  36. package/lua/src/120-tankers.lua +589 -0
  37. package/lua/src/130-airboss.lua +621 -0
  38. package/lua/src/135-pedro.lua +21 -0
  39. package/lua/src/140-beacons.lua +19 -0
  40. package/lua/src/150-awacs.lua +599 -0
  41. package/lua/src/160-atis.lua +53 -0
  42. package/lua/src/170-cap_zone_training.lua +127 -0
  43. package/lua/src/172-cap_zone_war.lua +190 -0
  44. package/lua/src/173-fox_zone_training.lua +87 -0
  45. package/lua/src/176-random_air_traffic.lua +73 -0
  46. package/lua/src/178-training-intercept.lua +263 -0
  47. package/lua/src/180-logistics.lua +80 -0
  48. package/lua/src/190-ranges.lua +54 -0
  49. package/lua/src/191-sams.lua +49 -0
  50. package/lua/src/193-training_ranges.lua +191 -0
  51. package/lua/src/195-reaper-ondemand.lua +522 -0
  52. package/lua/src/196-fac_ranges.lua +34 -0
  53. package/lua/src/199-skynet.lua +721 -0
  54. package/lua/src/200-mission.lua +3 -0
  55. package/package.json +4 -3
  56. package/resources/radios/.gitkeep +0 -0
  57. package/resources/sounds/CTLD/beacon.ogg +0 -0
  58. package/resources/sounds/CTLD/beaconsilent.ogg +0 -0
  59. package/resources/sounds/Misc/.gitkeep +0 -0
  60. package/resources/sounds/Misc/2_Bips.ogg +0 -0
  61. package/resources/sounds/Misc/Bip.ogg +0 -0
  62. package/resources/sounds/Misc/crash_wood.ogg +0 -0
  63. package/scripts/build.js +2 -1
  64. package/scripts/inject-scripts.js +127 -230
  65. package/scripts/template-update.js +1 -1
@@ -0,0 +1,1059 @@
1
+ -- *****************************************************************************
2
+ -- * Mission functions *
3
+ -- *****************************************************************************
4
+
5
+
6
+ --
7
+ -- Generic Spawn object functions
8
+ --
9
+ env.info('JTFF-SHAREDLIB: shared library loading...')
10
+
11
+ function debug_msg(message)
12
+ if DEBUG_MSG then
13
+ env.info(string.format("[DEBUG] %s", message))
14
+ end
15
+ end
16
+
17
+ function debug_detection_msg(message)
18
+ if DEBUG_DETECT_MSG then
19
+ env.info(string.format("[DETECTION] %s", message))
20
+ end
21
+ end
22
+
23
+ function debug_squeduler_msg(message)
24
+ if DEBUG_SQ_MSG then
25
+ env.info(string.format("[DEBUG SQ] %s", message))
26
+ end
27
+ end
28
+
29
+ function switchGroupImmortalStatus(group)
30
+ status = not BASE:GetState(group, "isImmortal")
31
+ debug_msg(string.format("switch group %s to immortal status %s", group:GetName(), tostring(status)))
32
+ group:SetCommandImmortal(status)
33
+ BASE:SetState(group, "isImmortal", status)
34
+ MESSAGE:NewType("Immortal status of your group : " .. tostring(status) , MESSAGE.Type.Update):ToGroup(group)
35
+ end
36
+
37
+ function switchGroupAirbossSubtitlesStatus(group)
38
+ for index, airbossObject in ipairs(AIRBOSSArray) do
39
+ for playerindex, player in ipairs(group:GetPlayerUnits()) do
40
+ airbossObject:_SubtitlesOnOff(player:Name())
41
+ end
42
+ end
43
+ end
44
+
45
+ function give_bra_of_air_group(param)
46
+ local target_group = param[1]
47
+ local client_group = param[2]
48
+ local settings = param[3]
49
+ local coordinate_target = target_group:GetCoordinate()
50
+ local coordinate_client = client_group:GetCoordinate()
51
+ return string.format ("%s, %s",
52
+ coordinate_target:ToStringBRA(coordinate_client, settings),
53
+ coordinate_target:ToStringAspect(coordinate_client)
54
+ )
55
+ end
56
+
57
+ function give_heading_speed(param)
58
+ local target_group = param[1]
59
+ local settings = param[2]
60
+ local heading_target = target_group:GetHeading()
61
+ local speed_target = target_group:GetVelocityKNOTS()
62
+ if (settings:IsMetric()) then
63
+ speed_target = target_group:GetVelocityKMH()
64
+ return string.format (
65
+ "Heading : %.0f, Speed : %.0f km/h",
66
+ heading_target,
67
+ speed_target
68
+ )
69
+ end
70
+ return string.format (
71
+ "Heading : %.0f, Speed : %.0f kt",
72
+ heading_target,
73
+ speed_target
74
+ )
75
+ end
76
+
77
+ function tankerStatusMessage(tanker, PlayerUnit, PlayerGroup)
78
+ local client = CLIENT:Find(PlayerUnit:GetDCSObject())
79
+ local setting = _DATABASE:GetPlayerSettings(client:GetPlayerName())
80
+
81
+ local tankerrefuelsystemName = "BOOM"
82
+ if playerrefuelsystem == 0 then
83
+ tankerrefuelsystemName = "PROBE"
84
+ end
85
+ local braa_message = give_bra_of_air_group({tanker:GetGroup(), PlayerGroup, setting})
86
+ local aspect_message = give_heading_speed({tanker:GetGroup(), setting})
87
+ local fuelState = string.format("%s Lbs", tanker:GetTemplateFuel() * 2.205)
88
+ if setting:IsMetric() then
89
+ fuelState = string.format("%s Kg", tanker:GetTemplateFuel())
90
+ end
91
+
92
+ local timeInTheAir = 0
93
+ local timeLeftInTheAir = 0
94
+ local timeLeftString = "Time left : "
95
+ local groupName = tanker:GetName()
96
+ for index, value in pairs(tankersArray) do
97
+ debug_msg(string.format("%s spawned at %i", value.tanker.GroupName, value.spawnAbsTime))
98
+ if (string.find(groupName, value.tanker.GroupName, 1, true) ~= nil) then
99
+ timeInTheAir = timer.getAbsTime() - value.spawnAbsTime
100
+ timeLeftInTheAir = value.customconfig.missionmaxduration * 60 - timeInTheAir
101
+ if (UTILS.SecondsToClock(timeLeftInTheAir, true) ~= nil) then
102
+ timeLeftString = timeLeftString .. UTILS.SecondsToClock(timeLeftInTheAir, true)
103
+ end
104
+ debug_msg(string.format("%s found in %s, time in the air : %i sec, time left %i sec",
105
+ value.tanker.GroupName, groupName, timeInTheAir, timeLeftInTheAir))
106
+ else
107
+ debug_msg(string.format("%s not found in %s", value.tanker.GroupName, groupName))
108
+ end
109
+ end
110
+
111
+ for index, value in pairs(tankersOnDemandArray) do
112
+ if( value ~= nil) then
113
+ debug_msg(string.format("%s spawned in tankersOnDemandArray", value:GetName()))
114
+ if (string.find(groupName, value:GetName(), 1, true) ~= nil) then
115
+ timeInTheAir = timer.getAbsTime() - value.spawnAbsTime
116
+ timeLeftInTheAir = value.missionmaxduration * 60 - timeInTheAir
117
+ if (UTILS.SecondsToClock(timeLeftInTheAir, true) ~= nil) then
118
+ timeLeftString = timeLeftString .. UTILS.SecondsToClock(timeLeftInTheAir, true)
119
+ end
120
+ debug_msg(string.format("%s found in %s, time in the air : %i sec, time left %i sec",
121
+ value:GetName(), groupName, timeInTheAir, timeLeftInTheAir))
122
+ else
123
+ debug_msg(string.format("%s not found in %s", value:GetName(), groupName))
124
+ end
125
+ end
126
+ end
127
+
128
+ local message = string.format("%s %s [%s]\nFuel State %s (%.2f)\n%s\n%s\n%s", tanker:GetName(),
129
+ tanker:GetTypeName(), tankerrefuelsystemName, fuelState, tanker:GetFuel() * 100, aspect_message, braa_message,
130
+ timeLeftString)
131
+ MESSAGE:NewType(message, MESSAGE.Type.Overview):ToGroup(PlayerGroup)
132
+ end
133
+
134
+ function findNearestTanker(PlayerUnit, PlayerGroup, Radius)
135
+
136
+ Radius=UTILS.NMToMeters(Radius or 50)
137
+
138
+ local isrefuelable, playerrefuelsystem=PlayerUnit:IsRefuelable()
139
+ if isrefuelable then
140
+ local coord=PlayerUnit:GetCoordinate()
141
+ local units=coord:ScanUnits(Radius)
142
+ local coalition=PlayerUnit:GetCoalition()
143
+
144
+ local dmin = math.huge
145
+ local tanker = nil --Wrapper.Unit#UNIT
146
+ for _,_unit in pairs(units.Set) do
147
+ local unit = _unit --Wrapper.Unit#UNIT
148
+ local istanker, tankerrefuelsystem=unit:IsTanker()
149
+ if istanker and
150
+ playerrefuelsystem == tankerrefuelsystem and
151
+ coalition == unit:GetCoalition() and
152
+ unit:IsAlive() then
153
+
154
+ -- Distance.
155
+ local d = unit:GetCoordinate():Get2DDistance(coord)
156
+ if d < dmin then
157
+ d = dmin
158
+ tanker=unit
159
+ end
160
+ end
161
+ end
162
+
163
+ tankerStatusMessage(tanker, PlayerUnit, PlayerGroup)
164
+ end
165
+ return nil
166
+ end
167
+
168
+ function findAllTanker(PlayerUnit, PlayerGroup, Radius)
169
+
170
+ Radius=UTILS.NMToMeters(Radius or 50)
171
+
172
+ local isrefuelable, playerrefuelsystem=PlayerUnit:IsRefuelable()
173
+ if isrefuelable then
174
+
175
+ local coord = PlayerUnit:GetCoordinate()
176
+ local units = coord:ScanUnits(Radius)
177
+ local coalition = PlayerUnit:GetCoalition()
178
+
179
+ local tanker = nil --Wrapper.Unit#UNIT
180
+ for _,_unit in pairs(units.Set) do
181
+ local unit=_unit --Wrapper.Unit#UNIT
182
+ local istanker, tankerrefuelsystem=unit:IsTanker()
183
+ if istanker and
184
+ playerrefuelsystem == tankerrefuelsystem and
185
+ coalition == unit:GetCoalition() and
186
+ unit:IsAlive() then
187
+ tanker=unit
188
+ tankerStatusMessage(tanker, PlayerUnit, PlayerGroup)
189
+ end
190
+ end
191
+ end
192
+ return nil
193
+ end
194
+
195
+ function NearestTankerInfo(param)
196
+ findNearestTanker(
197
+ param[1],
198
+ param[2],
199
+ 200
200
+ )
201
+ end
202
+
203
+ function AllTankersInfo(param)
204
+ findAllTanker(param[1],param[2], 200)
205
+ end
206
+
207
+ function taskTankerEscort(param)
208
+ local recoveryTankerObject = param[1]
209
+ local EscortGroup = param[2]
210
+ EscortGroup:OptionAlarmStateRed()
211
+ EscortGroup:OptionROEReturnFire()
212
+ --EscortGroup:TraceOn()
213
+ EscortGroup:OptionRTBAmmo(true)
214
+ EscortGroup:OptionRTBBingoFuel(true)
215
+ local randomCoord = EscortGroup
216
+ :GetCoordinate()
217
+ :GetRandomCoordinateInRadius( UTILS.NMToMeters(20), UTILS.NMToMeters(15) )
218
+ randomCoord.y = UTILS.FeetToMeters(15000)
219
+ --randomCoord:MarkToAll('rejointe '..EscortGroup.GroupName)
220
+ EscortGroup:Route(
221
+ {
222
+ randomCoord:WaypointAirTurningPoint(
223
+ COORDINATE.WaypointAltType.BARO,
224
+ 500,
225
+ {},
226
+ 'rejoin'
227
+ ),
228
+ randomCoord:GetRandomCoordinateInRadius( UTILS.NMToMeters(20), UTILS.NMToMeters(15) ):WaypointAirTurningPoint(
229
+ COORDINATE.WaypointAltType.BARO,
230
+ 500,
231
+ {
232
+ EscortGroup:TaskEscort(
233
+ GROUP:FindByName(recoveryTankerObject.tanker.GroupName),
234
+ POINT_VEC3:New(0, 10, 150):GetVec3(),
235
+ 20,
236
+ UTILS.NMToMeters(40),
237
+ { 'Air' }
238
+ )
239
+ },
240
+ 'escort-start'
241
+ )
242
+ }
243
+ )
244
+ env.info('Escort group spawned : '.. EscortGroup.GroupName..'. Escorting '..recoveryTankerObject.tanker.GroupName)
245
+ end
246
+
247
+ function taskGroupEscort(param)
248
+ local GroupToEscortObject = param[1]
249
+ local EscortingGroup = param[2]
250
+ EscortingGroup:OptionAlarmStateRed()
251
+ EscortingGroup:OptionROEReturnFire()
252
+ --EscortGroup:TraceOn()
253
+ EscortingGroup:OptionRTBAmmo(true)
254
+ EscortingGroup:OptionRTBBingoFuel(true)
255
+ local randomCoord = EscortingGroup
256
+ :GetCoordinate()
257
+ :GetRandomCoordinateInRadius( UTILS.NMToMeters(20), UTILS.NMToMeters(15) )
258
+ randomCoord.y = UTILS.FeetToMeters(15000)
259
+ --randomCoord:MarkToAll('rejointe '..EscortGroup.GroupName)
260
+ EscortingGroup:Route(
261
+ {
262
+ randomCoord:WaypointAirTurningPoint(
263
+ COORDINATE.WaypointAltType.BARO,
264
+ 500,
265
+ {},
266
+ 'rejoin'
267
+ ),
268
+ randomCoord:GetRandomCoordinateInRadius( UTILS.NMToMeters(20), UTILS.NMToMeters(15) ):WaypointAirTurningPoint(
269
+ COORDINATE.WaypointAltType.BARO,
270
+ 500,
271
+ {
272
+ EscortingGroup:TaskEscort(
273
+ GROUP:FindByName(GroupToEscortObject.GroupName),
274
+ POINT_VEC3:New(0, 10, 150):GetVec3(),
275
+ 20,
276
+ UTILS.NMToMeters(40),
277
+ { 'Air' }
278
+ )
279
+ },
280
+ 'escort-start'
281
+ )
282
+ }
283
+ )
284
+ env.info('Escort group spawned : '.. EscortingGroup.GroupName..'. Escorting '.. GroupToEscortObject.GroupName)
285
+ end
286
+
287
+ function spawnRecoveryTankerEscort(escortSpawnObject,customconfig)
288
+ if (customconfig.airspawn) then
289
+ return escortSpawnObject
290
+ :SpawnFromCoordinate(UNIT:FindByName(customconfig.baseUnit):GetCoordinate():SetAltitude(UTILS.FeetToMeters(customconfig.altitude)))
291
+ else
292
+ return escortSpawnObject
293
+ :SpawnAtAirbase(AIRBASE:FindByName(customconfig.baseUnit),SPAWN.Takeoff.Cold, customconfig.altitude)
294
+ end
295
+ end
296
+
297
+ function LeaveRecovery(objAirboss)
298
+ local shipID = UNIT:FindByName(objAirboss.carrier:Name()):GetDCSObject():getID()
299
+ end
300
+
301
+ function resetRecoveryTanker(recoveryTankerObject)
302
+ recoveryTankerObject:SetRespawnOnOff(true)
303
+ recoveryTankerObject.tanker:Destroy()
304
+ recoveryTankerObject:SetRespawnOnOff(recoveryTankerObject.customconfig.autorespawn)
305
+ if recoveryTankerObject.customconfig.escortgroupname then
306
+ recoveryTankerObject.escortGroupObject:Destroy()
307
+ --recoveryTankerObject.escortGroupObject = spawnRecoveryTankerEscort(recoveryTankerObject.escortSpawnObject,recoveryTankerObject.customconfig)
308
+ end
309
+ end
310
+
311
+ function fctKillSpawnObject(objSpawn)
312
+ local GroupPlane, Index = objSpawn:GetFirstAliveGroup()
313
+ while GroupPlane ~= nil do
314
+ -- Do actions with the GroupPlane object.
315
+ GroupPlane:Destroy(true)
316
+ GroupPlane, Index = objSpawn:GetNextAliveGroup( Index )
317
+ end
318
+ end
319
+
320
+ function getMaxThreatUnit(setUnits)
321
+ local setUnitsSorted = SET_UNIT:New()
322
+ setUnits:ForEachUnitPerThreatLevel(10, 0, function(unit)
323
+ setUnitsSorted:AddUnit(unit)
324
+ end)
325
+ debug_msg(string.format("Max priority unit : %s", setUnitsSorted:GetFirst():GetName()))
326
+ return setUnitsSorted:GetFirst()
327
+ end
328
+
329
+ function destroyGroup(group_name)
330
+ local set_group_alive = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
331
+ set_group_alive:ForEachGroupAlive(
332
+ function(group_alive)
333
+ debug_msg(string.format("Group %s just removed", group_alive:GetName()))
334
+ if (map_marker[group_alive:GetName()]) then
335
+ COORDINATE:RemoveMark(map_marker[group_alive:GetName()])
336
+ end
337
+ group_alive:Destroy()
338
+ end )
339
+ end
340
+
341
+ function destroyStatic(staticToDelete, subRangeName, index)
342
+ if (staticToDelete.name ~= nil) then
343
+ local staticNameToDelete = string.format("%s", staticToDelete.name)
344
+ if (subRangeName ~= nil and index ~= nil) then
345
+ staticNameToDelete = string.format("%s_%s_%i", subRangeName, staticToDelete.name, index)
346
+ end
347
+ local staticUnitToDelete = STATIC:FindByName(staticNameToDelete, false)
348
+ if (staticUnitToDelete ~= nil) then
349
+ debug_msg(string.format("Delete static %s", staticUnitToDelete:GetDCSObject():getName()))
350
+ staticUnitToDelete:Destroy()
351
+ end
352
+ elseif (staticToDelete.type ~= nil and staticToDelete.category ~= nil and index ~= nil) then
353
+ local staticNameToDelete = string.format("%s_%s_%i", subRangeName, staticToDelete.type, index)
354
+ local staticUnitToDelete = STATIC:FindByName(staticNameToDelete, false)
355
+ if (staticUnitToDelete ~= nil) then
356
+ debug_msg(string.format("Delete Static %s", staticUnitToDelete:GetDCSObject():getName()))
357
+ staticUnitToDelete:Destroy()
358
+ end
359
+ else
360
+ debug_msg(string.format("Static to delete has no name or type!"))
361
+ end
362
+ end
363
+
364
+ function destroyStatics(staticsToDelete, subRangeName)
365
+ for index, staticToDelete in ipairs(staticsToDelete) do
366
+ destroyStatic(staticToDelete, subRangeName, index)
367
+ end
368
+ end
369
+
370
+ function setROE(param)
371
+ local groupsToSpawn = param[1]
372
+ local ROEvalue = param[2]
373
+ for groupIndex = 1, #groupsToSpawn do
374
+ local group_name = string.format("%s", groupsToSpawn[groupIndex])
375
+ local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
376
+ dcs_groups:ForEachGroupAlive(function(group_alive)
377
+ debug_msg(string.format("SET ROE of group %s at %i", group_alive:GetName(), ROEvalue))
378
+ if (ROEvalue ~= ENUMS.ROE.WeaponHold) then
379
+ group_alive:SetAIOn()
380
+ end
381
+ group_alive:OptionROE(ROEvalue)
382
+ end)
383
+ end
384
+ end
385
+
386
+ function setAlarmState(param)
387
+ local groupsToSpawn = param[1]
388
+ local AlarmStateValue = param[2]
389
+ for groupIndex = 1, #groupsToSpawn do
390
+ local group_name = string.format("%s", groupsToSpawn[groupIndex])
391
+ local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
392
+ dcs_groups:ForEachGroupAlive(function(group_alive)
393
+ group_alive:SetAIOn()
394
+ if AlarmStateValue == ENUMS.AlarmState.Auto then
395
+ debug_msg(string.format("SET Alarm State of group %s at AUTO", group_alive:GetName()))
396
+ group_alive:OptionAlarmStateAuto()
397
+ elseif AlarmStateValue == ENUMS.AlarmState.Green then
398
+ debug_msg(string.format("SET Alarm State of group %s at Green", group_alive:GetName()))
399
+ group_alive:OptionAlarmStateGreen()
400
+ elseif AlarmStateValue == ENUMS.AlarmState.Red then
401
+ debug_msg(string.format("SET Alarm State of group %s at Red", group_alive:GetName()))
402
+ group_alive:OptionAlarmStateRed()
403
+ end
404
+ end)
405
+ end
406
+ end
407
+
408
+ function setEngageAirWeapons(param)
409
+ local groupsToSpawn = param[1]
410
+ local value = param[2]
411
+ for groupIndex = 1, #groupsToSpawn do
412
+ local group_name = string.format("%s", groupsToSpawn[groupIndex])
413
+ local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
414
+ dcs_groups:ForEachGroupAlive(function(group_alive)
415
+ debug_msg(string.format("SET Engage Air Weapons of group %s at %s", group_alive:GetName(), tostring(value)))
416
+ if (value) then
417
+ group_alive:SetAIOn()
418
+ end
419
+ group_alive:SetOption(AI.Option.Ground.id.ENGAGE_AIR_WEAPONS, value)
420
+ end)
421
+ end
422
+ end
423
+
424
+ function smokeOnSubRange(param)
425
+ local groupsToSpawn = param[1]
426
+ local displayToCoalition = param[2]
427
+ for groupIndex = 1, #groupsToSpawn do
428
+ local group_name = string.format("%s", groupsToSpawn[groupIndex])
429
+ local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
430
+ dcs_groups:ForEachGroupAlive(function(group_alive)
431
+ debug_msg(string.format("Smoke on group %s", group_alive:GetName()))
432
+ local list_units = group_alive:GetUnits()
433
+ local set_units_red = SET_UNIT:New()
434
+ local set_units_blue = SET_UNIT:New()
435
+ for index = 1, #list_units do
436
+ local unit_tmp = list_units[index]
437
+ if (unit_tmp:IsAlive() and unit_tmp:GetCoalition() == coalition.side.RED) then
438
+ set_units_red:AddUnit(unit_tmp)
439
+ end
440
+ end
441
+ if (set_units_red:CountAlive() > 0) then
442
+ local unit_red_to_smoke = getMaxThreatUnit(set_units_red)
443
+ if (unit_red_to_smoke) then
444
+ unit_red_to_smoke:SmokeRed()
445
+ MESSAGE:NewType(string.format("[%s] Red smoke on : %s", group_alive:GetName(),
446
+ unit_red_to_smoke:GetTypeName()), MESSAGE.Type.Overview):ToCoalition(displayToCoalition)
447
+ end
448
+ elseif (set_units_blue:CountAlive() > 0) then
449
+ local unit_blue_to_smoke = getMaxThreatUnit(set_units_blue)
450
+ if (unit_blue_to_smoke) then
451
+ unit_blue_to_smoke:SmokeBlue()
452
+ MESSAGE:NewType(string.format("[%s] Blue smoke on : %s", group_alive:GetName(),
453
+ unit_blue_to_smoke:GetTypeName()), MESSAGE.Type.Overview):ToCoalition(displayToCoalition)
454
+ end
455
+ end
456
+ end)
457
+ end
458
+ end
459
+
460
+ function giveToClientGroupCoordinates(param)
461
+ local groupsToSpawn = param[1]
462
+ for i = 1, #groupsToSpawn do
463
+ local group_name = string.format("%s", groupsToSpawn[i])
464
+ debug_msg(string.format("Coordinates of all groups with name prefix %s", group_name))
465
+ local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
466
+ Set_CLIENT:ForEachClient(function(client)
467
+ if (client:IsActive()) then
468
+ debug_msg(string.format("For Client %s ", client:GetName()))
469
+ local coordinate_txt = ""
470
+ dcs_groups:ForEachGroupAlive(function(group_alive)
471
+ debug_msg(string.format("Coordinates of the group %s", group_alive:GetName()))
472
+ local coordinate = group_alive:GetCoordinate()
473
+ local setting = _DATABASE:GetPlayerSettings(client:GetPlayerName())
474
+ local coordinate_string = ""
475
+ if (setting:IsA2G_LL_DDM()) then
476
+ coordinate_string = coordinate:ToStringLLDDM(setting)
477
+ debug_msg(string.format("%s IsA2G_LL_DDM", client:GetName()))
478
+ elseif (setting:IsA2G_MGRS()) then
479
+ coordinate_string = coordinate:ToStringMGRS(setting)
480
+ debug_msg(string.format("%s IsA2G_MGRS", client:GetName()))
481
+ elseif (setting:IsA2G_LL_DMS()) then
482
+ coordinate_string = coordinate:ToStringLLDMS(setting)
483
+ debug_msg(string.format("%s IsA2G_LL_DMS", client:GetName()))
484
+ elseif (setting:IsA2G_BR()) then
485
+ coordinate_string = coordinate:ToStringBR(client:GetCoordinate(), setting)
486
+ debug_msg(string.format("%s IsA2G_BR", client:GetName()))
487
+ end
488
+ debug_msg(string.format("coordinate_txt [%s] : %s", group_alive:GetName(), coordinate_string))
489
+ coordinate_txt = string.format("%s[%s] : %s\n", coordinate_txt, group_alive:GetName(),
490
+ coordinate_string)
491
+ end)
492
+ debug_msg(string.format("Message to Client %s : %s", client:GetName(), coordinate_txt))
493
+ MESSAGE:NewType(coordinate_txt, MESSAGE.Type.Detailed):ToClient(client)
494
+ end
495
+ end)
496
+ end
497
+ end
498
+
499
+ function giveListOfGroupsAliveInRange(param)
500
+ local groupsToSpawn = param[1]
501
+ local rangeConfig = param[2]
502
+ local subRangeConfig = param[3]
503
+ debug_msg(string.format("List of groups in range %s-%s", rangeConfig.name, subRangeConfig.name))
504
+ local message = string.format("Targets groups in Range %s-%s :", rangeConfig.name, subRangeConfig.name)
505
+ for i = 1, #groupsToSpawn do
506
+ local group_name = string.format("%s", groupsToSpawn[i])
507
+ local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
508
+ dcs_groups:ForEachGroupAlive(function(group_alive)
509
+ debug_msg(string.format("group %s", group_alive:GetName()))
510
+ message = string.format("%s %s | ", message, group_alive:GetName());
511
+ end)
512
+ end
513
+ Set_CLIENT:ForEachClient(function(client)
514
+ if (client:IsActive()) then
515
+ MESSAGE:NewType(message, MESSAGE.Type.Information):ToClient(client)
516
+ end
517
+ end)
518
+ end
519
+
520
+ function giveListOfUnitsAliveInGroup(param)
521
+ local groupsToSpawn = param[1]
522
+ local side = param[2]
523
+ local number_to_display = param[3]
524
+ for i = 1, #groupsToSpawn do
525
+ local group_name = string.format("%s", groupsToSpawn[i])
526
+ debug_msg(string.format("List of units of all groups with name prefix %s", group_name))
527
+ local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
528
+ dcs_groups:ForEachGroupAlive(function(group_alive)
529
+ debug_msg(string.format("List of units of the group %s", group_alive:GetName()))
530
+ local info_unit_header = string.format("Units list of the group [%s]:", group_name)
531
+ Set_CLIENT:ForEachClient(function(client)
532
+ if (client:IsActive()) then
533
+ MESSAGE:NewType(info_unit_header, MESSAGE.Type.Overview):ToClient(client)
534
+ end
535
+ end)
536
+ local list_units = group_alive:GetUnits()
537
+ local set_units = SET_UNIT:New()
538
+ for index = 1, #list_units do
539
+ local unit_tmp = list_units[index]
540
+ if (unit_tmp:IsAlive() and unit_tmp:GetCoalition() ~= side) then
541
+ set_units:AddUnit(unit_tmp)
542
+ debug_msg(string.format("Type : %s", unit_tmp:GetTypeName()))
543
+ end
544
+ end
545
+ local increment = 0;
546
+ set_units:ForEachUnitPerThreatLevel(10, 0, function(unit_tmp)
547
+ if (increment < number_to_display) then
548
+ local unit_life_pourcentage = (unit_tmp:GetLife() / (unit_tmp:GetLife0() + 1)) * 100
549
+ local unit_coordinate = unit_tmp:GetCoordinate()
550
+ local unit_altitude_m = unit_tmp:GetAltitude()
551
+ local unit_coordinate_for_client = ""
552
+ local unit_altitude_for_client = 0
553
+ local unit_altitude_for_client_unit = ""
554
+ Set_CLIENT:ForEachClient(function(client)
555
+ if (client:IsActive()) then
556
+ local setting = _DATABASE:GetPlayerSettings(client:GetPlayerName())
557
+ unit_coordinate_for_client = ""
558
+ if (setting:IsA2G_LL_DDM()) then
559
+ unit_coordinate_for_client = unit_coordinate:ToStringLLDDM(setting)
560
+ elseif (setting:IsA2G_MGRS()) then
561
+ unit_coordinate_for_client = unit_coordinate:ToStringMGRS(setting)
562
+ elseif (setting:IsA2G_LL_DMS()) then
563
+ unit_coordinate_for_client = unit_coordinate:ToStringLLDMS(setting)
564
+ elseif (setting:IsA2G_BR()) then
565
+ unit_coordinate_for_client = unit_coordinate:ToStringBR(client:GetCoordinate(), setting)
566
+ end
567
+ if (setting:IsImperial()) then
568
+ unit_altitude_for_client = UTILS.MetersToFeet(unit_altitude_m)
569
+ unit_altitude_for_client_unit = "ft"
570
+ elseif (setting:IsMetric()) then
571
+ unit_altitude_for_client = unit_altitude_m
572
+ unit_altitude_for_client_unit = "m"
573
+ end
574
+ local info_unit_tmp = string.format("[%i] %s (%i", unit_tmp:GetThreatLevel(),
575
+ unit_tmp:GetTypeName(), unit_life_pourcentage) .. '%),\t' .. unit_coordinate_for_client ..
576
+ string.format("\tAlt: %.0f%s", unit_altitude_for_client,
577
+ unit_altitude_for_client_unit)
578
+ MESSAGE:NewType(info_unit_tmp, MESSAGE.Type.Overview):ToClient(client)
579
+ end
580
+ end)
581
+ increment = increment + 1;
582
+ end
583
+ end)
584
+ end)
585
+ end
586
+ end
587
+
588
+ function markGroupOnMap(param)
589
+ local groupsToSpawn = param[1]
590
+ local side = param[2]
591
+ for i = 2, #groupsToSpawn do
592
+ local group_name = string.format("%s", groupsToSpawn[i])
593
+ debug_msg(string.format("Mark on map all groups with name prefix %s", group_name))
594
+ local dcs_groups = SET_GROUP:New():FilterPrefixes(group_name):FilterOnce()
595
+ dcs_groups:ForEachGroupAlive(function(group_alive)
596
+ debug_msg(string.format("Mark on map the group %s", group_alive:GetName()))
597
+ local coordinate = group_alive:GetCoordinate()
598
+ map_marker[group_alive:GetName()] = coordinate:MarkToCoalition(group_alive:GetName(), side)
599
+ end)
600
+ end
601
+ end
602
+
603
+ function addSubRangeRadioMenus(radioCommandSubRange, rangeConfig, subRangeConfig)
604
+ local RadioCommandAdd = MENU_COALITION_COMMAND:New(
605
+ rangeConfig.benefit_coalition,
606
+ "Spawn",
607
+ radioCommandSubRange,
608
+ SpawnRangesDelay,
609
+ {
610
+ radioCommandSubRange,
611
+ rangeConfig,
612
+ subRangeConfig,
613
+ spawnStandardDelay,
614
+ addSubRangeRadioMenus
615
+ }
616
+ )
617
+ end
618
+
619
+ function AddWholeRangeCoalitionCommandMenus(radioCommandRange, rangeConfig)
620
+ local AddWholeRangeCommand = MENU_COALITION_COMMAND:New(
621
+ rangeConfig.benefit_coalition,
622
+ "Spawn Whole Range",
623
+ radioCommandRange,
624
+ SpawnWholeRangesDelay,
625
+ {
626
+ radioCommandRange,
627
+ rangeConfig,
628
+ spawnStandardDelay,
629
+ AddWholeRangeCoalitionCommandMenus
630
+ }
631
+ )
632
+ local DeleteWholeRangeCommand = MENU_COALITION_COMMAND:New(
633
+ rangeConfig.benefit_coalition,
634
+ "Delete whole Range",
635
+ radioCommandRange,
636
+ deleteWholeRangeUnits,
637
+ {
638
+ rangeConfig,
639
+ radioCommandRange
640
+ }
641
+ )
642
+ return {AddWholeRangeCommand, DeleteWholeRangeCommand}
643
+ end
644
+
645
+ function SpawnRangesDelay(param)
646
+ --parameters :
647
+ -- 1 : parent Radio Menu
648
+ -- 2 : Root range config Object
649
+ -- 3 : subRange config Object
650
+ -- 4 : delay in s before sub (or subsub) range spawn
651
+ -- 5 : function calling me (No Idea why we need that)
652
+ -- 6 : boolean for sound warning play
653
+ -- 7 : boolean for message warning
654
+ local rangeConfig = param[2]
655
+ local subRangeConfig = param[3]
656
+ local delay = param[4] or spawnStandardDelay
657
+ local myfunc = param[5]
658
+ local sound_warning = true
659
+ if (type(param[6]) ~= nil) then
660
+ sound_warning = param[6]
661
+ end
662
+ local message_warning = true
663
+ if (type(param[7]) ~= nil) then
664
+ message_warning = param[7]
665
+ end
666
+ if ( sound_warning ) then
667
+ sound2Bip:ToAll()
668
+ end
669
+ if ( message_warning ) then
670
+ MESSAGE:NewType(string.format("Warning, Range Units %s(%s) will spawn in %d sec", rangeConfig.name, subRangeConfig.name, delay), MESSAGE.Type.Update):ToAll()
671
+ end
672
+ TIMER:New(SpawnRanges, param):Start(delay)
673
+ end
674
+
675
+ function SpawnWholeRangesDelay(param)
676
+ --parameters :
677
+ -- 1 : parent Radio Menu
678
+ -- 2 : Root range config Object
679
+ -- 3 : delay in s before sub (or subsub) range spawn
680
+ -- 4 : function calling me (No Idea why we need that)
681
+ -- 5 : boolean for sound warning play
682
+ -- 6 : boolean for message warning
683
+ local parentRangeMenu = param[1]
684
+ local rangeConfig = param[2]
685
+ local delay = param[3] or spawnStandardDelay
686
+ local myfunc = param[4]
687
+ local sound_warning = true
688
+ if (type(param[5]) ~= nil) then
689
+ sound_warning = param[5]
690
+ end
691
+ local message_warning = true
692
+ if (type(param[6]) ~= nil) then
693
+ message_warning = param[6]
694
+ end
695
+ parentRangeMenu:RemoveSubMenus()
696
+ if (rangeConfig.subRange) then
697
+ sound2Bip:ToAll()
698
+ for subIndex, subRangeConfig in ipairs(rangeConfig.subRange) do
699
+ local radioMenuSubRange = MENU_COALITION:New(
700
+ rangeConfig.benefit_coalition,
701
+ subRangeConfig.name,
702
+ parentRangeMenu
703
+ )
704
+ if (subRangeConfig.subsubRange) then
705
+ for subsubIndex, subsubRangeConfig in ipairs(subRangeConfig.subsubRange) do
706
+ local radioMenuSubSubRange = MENU_COALITION:New(
707
+ rangeConfig.benefit_coalition,
708
+ subsubRangeConfig.name,
709
+ radioMenuSubRange
710
+ )
711
+ SpawnRangesDelay(
712
+ {
713
+ radioMenuSubSubRange,
714
+ rangeConfig,
715
+ subsubRangeConfig,
716
+ delay,
717
+ myfunc,
718
+ sound_warning,
719
+ message_warning
720
+ }
721
+ )
722
+ end
723
+ else
724
+ SpawnRangesDelay(
725
+ {
726
+ radioMenuSubRange,
727
+ rangeConfig,
728
+ subRangeConfig,
729
+ delay,
730
+ myfunc,
731
+ sound_warning,
732
+ message_warning
733
+ }
734
+ )
735
+ end
736
+ end
737
+ local CommandZoneDetroy = MENU_COALITION_COMMAND:New(
738
+ rangeConfig.benefit_coalition,
739
+ "Delete whole Range",
740
+ parentRangeMenu,
741
+ deleteWholeRangeUnits,
742
+ {
743
+ rangeConfig,
744
+ parentRangeMenu
745
+ }
746
+ )
747
+ end
748
+ end
749
+
750
+ function SpawnRanges(param)
751
+ --parameters :
752
+ -- 1 : parent Radio Menu
753
+ -- 2 : Root range config Object
754
+ -- 3 : subRange config Object
755
+
756
+ local radioCommandSubRange = param[1]
757
+ local rangeConfig = param[2]
758
+ local rangeName = rangeConfig.name
759
+ local subRangeConfig = param[3]
760
+ local subRangeName = subRangeConfig.name
761
+ local groupsToSpawn = subRangeConfig.groupsToSpawn
762
+ local staticsToSpawn = subRangeConfig.staticsToSpawn
763
+ local holdFire = subRangeConfig.holdFire
764
+ local engageAirWeapons = subRangeConfig.engageAirWeapons
765
+ local activateAI = subRangeConfig.AI
766
+ local redAlert = subRangeConfig.redAlert
767
+
768
+ debug_msg(string.format("SpawnRanges : Range %s - Targets %s", rangeName, subRangeName))
769
+ if (staticsToSpawn ~= nil)then
770
+ for index, staticToSpawn in ipairs(staticsToSpawn) do
771
+ local spawnStatic = nil
772
+ if (staticToSpawn.name ~= nil) then
773
+ local staticNameToSpawn = string.format("%s", staticToSpawn.name)
774
+ spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn)
775
+ if (staticToSpawn.coalition ~= nil) then
776
+ if (staticToSpawn.coalition == coalition.side.BLUE) then
777
+ spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn, country.id.CJTF_BLUE)
778
+ elseif (staticToSpawn.coalition == coalition.side.RED) then
779
+ spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn, country.id.CJTF_RED)
780
+ else
781
+ spawnStatic = SPAWNSTATIC:NewFromStatic(staticNameToSpawn, country.id.UN_PEACEKEEPERS)
782
+ end
783
+ end
784
+ local x = staticToSpawn.x
785
+ local y = staticToSpawn.y
786
+ local heading = staticToSpawn.heading
787
+ local name = string.format("%s_%s_%i", subRangeName, staticNameToSpawn,index)
788
+ local static = spawnStatic:SpawnFromPointVec2( POINT_VEC2:New( x, y ), heading, name )
789
+ debug_msg(string.format("Static to spawn %s at %i,%i -> %s", static:GetDCSObject():getTypeName(), x, y, static:GetDCSObject():getName()))
790
+ elseif (staticToSpawn.type ~= nil and staticToSpawn.category ~= nil) then
791
+ local staticTypeToSpawn = string.format("%s", staticToSpawn.type)
792
+ local staticCategoryToSpawn = string.format("%s", staticToSpawn.category)
793
+ spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn)
794
+ if (staticToSpawn.coalition ~= nil) then
795
+ if (staticToSpawn.coalition == coalition.side.BLUE) then
796
+ spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn, country.id.CJTF_BLUE)
797
+ elseif (staticToSpawn.coalition == coalition.side.RED) then
798
+ spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn, country.id.CJTF_RED)
799
+ else
800
+ spawnStatic = SPAWNSTATIC:NewFromType(staticTypeToSpawn, staticCategoryToSpawn, country.id.UN_PEACEKEEPERS)
801
+ end
802
+ end
803
+ local x = staticToSpawn.x
804
+ local y = staticToSpawn.y
805
+ local heading = staticToSpawn.heading
806
+ local name = string.format("%s_%s_%i", subRangeName, staticTypeToSpawn, index)
807
+ local static = spawnStatic:SpawnFromPointVec2( POINT_VEC2:New( x, y ), heading, name )
808
+ debug_msg(string.format("Static type to spawn %s at %i,%i -> %s", static:GetDCSObject():getTypeName(), x, y, static:GetDCSObject():getName()))
809
+ else
810
+ debug_msg(string.format("Static to spawn has no name or type!"))
811
+ end
812
+ end
813
+ else
814
+ debug_msg(string.format("No static in %s", subRangeName))
815
+ end
816
+
817
+ for i = 1, #groupsToSpawn do
818
+ local groupNameToSpawn = string.format("%s", groupsToSpawn[i])
819
+ if (GROUP:FindByName(groupNameToSpawn) ~= nil) then
820
+ local spawnGroup = SPAWN:New(groupNameToSpawn)
821
+ debug_msg(string.format("SPAWN %s", groupNameToSpawn))
822
+ local groupSpawning
823
+ if (subRangeConfig.spawnZone) then
824
+ groupSpawning = spawnGroup:SpawnInZone(ZONE:New(subRangeConfig.spawnZone),true)
825
+ else
826
+ groupSpawning = spawnGroup:Spawn()
827
+ end
828
+ if (holdFire) then
829
+ groupSpawning:OptionROEHoldFire()
830
+ else
831
+ groupSpawning:OptionROEOpenFire()
832
+ end
833
+ if (engageAirWeapons) then
834
+ groupSpawning:SetOption(AI.Option.Ground.id.ENGAGE_AIR_WEAPONS, true)
835
+ end
836
+ if (activateAI == true or activateAI == false) then
837
+ groupSpawning:SetAIOnOff(activateAI)
838
+ end
839
+ if (redAlert == true or redAlert == false) then
840
+ if (redAlert == true) then
841
+ groupSpawning:OptionAlarmStateRed()
842
+ else
843
+ groupSpawning:OptionAlarmStateGreen()
844
+ end
845
+ else
846
+ groupSpawning:OptionAlarmStateAuto()
847
+ end
848
+ if (string.find(groupNameToSpawn, "SAM") ~= nil) then
849
+ sead:UpdateSet(groupNameToSpawn)
850
+ debug_msg(string.format("SEAD for %s", groupNameToSpawn))
851
+ end
852
+ else
853
+ debug_msg(string.format("GROUP to spawn %s not found in mission", groupNameToSpawn))
854
+ end
855
+ end
856
+
857
+ radioCommandSubRange:RemoveSubMenus()
858
+ local CommandZoneDetroy = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Delete", radioCommandSubRange,
859
+ deleteSubRangeUnits, {groupsToSpawn, rangeConfig, subRangeConfig, radioCommandSubRange, true})
860
+ local ROE = MENU_COALITION:New(rangeConfig.benefit_coalition, "ROE", radioCommandSubRange)
861
+ local ROEOpenFire = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Open Fire", ROE, setROE,
862
+ {groupsToSpawn, ENUMS.ROE.OpenFire})
863
+ local ROEReturnFire = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Return Fire", ROE, setROE,
864
+ {groupsToSpawn, ENUMS.ROE.ReturnFire})
865
+ local ROEHoldFire = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Hold Fire", ROE, setROE,
866
+ {groupsToSpawn, ENUMS.ROE.WeaponHold})
867
+ local AlarmState = MENU_COALITION:New(rangeConfig.benefit_coalition, "Alarm State", radioCommandSubRange)
868
+ local AlarmStateAuto = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Auto", AlarmState, setAlarmState,
869
+ {groupsToSpawn, ENUMS.AlarmState.Auto})
870
+ local AlarmStateGreen = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Green", AlarmState, setAlarmState,
871
+ {groupsToSpawn, ENUMS.AlarmState.Green})
872
+ local AlarmStateRed = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Red", AlarmState, setAlarmState,
873
+ {groupsToSpawn, ENUMS.AlarmState.Red})
874
+ local Engage_Air_Weapons = MENU_COALITION:New(rangeConfig.benefit_coalition, "Engage Air Weapons", radioCommandSubRange)
875
+ local Engage_Air_Weapons_True = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "True", Engage_Air_Weapons, setEngageAirWeapons,
876
+ {groupsToSpawn, true})
877
+ local Engage_Air_Weapons_False = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "False", Engage_Air_Weapons, setEngageAirWeapons,
878
+ {groupsToSpawn, false})
879
+ local CommandZoneFumigene = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Smoke", radioCommandSubRange,
880
+ smokeOnSubRange, {groupsToSpawn, rangeConfig.benefit_coalition})
881
+ local CommandZoneCoord = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "Coordinates",
882
+ radioCommandSubRange, giveToClientGroupCoordinates, {groupsToSpawn})
883
+ local CommandZoneListGroup = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "List Groups",
884
+ radioCommandSubRange, giveListOfGroupsAliveInRange, {groupsToSpawn, rangeConfig, subRangeConfig})
885
+ local CommandZoneList = MENU_COALITION_COMMAND:New(rangeConfig.benefit_coalition, "List Units",
886
+ radioCommandSubRange, giveListOfUnitsAliveInGroup, {groupsToSpawn, rangeConfig.benefit_coalition, 5})
887
+ MESSAGE:NewType(string.format("Units in range %s(%s) in place", rangeName, subRangeName), MESSAGE.Type.Information)
888
+ :ToCoalition(rangeConfig.benefit_coalition)
889
+ markGroupOnMap({groupsToSpawn, rangeConfig.benefit_coalition})
890
+ end
891
+
892
+ function deleteSubRangeUnits(param)
893
+ --parameters :
894
+ -- 1 : groups to be destroyed
895
+ -- 2 : Root range config Object
896
+ -- 3 : sub (or subsub) Range Config Object
897
+ -- 4 : sub (or subsub) Radio Menu
898
+ -- 5 : mute switch
899
+ local groupsToSpawn = param[1]
900
+ local rangeConfig = param[2]
901
+ local subRangeConfig = param[3]
902
+ local radioCommandSubRange = param[4]
903
+ local blnMute = param[5]
904
+ for i = 1, #groupsToSpawn do
905
+ destroyGroup(groupsToSpawn[i])
906
+ end
907
+
908
+ local subRangeName = subRangeConfig.name
909
+ local staticsToDelete = subRangeConfig.staticsToSpawn
910
+ if (staticsToDelete ~= nil)then
911
+ destroyStatics(staticsToDelete, subRangeName)
912
+ else
913
+ debug_msg(string.format("No static in %s", subRangeName))
914
+ end
915
+
916
+ MESSAGE:NewType(string.format("Remove the site : %s-%s", rangeConfig.name, subRangeConfig.name),
917
+ MESSAGE.Type.Information):ToBlue()
918
+ if (not(blnMute)) then
919
+ sound2Bip:ToAll()
920
+ end
921
+ if radioCommandSubRange then
922
+ radioCommandSubRange:RemoveSubMenus()
923
+ addSubRangeRadioMenus(radioCommandSubRange, rangeConfig, subRangeConfig)
924
+ end
925
+ end
926
+
927
+ function deleteWholeRangeUnits(param)
928
+ local rangeConfig = param[1]
929
+ local rangeCoalitionMenu = param[2]
930
+ rangeCoalitionMenu:RemoveSubMenus()
931
+ if (rangeConfig.subRange ~= nil ) then
932
+ sound2Bip:ToAll()
933
+ MESSAGE:NewType(string.format("Removing the whole site : %s", rangeConfig.name),
934
+ MESSAGE.Type.Information):ToCoalition(rangeConfig.benefit_coalition)
935
+ for subIndex, subRangeConfig in ipairs(rangeConfig.subRange) do
936
+ local radioMenuSubRange = MENU_COALITION:New(rangeConfig.benefit_coalition, subRangeConfig.name, rangeCoalitionMenu)
937
+ if (subRangeConfig.subsubRange ~= nil) then
938
+ for subsubIndex, subsubRangeConfig in ipairs(subRangeConfig.subsubRange) do
939
+ local radioMenuSubSubRange = MENU_COALITION:New(rangeConfig.benefit_coalition, subsubRangeConfig.name, radioMenuSubRange)
940
+ deleteSubRangeUnits({
941
+ subsubRangeConfig.groupsToSpawn,
942
+ rangeConfig,
943
+ subsubRangeConfig,
944
+ nil,
945
+ true
946
+ })
947
+ addSubRangeRadioMenus(radioMenuSubSubRange, rangeConfig, subsubRangeConfig)
948
+ end
949
+ else
950
+ deleteSubRangeUnits({
951
+ subRangeConfig.groupsToSpawn,
952
+ rangeConfig,
953
+ subRangeConfig,
954
+ nil,
955
+ true
956
+ })
957
+ addSubRangeRadioMenus(radioMenuSubRange, rangeConfig, subRangeConfig)
958
+ end
959
+ end
960
+ end
961
+ AddWholeRangeCoalitionCommandMenus(rangeCoalitionMenu, rangeConfig)
962
+ end
963
+
964
+ function SpawnFacRangesDelay(param)
965
+ local facRangeConfig = param[2]
966
+ local facSubRangeConfig = param[3]
967
+ local delay = param[4] or 10
968
+ MESSAGE:NewType(string.format("Warning, FAC in range %s(%s) will spawn in %d sec", facRangeConfig.name, facSubRangeConfig.name, delay), MESSAGE.Type.Update):ToBlue()
969
+ TIMER:New(SpawnFacRanges, param):Start(delay)
970
+ end
971
+
972
+ function SpawnFacRanges(param)
973
+ local radioCommandSubRange = param[1]
974
+ local facRangeConfig = param[2]
975
+ local facRangeName = facRangeConfig.name
976
+ local facSubRangeConfig = param[3]
977
+ local facSubRangeName = facSubRangeConfig.name
978
+ local groupsToSpawn = facSubRangeConfig.groupsToSpawn
979
+ local staticsToSpawn = facSubRangeConfig.staticsToSpawn
980
+
981
+ debug_msg(string.format("SpawnFacRanges : %s-%s", facRangeName, facSubRangeName))
982
+ for i = 1, #groupsToSpawn do
983
+ local groupNameToSpawn = string.format("%s", groupsToSpawn[i])
984
+ if (GROUP:FindByName(groupNameToSpawn) ~= nil) then
985
+ local spawnGroup = SPAWN:New(groupNameToSpawn)
986
+ debug_msg(string.format("SPAWN %s", groupNameToSpawn))
987
+ local groupSpawning
988
+ if (facSubRangeConfig.spawnZone) then
989
+ groupSpawning = spawnGroup:SpawnInZone(ZONE:New(facSubRangeConfig.spawnZone),true)
990
+ else
991
+ groupSpawning = spawnGroup:Spawn()
992
+ end
993
+ groupSpawning:SetCommandInvisible(true)
994
+ else
995
+ debug_msg(string.format("GROUP to spawn %s not found in mission", groupNameToSpawn))
996
+ end
997
+ end
998
+
999
+ radioCommandSubRange:RemoveSubMenus()
1000
+ local CommandZoneDetroy = MENU_COALITION_COMMAND:New(facRangeConfig.benefit_coalition, "Delete", radioCommandSubRange,
1001
+ deleteSubRangeUnits, { groupsToSpawn, facRangeConfig, facSubRangeConfig, radioCommandSubRange, true})
1002
+ local CommandZoneFumigene = MENU_COALITION_COMMAND:New(facRangeConfig.benefit_coalition, "Smoke", radioCommandSubRange,
1003
+ smokeOnSubRange, { groupsToSpawn, facRangeConfig.benefit_coalition})
1004
+ local CommandZoneCoord = MENU_COALITION_COMMAND:New(facRangeConfig.benefit_coalition, "Coordinates",
1005
+ radioCommandSubRange, giveToClientGroupCoordinates, {groupsToSpawn})
1006
+ local CommandZoneListGroup = MENU_COALITION_COMMAND:New(facRangeConfig.benefit_coalition, "List Groups",
1007
+ radioCommandSubRange, giveListOfGroupsAliveInRange, { groupsToSpawn, facRangeConfig, facSubRangeConfig })
1008
+ local CommandZoneList = MENU_COALITION_COMMAND:New(facRangeConfig.benefit_coalition, "List Units",
1009
+ radioCommandSubRange, giveListOfUnitsAliveInGroup, { groupsToSpawn, facRangeConfig.benefit_coalition, 5})
1010
+ MESSAGE:NewType(string.format("FAC in range %s(%s) in place", facRangeName, facSubRangeName), MESSAGE.Type.Information)
1011
+ :ToBlue()
1012
+ markGroupOnMap({ groupsToSpawn, facRangeConfig.benefit_coalition})
1013
+ end
1014
+
1015
+ function AddFacFunction(radioCommandSubRange, facRangeConfig, facSubRangeConfig)
1016
+ local RadioCommandAdd = MENU_COALITION_COMMAND:New(
1017
+ facRangeConfig.benefit_coalition,
1018
+ "Spawn",
1019
+ radioCommandSubRange,
1020
+ SpawnFacRangesDelay,
1021
+ {
1022
+ radioCommandSubRange,
1023
+ facRangeConfig,
1024
+ facSubRangeConfig,
1025
+ spawnStandardDelay,
1026
+ AddFacFunction
1027
+ }
1028
+ )
1029
+ end
1030
+
1031
+ function GetTableLng(tbl)
1032
+ local getN = 0
1033
+ for n in pairs(tbl) do
1034
+ getN = getN + 1
1035
+ end
1036
+ return getN
1037
+ end
1038
+
1039
+ function getSoundFilesPrefix()
1040
+ local strPrefix
1041
+ local lfs = require("lfs")
1042
+ if (use_jtff_sound_mod) then
1043
+ strPrefix = lfs.writedir() .. 'Sounds/JTFF-Missions/'
1044
+ else
1045
+ strPrefix = ""
1046
+ end
1047
+ return strPrefix
1048
+ end
1049
+
1050
+ env.info('JTFF-SHAREDLIB: shared library loaded succesfully')
1051
+
1052
+ soundFilesPrefix = getSoundFilesPrefix()
1053
+
1054
+
1055
+ sound2Bip = USERSOUND:New( soundFilesPrefix .. "Misc/2_Bips.ogg" )
1056
+ sound1Bip = USERSOUND:New( soundFilesPrefix .. "Misc/Bip.ogg" )
1057
+ soundCrashWood = USERSOUND:New( soundFilesPrefix .. "Misc/crash_wood.ogg" )
1058
+
1059
+ sound1Bip:ToAll()