@jtff/miztemplate-lib 3.5.9 → 3.6.0

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.
@@ -0,0 +1,25 @@
1
+ QRAConfig = {
2
+ {
3
+ enable = false,
4
+ name = "QRA Training AutoSpawn",
5
+ type = JTFF_QRA.Type.TangoAuto,
6
+ benefit_coalition = coalition.side.BLUE,
7
+ templates = {
8
+ 'qra_armed',
9
+ 'qra_safe',
10
+ },
11
+ skill = 'Excellent'
12
+ },
13
+ {
14
+ enable = false,
15
+ name = "QRA Training ManualSpawn",
16
+ type = JTFF_QRA.Type.TangoManual,
17
+ benefit_coalition = coalition.side.BLUE,
18
+ },
19
+ {
20
+ enable = false,
21
+ name = "QRA Alpha",
22
+ type = JTFF_QRA.Type.Alpha,
23
+ benefit_coalition = coalition.side.BLUE,
24
+ },
25
+ }
@@ -1135,13 +1135,31 @@ function spawnStaticListWithUnitLink(layoutData, namePrefix, unitID, countryID)
1135
1135
  end
1136
1136
  end
1137
1137
 
1138
+ function ClientIsOnGround(client)
1139
+ jtff_log.trace(string.format("Client %s is tested if alive and OnGround", client:GetPlayer() or ""),"QRA")
1140
+ return UNIT:Find(client:GetDCSObject()):IsAlive() and not(UNIT:Find(client:GetDCSObject()):InAir(true))
1141
+ end
1142
+
1143
+ -- @field #JTFF_QRA JTFF_QRA
1144
+ JTFF_QRA = {
1145
+ ClassName = "JTFF_QRA",
1146
+ }
1147
+
1148
+ --- QRA Types
1149
+ -- @type JTFF_QRA.Type
1150
+ JTFF_QRA.Type = {
1151
+ TangoAuto = "Tango Scramble Auto Spawn",
1152
+ TangoManual = "Tango Scramble Manual Spawn",
1153
+ Alpha = "Alpha Scramble",
1154
+ }
1155
+
1138
1156
  env.info('JTFF-SHAREDLIB: shared library loaded succesfully')
1139
1157
 
1140
1158
  soundFilesPrefix = getSoundFilesPrefix()
1141
1159
 
1142
-
1143
1160
  sound2Bip = USERSOUND:New( soundFilesPrefix .. "Misc/2_Bips.ogg" )
1144
1161
  sound1Bip = USERSOUND:New( soundFilesPrefix .. "Misc/Bip.ogg" )
1145
1162
  soundCrashWood = USERSOUND:New( soundFilesPrefix .. "Misc/crash_wood.ogg" )
1163
+ soundQRA = USERSOUND:New( soundFilesPrefix .. "Misc/SCRAMBLE QRA.ogg" )
1146
1164
 
1147
1165
  sound1Bip:ToAll()
@@ -11,7 +11,6 @@ function Set_CLIENT:OnEventPlayerEnterAircraft(EventData)
11
11
  clientSetting:SetImperial()
12
12
  clientSetting:SetA2G_MGRS()
13
13
  clientSetting:SetMenutextShort(true)
14
- jtff_log.debug(string.format("Add Tanker Menu for group [%s], player name [%s]",EventData.IniGroupName , EventData.IniPlayerName),"TANKER")
15
14
  if type(InterceptArray) == 'table' then
16
15
  for index, objIntercept in ipairs(InterceptArray) do
17
16
  if (objIntercept.menus[EventData.IniUnit:GetCoalition()]) then
@@ -23,6 +22,25 @@ function Set_CLIENT:OnEventPlayerEnterAircraft(EventData)
23
22
  end
24
23
  end
25
24
  end
