@jtff/miztemplate-lib 2.2.0 → 3.0.0-rc10
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/index.js +4 -3
- package/lib/jtff-lib-ci.js +4 -308
- package/lib/mizlib.js +321 -0
- package/lua/lib/Hercules_Cargo.lua +686 -0
- package/lua/lib/Moose_.lua +117314 -0
- package/lua/lib/Splash_Damage_2_0.lua +472 -0
- package/lua/lib/gemman.lua +1 -0
- package/lua/lib/mist_4_5_107.lua +9084 -0
- package/lua/lib/skynet-iads-compiled.lua +3864 -0
- package/lua/settings/settings-RAT.lua +235 -0
- package/lua/settings/settings-airboss.lua +142 -0
- package/lua/settings/settings-atis.lua +31 -0
- package/lua/settings/settings-awacs.lua +58 -0
- package/lua/settings/settings-awacsondemand.lua +26 -0
- package/lua/settings/settings-beacons.lua +10 -0
- package/lua/settings/settings-capwarzone.lua +164 -0
- package/lua/settings/settings-capzone.lua +32 -0
- package/lua/settings/settings-fac_ranges.lua +17 -0
- package/lua/settings/settings-foxzone.lua +14 -0
- package/lua/settings/settings-gemman.lua +6 -0
- package/lua/settings/settings-global.lua +31 -0
- package/lua/settings/settings-intercept.lua +23 -0
- package/lua/settings/settings-logistics.lua +22 -0
- package/lua/settings/settings-ondemandawacs.lua +29 -0
- package/lua/settings/settings-ondemandtankers.lua +29 -0
- package/lua/settings/settings-pedros.lua +11 -0
- package/lua/settings/settings-ranges.lua +28 -0
- package/lua/settings/settings-reapers.lua +25 -0
- package/lua/settings/settings-sams.lua +19 -0
- package/lua/settings/settings-skynet.lua +239 -0
- package/lua/settings/settings-tankers.lua +32 -0
- package/lua/settings/settings-training_ranges.lua +37 -0
- package/lua/src/010-root_menus.lua +5 -0
- package/lua/src/020-mission_functions.lua +1059 -0
- package/lua/src/110-set_clients.lua +61 -0
- package/lua/src/120-tankers.lua +589 -0
- package/lua/src/130-airboss.lua +621 -0
- package/lua/src/135-pedro.lua +21 -0
- package/lua/src/140-beacons.lua +19 -0
- package/lua/src/150-awacs.lua +599 -0
- package/lua/src/160-atis.lua +53 -0
- package/lua/src/170-cap_zone_training.lua +127 -0
- package/lua/src/172-cap_zone_war.lua +190 -0
- package/lua/src/173-fox_zone_training.lua +87 -0
- package/lua/src/176-random_air_traffic.lua +73 -0
- package/lua/src/178-training-intercept.lua +263 -0
- package/lua/src/180-logistics.lua +80 -0
- package/lua/src/190-ranges.lua +54 -0
- package/lua/src/191-sams.lua +49 -0
- package/lua/src/193-training_ranges.lua +191 -0
- package/lua/src/195-reaper-ondemand.lua +522 -0
- package/lua/src/196-fac_ranges.lua +34 -0
- package/lua/src/199-skynet.lua +721 -0
- package/lua/src/200-mission.lua +3 -0
- package/package.json +4 -3
- package/resources/radios/.gitkeep +0 -0
- package/resources/sounds/CTLD/beacon.ogg +0 -0
- package/resources/sounds/CTLD/beaconsilent.ogg +0 -0
- package/resources/sounds/Misc/.gitkeep +0 -0
- package/resources/sounds/Misc/2_Bips.ogg +0 -0
- package/resources/sounds/Misc/Bip.ogg +0 -0
- package/resources/sounds/Misc/crash_wood.ogg +0 -0
- package/scripts/build.js +1 -1
- package/scripts/inject-scripts.js +124 -228
- 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()
|