@jtff/miztemplate-lib 3.6.5 → 3.7.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jtff/miztemplate-lib",
3
- "version": "3.6.5",
3
+ "version": "3.7.0",
4
4
  "description": "JTFF mission template library",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -171,8 +171,8 @@ async function doInject(ciObject, sourceMizFileName, workspacePath,destinationMi
171
171
  // insertion des librairies externes dans la file d'attente
172
172
  libsArray.push({
173
173
  folder: 'lib',
174
- scriptTitle: 'SplashDamage 2.0',
175
- scripts: ['Splash_Damage_2_0.lua'],
174
+ scriptTitle: 'SplashDamage 3.0',
175
+ scripts: ['Splash_Damage_3.0.lua'],
176
176
  timing: 9,
177
177
  color: '0x008000ff'
178
178
  });
@@ -1,472 +0,0 @@
1
-
2
- --assert(loadfile("C:\\Users\\spenc\\OneDrive\\Documents\\Eclipe_LDT\\dcs splash damage\\src\\mist.lua"))()
3
- --[[
4
- 2 October 2020
5
- FrozenDroid:
6
- - Added error handling to all event handler and scheduled functions. Lua script errors can no longer bring the server down.
7
- - Added some extra checks to which weapons to handle, make sure they actually have a warhead (how come S-8KOM's don't have a warhead field...?)
8
-
9
- 28 October 2020
10
- FrozenDroid:
11
- - Uncommented error logging, actually made it an error log which shows a message box on error.
12
- - Fixed the too restrictive weapon filter (took out the HE warhead requirement)
13
-
14
- 21 December 2021
15
- spencershepard (GRIMM):
16
- SPLASH DAMAGE 2.0:
17
- -Added blast wave effect to add timed and scaled secondary explosions on top of game objects
18
- -object geometry within blast wave changes damage intensity
19
- -damage boost for structures since they are hard to kill, even if very close to large explosions
20
- -increased some rocket values in explTable
21
- -missing weapons from explTable will display message to user and log to DCS.log so that we can add what's missing
22
- -damage model for ground units that will disable their weapons and ability to move with partial damage before they are killed
23
- -added options table to allow easy adjustments before release
24
- -general refactoring and restructure
25
-
26
- 31 December 2021
27
- spencershepard (GRIMM):
28
- -added many new weapons
29
- -added filter for weapons.shells events
30
- -fixed mission weapon message option
31
- -changed default for damage_model option
32
-
33
- 16 April 2022
34
- spencershepard (GRIMM):
35
- added new/missing weapons to explTable
36
- added new option rocket_multiplier
37
- --]]
38
-
39
- ----[[ ##### SCRIPT CONFIGURATION ##### ]]----
40
-
41
- splash_damage_options = {
42
- ["static_damage_boost"] = 2000, --apply extra damage to Unit.Category.STRUCTUREs with wave explosions
43
- ["wave_explosions"] = false, --secondary explosions on top of game objects, radiating outward from the impact point and scaled based on size of object and distance from weapon impact point
44
- ["larger_explosions"] = true, --secondary explosions on top of weapon impact points, dictated by the values in the explTable
45
- ["damage_model"] = false, --allow blast wave to affect ground unit movement and weapons
46
- ["blast_search_radius"] = 100, --this is the max size of any blast wave radius, since we will only find objects within this zone
47
- ["cascade_damage_threshold"] = 0.1, --if the calculated blast damage doesn't exeed this value, there will be no secondary explosion damage on the unit. If this value is too small, the appearance of explosions far outside of an expected radius looks incorrect.
48
- ["game_messages"] = true, --enable some messages on screen
49
- ["blast_stun"] = false, --not implemented
50
- ["unit_disabled_health"] = 30, --if health is below this value after our explosions, disable its movement
51
- ["unit_cant_fire_health"] = 40, --if health is below this value after our explosions, set ROE to HOLD to simulate damage weapon systems
52
- ["infantry_cant_fire_health"] = 90, --if health is below this value after our explosions, set ROE to HOLD to simulate severe injury
53
- ["debug"] = false, --enable debugging messages
54
- ["weapon_missing_message"] = false, --false disables messages alerting you to weapons missing from the explTable
55
- ["rocket_multiplier"] = 1.3, --multiplied by the explTable value for rockets
56
- }
57
-
58
- local script_enable = 1
59
- refreshRate = 0.1
60
-
61
- ----[[ ##### End of SCRIPT CONFIGURATION ##### ]]----
62
-
63
- explTable = {
64
- ["FAB_100"] = 45,
65
- ["FAB_250"] = 100,
66
- ["FAB_250M54TU"]= 100,
67
- ["FAB_500"] = 213,
68
- ["FAB_1500"] = 675,
69
- ["BetAB_500"] = 98,
70
- ["BetAB_500ShP"]= 107,
71
- ["KH-66_Grom"] = 108,
72
- ["M_117"] = 201,
73
- ["Mk_81"] = 60,
74
- ["Mk_82"] = 118,
75
- ["AN_M64"] = 121,
76
- ["Mk_83"] = 274,
77
- ["Mk_84"] = 582,
78
- ["MK_82AIR"] = 118,
79
- ["MK_82SNAKEYE"]= 118,
80
- ["GBU_10"] = 582,
81
- ["GBU_12"] = 118,
82
- ["GBU_16"] = 274,
83
- ["KAB_1500Kr"] = 675,
84
- ["KAB_500Kr"] = 213,
85
- ["KAB_500"] = 213,
86
- ["GBU_31"] = 582,
87
- ["GBU_31_V_3B"] = 582,
88
- ["GBU_31_V_2B"] = 582,
89
- ["GBU_31_V_4B"] = 582,
90
- ["GBU_32_V_2B"] = 202,
91
- ["GBU_38"] = 118,
92
- ["AGM_62"] = 400,
93
- ["GBU_24"] = 582,
94
- ["X_23"] = 111,
95
- ["X_23L"] = 111,
96
- ["X_28"] = 160,
97
- ["X_25ML"] = 89,
98
- ["X_25MP"] = 89,
99
- ["X_25MR"] = 140,
100
- ["X_58"] = 140,
101
- ["X_29L"] = 320,
102
- ["X_29T"] = 320,
103
- ["X_29TE"] = 320,
104
- ["AGM_84E"] = 488,
105
- ["AGM_88C"] = 89,
106
- ["AGM_122"] = 15,
107
- ["AGM_123"] = 274,
108
- ["AGM_130"] = 582,
109
- ["AGM_119"] = 176,
110
- ["AGM_154C"] = 305,
111
- ["S-24A"] = 24,
112
- --["S-24B"] = 123,
113
- ["S-25OF"] = 194,
114
- ["S-25OFM"] = 150,
115
- ["S-25O"] = 150,
116
- ["S_25L"] = 190,
117
- ["S-5M"] = 1,
118
- ["C_8"] = 4,
119
- ["C_8OFP2"] = 3,
120
- ["C_13"] = 21,
121
- ["C_24"] = 123,
122
- ["C_25"] = 151,
123
- ["HYDRA_70M15"] = 3,
124
- ["Zuni_127"] = 5,
125
- ["ARAKM70BHE"] = 4,
126
- ["BR_500"] = 118,
127
- ["Rb 05A"] = 217,
128
- ["HEBOMB"] = 40,
129
- ["HEBOMBD"] = 40,
130
- ["MK-81SE"] = 60,
131
- ["AN-M57"] = 56,
132
- ["AN-M64"] = 180,
133
- ["AN-M65"] = 295,
134
- ["AN-M66A2"] = 536,
135
- ["HYDRA_70_M151"] = 4,
136
- ["HYDRA_70_MK5"] = 4,
137
- ["Vikhr_M"] = 11,
138
- ["British_GP_250LB_Bomb_Mk1"] = 100, --("250 lb GP Mk.I")
139
- ["British_GP_250LB_Bomb_Mk4"] = 100, --("250 lb GP Mk.IV")
140
- ["British_GP_250LB_Bomb_Mk5"] = 100, --("250 lb GP Mk.V")
141
- ["British_GP_500LB_Bomb_Mk1"] = 213, --("500 lb GP Mk.I")
142
- ["British_GP_500LB_Bomb_Mk4"] = 213, --("500 lb GP Mk.IV")
143
- ["British_GP_500LB_Bomb_Mk4_Short"] = 213, --("500 lb GP Short tail")
144
- ["British_GP_500LB_Bomb_Mk5"] = 213, --("500 lb GP Mk.V")
145
- ["British_MC_250LB_Bomb_Mk1"] = 100, --("250 lb MC Mk.I")
146
- ["British_MC_250LB_Bomb_Mk2"] = 100, --("250 lb MC Mk.II")
147
- ["British_MC_500LB_Bomb_Mk1_Short"] = 213, --("500 lb MC Short tail")
148
- ["British_MC_500LB_Bomb_Mk2"] = 213, --("500 lb MC Mk.II")
149
- ["British_SAP_250LB_Bomb_Mk5"] = 100, --("250 lb S.A.P.")
150
- ["British_SAP_500LB_Bomb_Mk5"] = 213, --("500 lb S.A.P.")
151
- ["British_AP_25LBNo1_3INCHNo1"] = 4, --("RP-3 25lb AP Mk.I")
152
- ["British_HE_60LBSAPNo2_3INCHNo1"] = 4, --("RP-3 60lb SAP No2 Mk.I")
153
- ["British_HE_60LBFNo1_3INCHNo1"] = 4, --("RP-3 60lb F No1 Mk.I")
154
- ["WGr21"] = 4, --("Werfer-Granate 21 - 21 cm UnGd air-to-air rocket")
155
- ["3xM8_ROCKETS_IN_TUBES"] = 4, --("4.5 inch M8 UnGd Rocket")
156
- ["AN_M30A1"] = 45, --("AN-M30A1 - 100lb GP Bomb LD")
157
- ["AN_M57"] = 100, --("AN-M57 - 250lb GP Bomb LD")
158
- ["AN_M65"] = 400, --("AN-M65 - 1000lb GP Bomb LD")
159
- ["AN_M66"] = 800, --("AN-M66 - 2000lb GP Bomb LD")
160
- ["SC_50"] = 20, --("SC 50 - 50kg GP Bomb LD")
161
- ["ER_4_SC50"] = 20, --("4 x SC 50 - 50kg GP Bomb LD")
162
- ["SC_250_T1_L2"] = 100, --("SC 250 Type 1 L2 - 250kg GP Bomb LD")
163
- ["SC_501_SC250"] = 100, --("SC 250 Type 3 J - 250kg GP Bomb LD")
164
- ["Schloss500XIIC1_SC_250_T3_J"] = 100, --("SC 250 Type 3 J - 250kg GP Bomb LD")
165
- ["SC_501_SC500"] = 213, --("SC 500 J - 500kg GP Bomb LD")
166
- ["SC_500_L2"] = 213, --("SC 500 L2 - 500kg GP Bomb LD")
167
- ["SD_250_Stg"] = 100, --("SD 250 Stg - 250kg GP Bomb LD")
168
- ["SD_500_A"] = 213, --("SD 500 A - 500kg GP Bomb LD")
169
- ["AB_250_2_SD_2"] = 100, --("AB 250-2 - 144 x SD-2, 250kg CBU with HE submunitions")
170
- ["AB_250_2_SD_10A"] = 100, --("AB 250-2 - 17 x SD-10A, 250kg CBU with 10kg Frag/HE submunitions")
171
- ["AB_500_1_SD_10A"] = 213, --("AB 500-1 - 34 x SD-10A, 500kg CBU with 10kg Frag/HE submunitions")
172
- ["AGM_114K"] = 10,
173
- ["HYDRA_70_M229"] = 8,
174
- ["AGM_65D"] = 60,
175
- ["AGM_65E"] = 300,
176
- ["AGM_65F"] = 300,
177
- ["HOT3"] = 15,
178
- ["AGR_20A"] = 8,
179
- ["GBU_54_V_1B"] = 118,
180
-
181
- }
182
-
183
-
184
- ----[[ ##### HELPER/UTILITY FUNCTIONS ##### ]]----
185
-
186
- local function tableHasKey(table,key)
187
- return table[key] ~= nil
188
- end
189
-
190
- local function debugMsg(str)
191
- if splash_damage_options.debug == true then
192
- trigger.action.outText(str , 5)
193
- end
194
- end
195
-
196
- local function gameMsg(str)
197
- if splash_damage_options.game_messages == true then
198
- trigger.action.outText(str , 5)
199
- end
200
- end
201
-
202
- local function getDistance(point1, point2)
203
- local x1 = point1.x
204
- local y1 = point1.y
205
- local z1 = point1.z
206
- local x2 = point2.x
207
- local y2 = point2.y
208
- local z2 = point2.z
209
- local dX = math.abs(x1-x2)
210
- local dZ = math.abs(z1-z2)
211
- local distance = math.sqrt(dX*dX + dZ*dZ)
212
- return distance
213
- end
214
-
215
- local function getDistance3D(point1, point2)
216
- local x1 = point1.x
217
- local y1 = point1.y
218
- local z1 = point1.z
219
- local x2 = point2.x
220
- local y2 = point2.y
221
- local z2 = point2.z
222
- local dX = math.abs(x1-x2)
223
- local dY = math.abs(y1-y2)
224
- local dZ = math.abs(z1-z2)
225
- local distance = math.sqrt(dX*dX + dZ*dZ + dY*dY)
226
- return distance
227
- end
228
-
229
- local function vec3Mag(speedVec)
230
- local mag = speedVec.x*speedVec.x + speedVec.y*speedVec.y+speedVec.z*speedVec.z
231
- mag = math.sqrt(mag)
232
- --trigger.action.outText("X = " .. speedVec.x ..", y = " .. speedVec.y .. ", z = "..speedVec.z, 10)
233
- --trigger.action.outText("Speed = " .. mag, 1)
234
- return mag
235
- end
236
-
237
- local function lookahead(speedVec)
238
- local speed = vec3Mag(speedVec)
239
- local dist = speed * refreshRate * 1.5
240
- return dist
241
- end
242
-
243
- ----[[ ##### End of HELPER/UTILITY FUNCTIONS ##### ]]----
244
-
245
-
246
- WpnHandler = {}
247
- tracked_weapons = {}
248
-
249
- function track_wpns()
250
- -- env.info("Weapon Track Start")
251
- for wpn_id_, wpnData in pairs(tracked_weapons) do
252
- if wpnData.wpn:isExist() then -- just update speed, position and direction.
253
- wpnData.pos = wpnData.wpn:getPosition().p
254
- wpnData.dir = wpnData.wpn:getPosition().x
255
- wpnData.speed = wpnData.wpn:getVelocity()
256
- --wpnData.lastIP = land.getIP(wpnData.pos, wpnData.dir, 50)
257
- else -- wpn no longer exists, must be dead.
258
- -- trigger.action.outText("Weapon impacted, mass of weapon warhead is " .. wpnData.exMass, 2)
259
- local ip = land.getIP(wpnData.pos, wpnData.dir, lookahead(wpnData.speed)) -- terrain intersection point with weapon's nose. Only search out 20 meters though.
260
- local impactPoint
261
- if not ip then -- use last calculated IP
262
- impactPoint = wpnData.pos
263
- -- trigger.action.outText("Impact Point:\nPos X: " .. impactPoint.x .. "\nPos Z: " .. impactPoint.z, 2)
264
- else -- use intersection point
265
- impactPoint = ip
266
- -- trigger.action.outText("Impact Point:\nPos X: " .. impactPoint.x .. "\nPos Z: " .. impactPoint.z, 2)
267
- end
268
- --env.info("Weapon is gone") -- Got to here --
269
- --trigger.action.outText("Weapon Type was: ".. wpnData.name, 20)
270
- if splash_damage_options.larger_explosions == true then
271
- --env.info("triggered explosion size: "..getWeaponExplosive(wpnData.name))
272
- trigger.action.explosion(impactPoint, getWeaponExplosive(wpnData.name))
273
- --trigger.action.smoke(impactPoint, 0)
274
- end
275
- local explosive = getWeaponExplosive(wpnData.name)
276
- if splash_damage_options.rocket_multiplier > 0 and wpnData.cat == Weapon.Category.ROCKET then
277
- explosive = explosive * splash_damage_options.rocket_multiplier
278
- end
279
- blastWave(impactPoint, splash_damage_options.blast_search_radius, wpnData.ordnance, explosive)
280
- tracked_weapons[wpn_id_] = nil -- remove from tracked weapons first.
281
- end
282
- end
283
- -- env.info("Weapon Track End")
284
- end
285
-
286
- function onWpnEvent(event)
287
- if event.id == world.event.S_EVENT_SHOT then
288
- if event.weapon then
289
- local ordnance = event.weapon
290
- local weapon_desc = ordnance:getDesc()
291
- if string.find(ordnance:getTypeName(), "weapons.shells") then
292
- debugMsg("event shot, but not tracking: "..ordnance:getTypeName())
293
- return --we wont track these types of weapons, so exit here
294
- end
295
-
296
- if explTable[ordnance:getTypeName()] then
297
- --trigger.action.outText(ordnance:getTypeName().." found.", 10)
298
- else
299
- env.info(ordnance:getTypeName().." missing from Splash Damage script")
300
- if splash_damage_options.weapon_missing_message == true then
301
- trigger.action.outText(ordnance:getTypeName().." missing from Splash Damage script", 10)
302
- debugMsg("desc: "..mist.utils.tableShow(weapon_desc))
303
- end
304
- end
305
- if (weapon_desc.category ~= 0) and event.initiator then
306
- if (weapon_desc.category == 1) then
307
- if (weapon_desc.MissileCategory ~= 1 and weapon_desc.MissileCategory ~= 2) then
308
- tracked_weapons[event.weapon.id_] = { wpn = ordnance, init = event.initiator:getName(), pos = ordnance:getPoint(), dir = ordnance:getPosition().x, name = ordnance:getTypeName(), speed = ordnance:getVelocity(), cat = ordnance:getCategory() }
309
- end
310
- else
311
- tracked_weapons[event.weapon.id_] = { wpn = ordnance, init = event.initiator:getName(), pos = ordnance:getPoint(), dir = ordnance:getPosition().x, name = ordnance:getTypeName(), speed = ordnance:getVelocity(), cat = ordnance:getCategory() }
312
- end
313
- end
314
- end
315
- end
316
-
317
- end
318
-
319
- local function protectedCall(...)
320
- local status, retval = pcall(...)
321
- if not status then
322
- env.warning("Splash damage script error... gracefully caught! " .. retval, true)
323
- end
324
- end
325
-
326
-
327
- function WpnHandler:onEvent(event)
328
- protectedCall(onWpnEvent, event)
329
- end
330
-
331
-
332
-
333
- function explodeObject(table)
334
- local point = table[1]
335
- local distance = table[2]
336
- local power = table[3]
337
- trigger.action.explosion(point, power)
338
- end
339
-
340
- function getWeaponExplosive(name)
341
- if explTable[name] then
342
- return explTable[name]
343
- else
344
- return 0
345
- end
346
- end
347
-
348
- --controller is only at group level for ground units. we should itterate over the group and only apply effects if health thresholds are met by all units in the group
349
- function modelUnitDamage(units)
350
- --debugMsg("units table: "..mist.utils.tableShow(units))
351
- for i, unit in ipairs(units)
352
- do
353
- --debugMsg("unit table: "..mist.utils.tableShow(unit))
354
- if unit:isExist() then --if units are not already dead
355
- local health = (unit:getLife() / unit:getDesc().life) * 100
356
- --debugMsg(unit:getTypeName().." health %"..health)
357
- if unit:hasAttribute("Infantry") == true and health > 0 then --if infantry
358
- if health <= splash_damage_options.infantry_cant_fire_health then
359
- ---disable unit's ability to fire---
360
- unit:getController():setOption(AI.Option.Ground.id.ROE , AI.Option.Ground.val.ROE.WEAPON_HOLD)
361
- end
362
- end
363
- if unit:getDesc().category == Unit.Category.GROUND_UNIT == true and unit:hasAttribute("Infantry") == false and health > 0 then --if ground unit but not infantry
364
- if health <= splash_damage_options.unit_cant_fire_health then
365
- ---disable unit's ability to fire---
366
- unit:getController():setOption(AI.Option.Ground.id.ROE , AI.Option.Ground.val.ROE.WEAPON_HOLD)
367
- gameMsg(unit:getTypeName().." weapons disabled")
368
- end
369
- if health <= splash_damage_options.unit_disabled_health and health > 0 then
370
- ---disable unit's ability to move---
371
- unit:getController():setTask({id = 'Hold', params = { }} )
372
- unit:getController():setOnOff(false)
373
- gameMsg(unit:getTypeName().." disabled")
374
- end
375
- end
376
-
377
- else
378
- --debugMsg("unit no longer exists")
379
- end
380
- end
381
- end
382
-
383
-
384
- function blastWave(_point, _radius, weapon, power)
385
- local foundUnits = {}
386
- local volS = {
387
- id = world.VolumeType.SPHERE,
388
- params = {
389
- point = _point,
390
- radius = _radius
391
- }
392
- }
393
-
394
- local ifFound = function(foundObject, val)
395
- if foundObject:getDesc().category == Unit.Category.GROUND_UNIT and foundObject:getCategory() == Object.Category.UNIT then
396
- foundUnits[#foundUnits + 1] = foundObject
397
- end
398
- if foundObject:getDesc().category == Unit.Category.GROUND_UNIT then --if ground unit
399
- if splash_damage_options.blast_stun == true then
400
- --suppressUnit(foundObject, 2, weapon)
401
- end
402
- end
403
- if splash_damage_options.wave_explosions == true then
404
- local obj = foundObject
405
- local obj_location = obj:getPoint()
406
- local distance = getDistance(_point, obj_location)
407
- local timing = distance/500
408
- if obj:isExist() then
409
-
410
- if tableHasKey(obj:getDesc(), "box") then
411
- local length = (obj:getDesc().box.max.x + math.abs(obj:getDesc().box.min.x))
412
- local height = (obj:getDesc().box.max.y + math.abs(obj:getDesc().box.min.y))
413
- local depth = (obj:getDesc().box.max.z + math.abs(obj:getDesc().box.min.z))
414
- local _length = length
415
- local _depth = depth
416
- if depth > length then
417
- _length = depth
418
- _depth = length
419
- end
420
- local surface_distance = distance - _depth/2
421
- local scaled_power_factor = 0.006 * power + 1 --this could be reduced into the calc on the next line
422
- local intensity = (power * scaled_power_factor) / (4 * 3.14 * surface_distance * surface_distance )
423
- local surface_area = _length * height --Ideally we should roughly calculate the surface area facing the blast point, but we'll just find the largest side of the object for now
424
- local damage_for_surface = intensity * surface_area
425
- --debugMsg(obj:getTypeName().." sa:"..surface_area.." distance:"..surface_distance.." dfs:"..damage_for_surface)
426
- if damage_for_surface > splash_damage_options.cascade_damage_threshold then
427
- local explosion_size = damage_for_surface
428
- if obj:getDesc().category == Unit.Category.STRUCTURE then
429
- explosion_size = intensity * splash_damage_options.static_damage_boost --apply an extra damage boost for static objects. should we factor in surface_area?
430
- --debugMsg("static obj :"..obj:getTypeName())
431
- end
432
- if explosion_size > power then explosion_size = power end --secondary explosions should not be larger than the explosion that created it
433
- local id = timer.scheduleFunction(explodeObject, {obj_location, distance, explosion_size}, timer.getTime() + timing) --create the explosion on the object location
434
- end
435
-
436
-
437
- else --debugMsg(obj:getTypeName().." object does not have box property")
438
- end
439
-
440
- end
441
-
442
- end
443
-
444
- return true
445
- end
446
-
447
- world.searchObjects(Object.Category.UNIT, volS, ifFound)
448
- world.searchObjects(Object.Category.STATIC, volS, ifFound)
449
- world.searchObjects(Object.Category.SCENERY, volS, ifFound)
450
- world.searchObjects(Object.Category.CARGO, volS, ifFound)
451
- --world.searchObjects(Object.Category.BASE, volS, ifFound)
452
-
453
- if splash_damage_options.damage_model == true then
454
- local id = timer.scheduleFunction(modelUnitDamage, foundUnits, timer.getTime() + 1.5) --allow some time for the game to adjust health levels before running our function
455
- end
456
- end
457
-
458
-
459
-
460
- if (script_enable == 1) then
461
- gameMsg("SPLASH DAMAGE 2 SCRIPT RUNNING")
462
- env.info("SPLASH DAMAGE 2 SCRIPT RUNNING")
463
- timer.scheduleFunction(function()
464
- protectedCall(track_wpns)
465
- return timer.getTime() + refreshRate
466
- end,
467
- {},
468
- timer.getTime() + refreshRate
469
- )
470
- world.addEventHandler(WpnHandler)
471
- end
472
-