25
+ jtff_log.debug(string.format("Add QRA Menu for group [%s], player name [%s]",EventData.IniGroupName , EventData.IniPlayerName),"QRA")
26
+ if type(QRAArray) == 'table' then
27
+ for index, objQRA in ipairs(QRAArray) do
28
+ if (MenuCoalitionQRA[EventData.IniUnit:GetCoalition()]) and (objQRA.customconfig.type == JTFF_QRA.Type.TangoAuto) then
29
+ objQRA.menu[EventData.IniUnit:GetCoalition()] = MENU_GROUP_COMMAND:New(
30
+ EventData.IniGroup,
31
+ "Trigger " .. objQRA.customconfig.name,
32
+ MenuCoalitionQRA[EventData.IniUnit:GetCoalition()],
33
+ QRATrigger,
34
+ {
35
+ objQRA,
36
+ EventData.IniUnit:GetName(),
37
+ index,
38
+ }
39
+ )
40
+ end
41
+ end
42
+ end
43
+ jtff_log.debug(string.format("Add Tanker Menu for group [%s], player name [%s]",EventData.IniGroupName , EventData.IniPlayerName),"TANKER")
26
44
  if EventData.IniUnit:GetCoalition() == coalition.side.BLUE then
27
45
  MENU_GROUP_COMMAND:New( EventData.IniGroup, "Nearest Tanker Info", MenuCoalitionTankerBlue, NearestTankerInfo, { EventData.IniUnit, EventData.IniGroup} )
28
46
  MENU_GROUP_COMMAND:New( EventData.IniGroup, "All Tankers Info", MenuCoalitionTankerBlue, AllTankersInfo, {EventData.IniUnit,EventData.IniGroup} )
@@ -84,4 +102,4 @@ end
84
102
  Set_CLIENT_Bleu = SET_CLIENT:New():FilterCoalitions(coalition.side.BLUE):FilterOnce()
85
103
  jtff_log.debug(string.format("Nbre Blue Client : %i", Set_CLIENT_Bleu:Count()),"GENERAL")
86
104
  Set_CLIENT_Red = SET_CLIENT:New():FilterCoalitions(coalition.side.RED):FilterOnce()
87
- jtff_log.debug(string.format("Nbre Red Client : %i", Set_CLIENT_Red:Count()),"GENERAL")
105
+ jtff_log.debug(string.format("Nbre Red Client : %i", Set_CLIENT_Red:Count()),"GENERAL")
@@ -0,0 +1,349 @@
1
+ function playQRASoundToClient(client, time)
2
+ soundQRA:ToClient(client)
3
+ return nil
4
+ end
5
+
6
+ function QRALaunchBogey(params)
7
+ local objQRA = params[1]
8
+ local trigerringUnitName = params[2]
9
+ local QRAIndex = params[3]
10
+ local playerClient = CLIENT:FindByName(trigerringUnitName)
11
+ local playerCoord = playerClient:GetCoordinate()
12
+ local bogeyGroup = nil
13
+ local bogeyRouteLengthNM = 200
14
+ local bogeyRangeMin = 100
15
+ local bogeyRangeMax = 300
16
+ local bogeyFLMin = 5
17
+ local bogeyFLMax = 250
18
+ local bogeyAzimuthMin = 0
19
+ local bogeyAzimuthMax = 359
20
+ local bogeyGroundSpeedKnots = 600
21
+ local bogeyAzimuth = math.floor(
22
+ math.random(
23
+ UTILS.FeetToMeters(bogeyAzimuthMin),
24
+ UTILS.FeetToMeters(bogeyAzimuthMax)
25
+ )
26
+ )
27
+ local bogeyFL = math.floor(
28
+ math.random(
29
+ UTILS.FeetToMeters(bogeyFLMin * 100),
30
+ UTILS.FeetToMeters(bogeyFLMax * 100)
31
+ )
32
+ )
33
+ local bogeyRangeMeters = math.floor(
34
+ math.random(
35
+ UTILS.NMToMeters(bogeyRangeMin),
36
+ UTILS.NMToMeters(bogeyRangeMax)
37
+ )
38
+ )
39
+ local bogeySpawnObj = QRAArray[QRAIndex].objSpawn
40
+ local bogeyCoord = POINT_VEC3:NewFromVec3(
41
+ {
42
+ x = playerCoord.x + math.floor(bogeyRangeMeters * math.cos(math.rad(bogeyAzimuth))),
43
+ y = math.max(
44
+ math.min(
45
+ bogeyFL,
46
+ UTILS.FeetToMeters(32000)
47
+ ),
48
+ UTILS.FeetToMeters(500)
49
+ ),
50
+ z = playerCoord.z + math.floor(bogeyRangeMeters * math.sin(math.rad(bogeyAzimuth))),
51
+ }
52
+ )
53
+ local bogeyDestination = playerCoord:GetRandomCoordinateInRadius(
54
+ UTILS.NMToMeters(10),
55
+ UTILS.NMToMeters(60)
56
+ )
57
+ local bogeyHeading = bogeyCoord:HeadingTo(bogeyDestination)
58
+ jtff_log.info(
59
+ string.format(
60
+ "Spawning bogey based on %s with Heading of %i degrees",
61
+ bogeySpawnObj.SpawnTemplatePrefix,
62
+ bogeyHeading
63
+ ),
64
+ "QRA"
65
+ )
66
+ bogeyGroup = bogeySpawnObj:InitHeading(bogeyHeading):SpawnFromVec3(bogeyCoord)
67
+ bogeyGroup:OptionROE(ENUMS.ROE.WeaponHold)
68
+ bogeyGroup:OptionROT(ENUMS.ROT.NoReaction)
69
+ bogeyGroup:OptionRTBBingoFuel(true)
70
+ bogeyGroup:OptionRestrictBurner(false)
71
+ bogeyGroup:EnableEmission(false)
72
+ bogeyGroup:OptionAlarmStateGreen()
73
+ bogeyGroup:OptionECM_Never()
74
+ bogeyGroup:CommandEPLRS(true)
75
+ local bogeyDestinationCoord = bogeyGroup:GetCoordinate():Translate(
76
+ UTILS.NMToMeters(bogeyRouteLengthNM),
77
+ bogeyHeading,
78
+ true,
79
+ false
80
+ )
81
+ bogeyGroup:Route(
82
+ {
83
+ bogeyDestinationCoord:WaypointAirTurningPoint(
84
+ COORDINATE.WaypointAltType.BARO,
85
+ UTILS.KnotsToKmph(bogeyGroundSpeedKnots),
86
+ nil,
87
+ "End QRA"
88
+ ),
89
+ bogeyDestinationCoord:GetClosestAirbase(
90
+ --bogeyGroup:GetCategory(),
91
+ --bogeyGroup:GetCoalition()
92
+ ):GetCoordinate():WaypointAirLanding(
93
+ UTILS.KnotsToKmph(bogeyGroundSpeedKnots),
94
+ bogeyDestinationCoord:GetClosestAirbase(
95
+ --bogeyGroup:GetCategory(),
96
+ --bogeyGroup:GetCoalition()
97
+ )
98
+ )
99
+ }
100
+ )
101
+ return bogeyGroup
102
+ end
103
+
104
+ function QRATrigger(params)
105
+ local objQRA = params[1]
106
+ local trigerringUnitName = params[2]
107
+ local QRAIndex = params[3]
108
+ local msgTriggeredGround = ""
109
+ local msgTriggeredOthers = ""
110
+ if (objQRA.customconfig.type == JTFF_QRA.Type.TangoAuto) then
111
+ local playerClient = CLIENT:FindByName(trigerringUnitName)
112
+ local playerName = playerClient:GetPlayer()
113
+ local playerCoord = playerClient:GetCoordinate()
114
+ QRAArray[QRAIndex].objBogeyGroup = QRALaunchBogey(params)
115
+ local bullsCoord = COORDINATE.GetBullseyeCoordinate(objQRA.customconfig.benefit_coalition)
116
+ local bogeyCoord = QRAArray[QRAIndex].objBogeyGroup:GetCoordinate()
117
+ local bullsBearing = math.floor(bullsCoord:HeadingTo(bogeyCoord))
118
+ local bullsRange = math.floor(UTILS.MetersToNM(bullsCoord:Get2DDistance(bogeyCoord)))
119
+ local bogeyAngel = math.floor(UTILS.MetersToFeet(QRAArray[QRAIndex].objBogeyGroup:GetAltitude(false))/1000)
120
+ local bogeyApproxDestination = playerCoord:GetClosestAirbase():GetName()
121
+ jtff_log.info(
122
+ string.format(
123
+ "Bogey Spawned based on %s",
124
+ QRAArray[QRAIndex].objSpawn.SpawnTemplatePrefix
125
+ ),
126
+ "QRA"
127
+ )
128
+ jtff_log.info(
129
+ string.format("Bogey is Bulls %i for %i Angel %i, tracking to %s",
130
+ bullsBearing,
131
+ bullsRange,
132
+ bogeyAngel,
133
+ bogeyApproxDestination
134
+ ),
135
+ "QRA"
136
+ )
137
+ local formatString = "QRA %s has been triggered by %s!\n" ..
138
+ "Type is : %s\n" ..
139
+ "Bogey is Bulls %i for %i Angel %i, tracking %s\n" ..
140
+ "If you're on Alert," ..
141
+ " you have 10 minutes to take-off and intercept the bogey.\n" ..
142
+ "If you're not, please give %s priority on the taxiway.\n"
143
+ msgTriggeredGround = string.format(
144
+ formatString,
145
+ objQRA.customconfig.name,
146
+ playerName,
147
+ objQRA.customconfig.type,
148
+ bullsBearing,
149
+ bullsRange,
150
+ bogeyAngel,
151
+ bogeyApproxDestination,
152
+ playerName
153
+ )
154
+ formatString = "<WARNING> : QRA Triggered by %s!\n" ..
155
+ "A Bogey is approaching %s, " ..
156
+ "stay away from the interception area\n" ..
157
+ "...\n" ..
158
+ "Bogey last position : Bulls %i for %i Angel %i, tracking to %s"
159
+ msgTriggeredOthers = string.format(formatString,
160
+ playerName,
161
+ playerCoord:GetClosestAirbase():GetName(),
162
+ bullsBearing,
163
+ bullsRange,
164
+ bogeyAngel,
165
+ bogeyApproxDestination
166
+ )
167
+ elseif (objQRA.customconfig.type == JTFF_QRA.Type.TangoManual) then
168
+ local playerClient
169
+ local playerName
170
+ local playerCoord
171
+ if type(trigerringUnitName) == 'nil' then
172
+ playerName = "GameMaster"
173
+ playerClient = nil
174
+ playerCoord = COORDINATE.GetBullseyeCoordinate(objQRA.customconfig.benefit_coalition)
175
+ else
176
+ playerClient = CLIENT:FindByName(trigerringUnitName)
177
+ playerName = playerClient:GetPlayer()
178
+ playerCoord = playerClient:GetCoordinate()
179
+ end
180
+ local formatString = "QRA %s has been triggered by %s !\n" ..
181
+ "Type is : %s\n" ..
182
+ "If you're on Alert," ..
183
+ " you have 10 minutes to take-off and start intercepting the the bogey.\n" ..
184
+ "You are cleared to start and wait your AIC for scramble information\n\n\n" ..
185
+ "If you're not on alert, please monitor the ground frequency" ..
186
+ " and let the scramble flight taxi in highest priority..."
187
+ msgTriggeredGround = string.format(
188
+ formatString,
189
+ objQRA.customconfig.name,
190
+ playerName,
191
+ objQRA.customconfig.type
192
+ )
193
+ formatString = "<WARNING> : QRA Training triggered by %s!\n" ..
194
+ "Stay away from the interception area (%s)\n" ..
195
+ "...\n" ..
196
+ "Keep monitoring your tactical frequency" ..
197
+ " for information about the Scramble procedure"
198
+ msgTriggeredOthers = string.format(formatString,
199
+ playerName,
200
+ type(playerClient) ~= 'nil' and playerCoord:ToStringMGRS() or ""
201
+ )
202
+ elseif (objQRA.customconfig.type == JTFF_QRA.Type.Alpha) then
203
+ local playerClient
204
+ local playerName
205
+ local playerCoord
206
+ if type(trigerringUnitName) == 'nil' then
207
+ playerName = "GameMaster"
208
+ playerClient = nil
209
+ playerCoord = COORDINATE.GetBullseyeCoordinate(objQRA.customconfig.benefit_coalition)
210
+ else
211
+ playerClient = CLIENT:FindByName(trigerringUnitName)
212
+ playerName = playerClient:GetPlayer()
213
+ playerCoord = playerClient:GetCoordinate()
214
+ end
215
+ local formatString = "QRA %s has been triggered by %s !\n" ..
216
+ "Type is : %s\n" ..
217
+ "If you're on Alert," ..
218
+ " you have 10 minutes to take-off and start intercepting the the bogey.\n" ..
219
+ "You are cleared to start and wait your AIC for scramble information\n\n\n" ..
220
+ "If you're not on alert, please monitor the ground frequency" ..
221
+ " and let the scramble flight taxi in highest priority..."
222
+ msgTriggeredGround = string.format(
223
+ formatString,
224
+ objQRA.customconfig.name,
225
+ playerName,
226
+ objQRA.customconfig.type
227
+ )
228
+ formatString = "<WARNING> : QRA Triggered by %s!\n" ..
229
+ "Stay away from the interception area (%s)\n" ..
230
+ "...\n" ..
231
+ "Keep monitoring your tactical frequency" ..
232
+ " for information about the Scramble procedure"
233
+ msgTriggeredOthers = string.format(formatString,
234
+ playerName,
235
+ type(playerClient) ~= 'nil' and playerCoord:ToStringMGRS() or ""
236
+ )
237
+ else
238
+ end
239
+ objQRA.clientSet:ForEachClient(
240
+ function(clientObject)
241
+ if ClientIsOnGround(clientObject) then
242
+ playQRASoundToClient(clientObject)
243
+ timer.scheduleFunction(
244
+ playQRASoundToClient,
245
+ clientObject,
246
+ timer.getTime() + 17
247
+ )
248
+ MESSAGE:New(msgTriggeredGround,60):ToClient(clientObject)
249
+ end
250
+ end
251
+ )
252
+ MESSAGE:New(msgTriggeredOthers,30):ToCoalition(objQRA.customconfig.benefit_coalition)
253
+ QRAArray[QRAIndex].menu_finex[QRAArray[QRAIndex].customconfig.benefit_coalition] = MENU_COALITION_COMMAND:New(
254
+ QRAArray[QRAIndex].customconfig.benefit_coalition,
255
+ "FinEx - " .. QRAArray[QRAIndex].customconfig.name .. " !!",
256
+ MenuCoalitionQRA[QRAArray[QRAIndex].customconfig.benefit_coalition],
257
+ QRAFinex,
258
+ QRAIndex
259
+ )
260
+ end
261
+
262
+ function QRAFinex(objQRAIndex)
263
+ local objQRA = QRAArray[objQRAIndex]
264
+ if objQRA.customconfig.type == JTFF_QRA.Type.TangoAuto then
265
+ jtff_log.trace(string.format("objQRA.objSpawn is %s", net.lua2json(objQRA.objSpawn)),"QRA")
266
+ local GroupPlane, Index = objQRA.objSpawn:GetFirstAliveGroup()
267
+ while GroupPlane ~= nil do
268
+ GroupPlane:ScheduleStop()
269
+ GroupPlane:Destroy(true,0)
270
+ GroupPlane, Index = objQRA.objSpawn:GetNextAliveGroup( Index )
271
+ end
272
+ collectgarbage()
273
+ end
274
+ QRAArray[objQRAIndex].menu_finex[QRAArray[objQRAIndex].customconfig.benefit_coalition]:Remove()
275
+ QRAArray[objQRAIndex].menu_finex[QRAArray[objQRAIndex].customconfig.benefit_coalition] = nil
276
+ end
277
+
278
+
279
+
280
+ JTFF_LOGLEVEL = 'debug'
281
+
282
+ -- *****************************************************************************
283
+ -- ** QRA **
284
+ -- *********************************************************
285
+ QRAArray = {}
286
+ compteur = 0
287
+ MenuCoalitionQRA = {}
288
+ MenuCoalitionQRA[coalition.side.BLUE] = MENU_COALITION:New(coalition.side.BLUE, "QRA", MenuCoalitionBlue)
289
+ MenuCoalitionQRA[coalition.side.RED] = MENU_COALITION:New(coalition.side.RED, "QRA", MenuCoalitionRed)
290
+ for index, qraconfig in ipairs(QRAConfig) do
291
+ if qraconfig.enable == true then
292
+ compteur = compteur + 1
293
+ jtff_log.info('creation QRA : '.. qraconfig.name..'...',"QRA")
294
+ local objQRA = {
295
+ customconfig = {},
296
+ clientSet = nil,
297
+ objSpawn = nil,
298
+ objBogeyGroup = nil,
299
+ menu = {},
300
+ menu_finex = {},
301
+ }
302
+ if ( qraconfig.type == JTFF_QRA.Type.TangoAuto) then
303
+ objQRA.objSpawn = SPAWN:New(qraconfig.templates[1])
304
+ :InitSkill(qraconfig.skill)
305
+ :InitRandomizeTemplate(qraconfig.templates or {})
306
+ end
307
+ objQRA.clientSet = SET_CLIENT:New()
308
+ :FilterCoalitions(string.lower(UTILS.GetCoalitionName(qraconfig.benefit_coalition)))
309
+ :FilterCategories("plane")
310
+ :FilterActive(true)
311
+ :FilterFunction(ClientIsOnGround)
312
+ :FilterStart()
313
+ objQRA.clientSet:HandleEvent(EVENTS.PlayerEnterAircraft)
314
+ jtff_log.debug(string.format("Nbr Clients getting QRA Calls : %i", objQRA.clientSet:Count()),"QRA")
315
+
316
+ function objQRA.clientSet:OnEventPlayerEnterAircraft(EventData)
317
+ local clientObject = CLIENT:Find(EventData.IniUnit:GetDCSObject())
318
+ if ClientIsOnGround(clientObject) then
319
+ --self:Add(clientObject:GetPlayer(), clientObject)
320
+ jtff_log.debug(string.format("Added %s to QRA receivers", clientObject:GetPlayer() or ""),"QRA")
321
+ jtff_log.debug(string.format("Nbr Clients getting QRA Calls : %i", objQRA.clientSet:Count()),"QRA")
322
+ end
323
+ end
324
+
325
+ if ( qraconfig.type ~= JTFF_QRA.Type.TangoAuto) then
326
+ objQRA.menu[qraconfig.benefit_coalition] = MENU_COALITION_COMMAND:New(
327
+ qraconfig.benefit_coalition,
328
+ "Trigger " .. qraconfig.name,
329
+ MenuCoalitionQRA[qraconfig.benefit_coalition],
330
+ QRATrigger,
331
+ {
332
+ objQRA,
333
+ nil,
334
+ index,
335
+ }
336
+ )
337
+ end
338
+
339
+ objQRA.customconfig = qraconfig
340
+
341
+ QRAArray[compteur] = objQRA
342
+ end
343
+ end
344
+
345
+ if compteur == 0 then
346
+ MenuCoalitionQRA[coalition.side.BLUE]:Remove()
347
+ MenuCoalitionQRA[coalition.side.RED]:Remove()
348
+ MenuCoalitionQRA = {}
349
+ end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jtff/miztemplate-lib",
3
- "version": "3.5.9",
3
+ "version": "3.6.0",
4
4
  "description": "JTFF mission template library",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -399,7 +399,7 @@ async function doInject(ciObject, sourceMizFileName, workspacePath,destinationMi
399
399
  scriptsArray.push({
400
400
  folder: 'src',
401
401
  scriptTitle: 'Air To Air',
402
- scripts: ['170-cap_zone_training.lua', '172-cap_zone_war.lua', '173-fox_zone_training.lua', '176-random_air_traffic.lua', '178-training-intercept.lua'],
402
+ scripts: ['170-cap_zone_training.lua', '172-cap_zone_war.lua', '173-fox_zone_training.lua', '174-qra-scenario.lua', '176-random_air_traffic.lua', '178-training-intercept.lua'],
403
403
  timing: 27,
404
404
  color: '0xff0000ff',
405
405
  fromLibrary: true