@jtff/miztemplate-lib 3.1.10 → 3.2.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.
@@ -1,4 +1,36 @@
1
- env.info('*** MOOSE GITHUB Commit Hash ID: 2024-01-01T00:38:59+01:00-8dcd22f18c9bf740c53b69c7ba3901a9ada0bb2d ***')
1
+ env.info('*** MOOSE GITHUB Commit Hash ID: 2024-02-03T12:48:41+01:00-86e13df3039b95b46af4786cb3196cb931175778 ***')
2
+ if not MOOSE_DEVELOPMENT_FOLDER then
3
+ MOOSE_DEVELOPMENT_FOLDER='Scripts'
4
+ end
5
+ ModuleLoader=MOOSE_DEVELOPMENT_FOLDER..'/Moose/Modules.lua'
6
+ if io then
7
+ local f=io.open(ModuleLoader,"r")
8
+ if f~=nil then
9
+ io.close(f)
10
+ env.info('*** MOOSE DYNAMIC INCLUDE START *** ')
11
+ local base=_G
12
+ __Moose={}
13
+ __Moose.Include=function(IncludeFile)
14
+ if not __Moose.Includes[IncludeFile]then
15
+ __Moose.Includes[IncludeFile]=IncludeFile
16
+ local f=assert(base.loadfile(IncludeFile))
17
+ if f==nil then
18
+ error("Moose: Could not load Moose file "..IncludeFile)
19
+ else
20
+ env.info("Moose: "..IncludeFile.." dynamically loaded.")
21
+ return f()
22
+ end
23
+ end
24
+ end
25
+ __Moose.Includes={}
26
+ __Moose.Include(MOOSE_DEVELOPMENT_FOLDER..'/Moose/Modules.lua')
27
+ BASE:TraceOnOff(true)
28
+ env.info('*** MOOSE INCLUDE END *** ')
29
+ do return end
30
+ end
31
+ else
32
+ env.info('*** MOOSE DYNAMIC INCLUDE NOT POSSIBLE (Desanitize io to use it) *** ')
33
+ end
2
34
  env.info('*** MOOSE STATIC INCLUDE START *** ')
3
35
  ENUMS={}
4
36
  env.setErrorMessageBoxEnabled(false)
@@ -1542,6 +1574,43 @@ return string.format('%03d°',latDeg)..' '..string.format(minFrmtStr,latMin)..'\
1542
1574
  ..string.format('%03d°',lonDeg)..' '..string.format(minFrmtStr,lonMin)..'\''..lonHemi
1543
1575
  end
1544
1576
  end
1577
+ UTILS.tostringLLM2KData=function(lat,lon,acc)
1578
+ local latHemi,lonHemi
1579
+ if lat>0 then
1580
+ latHemi='N'
1581
+ else
1582
+ latHemi='S'
1583
+ end
1584
+ if lon>0 then
1585
+ lonHemi='E'
1586
+ else
1587
+ lonHemi='W'
1588
+ end
1589
+ lat=math.abs(lat)
1590
+ lon=math.abs(lon)
1591
+ local latDeg=math.floor(lat)
1592
+ local latMin=(lat-latDeg)*60
1593
+ local lonDeg=math.floor(lon)
1594
+ local lonMin=(lon-lonDeg)*60
1595
+ latMin=UTILS.Round(latMin,acc)
1596
+ lonMin=UTILS.Round(lonMin,acc)
1597
+ if latMin==60 then
1598
+ latMin=0
1599
+ latDeg=latDeg+1
1600
+ end
1601
+ if lonMin==60 then
1602
+ lonMin=0
1603
+ lonDeg=lonDeg+1
1604
+ end
1605
+ local minFrmtStr
1606
+ if acc<=0 then
1607
+ minFrmtStr='%02d'
1608
+ else
1609
+ local width=3+acc
1610
+ minFrmtStr='%0'..width..'.'..acc..'f'
1611
+ end
1612
+ return latHemi..string.format('%02d:',latDeg)..string.format(minFrmtStr,latMin),lonHemi..string.format('%02d:',lonDeg)..string.format(minFrmtStr,lonMin)
1613
+ end
1545
1614
  UTILS.tostringMGRS=function(MGRS,acc)
1546
1615
  if acc<=0 then
1547
1616
  return MGRS.UTMZone..' '..MGRS.MGRSDigraph
@@ -2410,15 +2479,27 @@ _start=_start+50000
2410
2479
  end
2411
2480
  return FreeVHFFrequencies
2412
2481
  end
2413
- function UTILS.GenerateUHFrequencies()
2482
+ function UTILS.GenerateUHFrequencies(Start,End)
2414
2483
  local FreeUHFFrequencies={}
2415
2484
  local _start=220000000
2485
+ if not Start then
2416
2486
  while _start<399000000 do
2417
2487
  if _start~=243000000 then
2418
2488
  table.insert(FreeUHFFrequencies,_start)
2419
2489
  end
2420
2490
  _start=_start+500000
2421
2491
  end
2492
+ else
2493
+ local myend=End*1000000 or 399000000
2494
+ local mystart=Start*1000000 or 220000000
2495
+ while _start<399000000 do
2496
+ if _start~=243000000 and(_start<mystart or _start>myend)then
2497
+ print(_start)
2498
+ table.insert(FreeUHFFrequencies,_start)
2499
+ end
2500
+ _start=_start+500000
2501
+ end
2502
+ end
2422
2503
  return FreeUHFFrequencies
2423
2504
  end
2424
2505
  function UTILS.GenerateLaserCodes()
@@ -11004,7 +11085,12 @@ local DCSAirbaseName=airbase:getName()
11004
11085
  local airbaseID=airbase:getID()
11005
11086
  local airbase=self:AddAirbase(DCSAirbaseName)
11006
11087
  local airbaseUID=airbase:GetID(true)
11007
- local text=string.format("Register %s: %s (UID=%d), Runways=%d, Parking=%d [",AIRBASE.CategoryName[airbase.category],tostring(DCSAirbaseName),airbaseUID,#airbase.runways,airbase.NparkingTotal)
11088
+ local typename=airbase:GetTypeName()
11089
+ local category=airbase.category
11090
+ if category==Airbase.Category.SHIP and typename=="FARP_SINGLE_01"then
11091
+ category=Airbase.Category.HELIPAD
11092
+ end
11093
+ local text=string.format("Register %s: %s (UID=%d), Runways=%d, Parking=%d [",AIRBASE.CategoryName[category],tostring(DCSAirbaseName),airbaseUID,#airbase.runways,airbase.NparkingTotal)
11008
11094
  for _,terminalType in pairs(AIRBASE.TerminalType)do
11009
11095
  if airbase.NparkingTerminal and airbase.NparkingTerminal[terminalType]then
11010
11096
  text=text..string.format("%d=%d ",terminalType,airbase.NparkingTerminal[terminalType])
@@ -11580,6 +11666,17 @@ local RandomItem=self.Set[self.Index[math.random(1,tablemax)]]
11580
11666
  self:T3({RandomItem})
11581
11667
  return RandomItem
11582
11668
  end
11669
+ function SET_BASE:GetRandomSurely()
11670
+ local tablemax=0
11671
+ local sorted={}
11672
+ for _,_obj in pairs(self.Set)do
11673
+ tablemax=tablemax+1
11674
+ sorted[tablemax]=_obj
11675
+ end
11676
+ local RandomItem=sorted[math.random(1,tablemax)]
11677
+ self:T3({RandomItem})
11678
+ return RandomItem
11679
+ end
11583
11680
  function SET_BASE:Count()
11584
11681
  return self.Index and table.maxn(self.Index)or 0
11585
11682
  end
@@ -11859,7 +11956,7 @@ end
11859
11956
  function SET_GROUP:AddGroup(group,DontSetCargoBayLimit)
11860
11957
  self:Add(group:GetName(),group)
11861
11958
  if not DontSetCargoBayLimit then
11862
- for UnitID,UnitData in pairs(group:GetUnits())do
11959
+ for UnitID,UnitData in pairs(group:GetUnits()or{})do
11863
11960
  if UnitData and UnitData:IsAlive()then
11864
11961
  UnitData:SetCargoBayWeightLimit()
11865
11962
  end
@@ -12053,7 +12150,7 @@ end
12053
12150
  end
12054
12151
  function SET_GROUP:AddInDatabase(Event)
12055
12152
  self:F3({Event})
12056
- if Event.IniObjectCategory==1 then
12153
+ if Event.IniObjectCategory==Object.Category.UNIT then
12057
12154
  if not self.Database[Event.IniDCSGroupName]then
12058
12155
  self.Database[Event.IniDCSGroupName]=GROUP:Register(Event.IniDCSGroupName)
12059
12156
  self:T3(self.Database[Event.IniDCSGroupName])
@@ -12551,7 +12648,7 @@ return self
12551
12648
  end
12552
12649
  function SET_UNIT:AddInDatabase(Event)
12553
12650
  self:F3({Event})
12554
- if Event.IniObjectCategory==1 then
12651
+ if Event.IniObjectCategory==Object.Category.UNIT then
12555
12652
  if not self.Database[Event.IniDCSUnitName]then
12556
12653
  self.Database[Event.IniDCSUnitName]=UNIT:Register(Event.IniDCSUnitName)
12557
12654
  self:T3(self.Database[Event.IniDCSUnitName])
@@ -13629,7 +13726,7 @@ end
13629
13726
  function SET_CLIENT:_EventPlayerEnterUnit(Event)
13630
13727
  self:I("_EventPlayerEnterUnit")
13631
13728
  if Event.IniDCSUnit then
13632
- if Event.IniObjectCategory==1 and Event.IniGroup and Event.IniGroup:IsGround()then
13729
+ if Event.IniObjectCategory==Object.Category.UNIT and Event.IniGroup and Event.IniGroup:IsGround()then
13633
13730
  local ObjectName,Object=self:AddInDatabase(Event)
13634
13731
  self:I(ObjectName,UTILS.PrintTableToLog(Object))
13635
13732
  if Object and self:IsIncludeObject(Object)then
@@ -13642,7 +13739,7 @@ end
13642
13739
  function SET_CLIENT:_EventPlayerLeaveUnit(Event)
13643
13740
  self:I("_EventPlayerLeaveUnit")
13644
13741
  if Event.IniDCSUnit then
13645
- if Event.IniObjectCategory==1 and Event.IniGroup and Event.IniGroup:IsGround()then
13742
+ if Event.IniObjectCategory==Object.Category.UNIT and Event.IniGroup and Event.IniGroup:IsGround()then
13646
13743
  local ObjectName,Object=self:FindInDatabase(Event)
13647
13744
  if ObjectName then
13648
13745
  self:Remove(ObjectName)
@@ -15271,6 +15368,20 @@ end
15271
15368
  end
15272
15369
  return self
15273
15370
  end
15371
+ function SET_OPSGROUP:_EventOnBirth(Event)
15372
+ self:F3({Event})
15373
+ if Event.IniDCSUnit and Event.IniDCSGroup then
15374
+ local DCSgroup=Event.IniDCSGroup
15375
+ if DCSgroup:getInitialSize()==DCSgroup:getSize()then
15376
+ local groupname,group=self:AddInDatabase(Event)
15377
+ if group and group:CountAliveUnits()==DCSgroup:getInitialSize()then
15378
+ if group and self:IsIncludeObject(group)then
15379
+ self:Add(groupname,group)
15380
+ end
15381
+ end
15382
+ end
15383
+ end
15384
+ end
15274
15385
  function SET_OPSGROUP:_EventOnDeadOrCrash(Event)
15275
15386
  self:F({Event})
15276
15387
  if Event.IniDCSUnit then
@@ -15283,7 +15394,7 @@ end
15283
15394
  end
15284
15395
  end
15285
15396
  function SET_OPSGROUP:AddInDatabase(Event)
15286
- if Event.IniObjectCategory==1 then
15397
+ if Event.IniObjectCategory==Object.Category.UNIT then
15287
15398
  if not self.Database[Event.IniDCSGroupName]then
15288
15399
  self.Database[Event.IniDCSGroupName]=GROUP:Register(Event.IniDCSGroupName)
15289
15400
  end
@@ -15473,7 +15584,11 @@ self:ForEach(IteratorFunction,arg,self:GetSet())
15473
15584
  return self
15474
15585
  end
15475
15586
  function SET_SCENERY:GetCoordinate()
15476
- local Coordinate=self:GetRandom():GetCoordinate()
15587
+ local Coordinate=COORDINATE:New({0,0,0})
15588
+ local Item=self:GetRandomSurely()
15589
+ if Item then
15590
+ Coordinate:GetCoordinate()
15591
+ end
15477
15592
  local x1=Coordinate.x
15478
15593
  local x2=Coordinate.x
15479
15594
  local y1=Coordinate.y
@@ -17000,6 +17115,11 @@ end
17000
17115
  function COORDINATE:GetLLDDM()
17001
17116
  return coord.LOtoLL(self:GetVec3())
17002
17117
  end
17118
+ function COORDINATE:ToStringLL(Settings)
17119
+ local LL_Accuracy=Settings and Settings.LL_Accuracy or _SETTINGS.LL_Accuracy
17120
+ local lat,lon=coord.LOtoLL(self:GetVec3())
17121
+ return string.format('%f',lat)..' '..string.format('%f',lon)
17122
+ end
17003
17123
  function COORDINATE:ToStringLLDMS(Settings)
17004
17124
  local LL_Accuracy=Settings and Settings.LL_Accuracy or _SETTINGS.LL_Accuracy
17005
17125
  local lat,lon=coord.LOtoLL(self:GetVec3())
@@ -17621,27 +17741,33 @@ return self
17621
17741
  end
17622
17742
  _MESSAGESRS={}
17623
17743
  function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,Gender,Culture,Voice,Coalition,Volume,Label,Coordinate)
17624
- _MESSAGESRS.MSRS=MSRS:New(PathToSRS,Frequency or 243,Modulation or radio.modulation.AM,Volume)
17625
- _MESSAGESRS.frequency=Frequency
17626
- _MESSAGESRS.modulation=Modulation or radio.modulation.AM
17627
- _MESSAGESRS.MSRS:SetCoalition(Coalition or coalition.side.NEUTRAL)
17628
- _MESSAGESRS.coalition=Coalition or coalition.side.NEUTRAL
17744
+ _MESSAGESRS.PathToSRS=PathToSRS or MSRS.path or"C:\\Program Files\\DCS-SimpleRadio-Standalone"
17745
+ _MESSAGESRS.frequency=Frequency or MSRS.frequencies or 243
17746
+ _MESSAGESRS.modulation=Modulation or MSRS.modulations or radio.modulation.AM
17747
+ _MESSAGESRS.MSRS=MSRS:New(_MESSAGESRS.PathToSRS,_MESSAGESRS.frequency,_MESSAGESRS.modulation)
17748
+ _MESSAGESRS.coalition=Coalition or MSRS.coalition or coalition.side.NEUTRAL
17749
+ _MESSAGESRS.MSRS:SetCoalition(_MESSAGESRS.coalition)
17629
17750
  _MESSAGESRS.coordinate=Coordinate
17751
+ if Coordinate then
17630
17752
  _MESSAGESRS.MSRS:SetCoordinate(Coordinate)
17753
+ end
17754
+ _MESSAGESRS.Culture=Culture or MSRS.culture or"en-GB"
17631
17755
  _MESSAGESRS.MSRS:SetCulture(Culture)
17632
- _MESSAGESRS.Culture=Culture or"en-GB"
17756
+ _MESSAGESRS.Gender=Gender or MSRS.gender or"female"
17633
17757
  _MESSAGESRS.MSRS:SetGender(Gender)
17634
- _MESSAGESRS.Gender=Gender or"female"
17635
- _MESSAGESRS.MSRS:SetGoogle(PathToCredentials)
17758
+ if PathToCredentials then
17759
+ _MESSAGESRS.MSRS:SetProviderOptionsGoogle(PathToCredentials)
17760
+ _MESSAGESRS.MSRS:SetProvider(MSRS.Provider.GOOGLE)
17761
+ end
17762
+ _MESSAGESRS.label=Label or MSRS.Label or"MESSAGE"
17636
17763
  _MESSAGESRS.MSRS:SetLabel(Label or"MESSAGE")
17637
- _MESSAGESRS.label=Label or"MESSAGE"
17764
+ _MESSAGESRS.port=Port or MSRS.port or 5002
17638
17765
  _MESSAGESRS.MSRS:SetPort(Port or 5002)
17639
- _MESSAGESRS.port=Port or 5002
17640
- _MESSAGESRS.volume=Volume or 1
17766
+ _MESSAGESRS.volume=Volume or MSRS.volume or 1
17641
17767
  _MESSAGESRS.MSRS:SetVolume(_MESSAGESRS.volume)
17642
17768
  if Voice then _MESSAGESRS.MSRS:SetVoice(Voice)end
17643
- _MESSAGESRS.voice=Voice
17644
- _MESSAGESRS.SRSQ=MSRSQUEUE:New(Label or"MESSAGE")
17769
+ _MESSAGESRS.voice=Voice or MSRS.voice
17770
+ _MESSAGESRS.SRSQ=MSRSQUEUE:New(_MESSAGESRS.label)
17645
17771
  end
17646
17772
  function MESSAGE:ToSRS(frequency,modulation,gender,culture,voice,coalition,volume,coordinate)
17647
17773
  local tgender=gender or _MESSAGESRS.Gender
@@ -17653,7 +17779,7 @@ if coordinate then
17653
17779
  _MESSAGESRS.MSRS:SetCoordinate(coordinate)
17654
17780
  end
17655
17781
  local category=string.gsub(self.MessageCategory,":","")
17656
- _MESSAGESRS.SRSQ:NewTransmission(self.MessageText,nil,_MESSAGESRS.MSRS,nil,nil,nil,nil,nil,frequency or _MESSAGESRS.frequency,modulation or _MESSAGESRS.modulation,gender or _MESSAGESRS.Gender,culture or _MESSAGESRS.Culture,nil,volume or _MESSAGESRS.volume,category,coordinate or _MESSAGESRS.coordinate)
17782
+ _MESSAGESRS.SRSQ:NewTransmission(self.MessageText,nil,_MESSAGESRS.MSRS,0.5,1,nil,nil,nil,frequency or _MESSAGESRS.frequency,modulation or _MESSAGESRS.modulation,gender or _MESSAGESRS.Gender,culture or _MESSAGESRS.Culture,nil,volume or _MESSAGESRS.volume,category,coordinate or _MESSAGESRS.coordinate)
17657
17783
  end
17658
17784
  return self
17659
17785
  end
@@ -18680,6 +18806,7 @@ if self.SpawnGroups[self.SpawnIndex].Visible then
18680
18806
  self.SpawnGroups[self.SpawnIndex].Group:Activate()
18681
18807
  else
18682
18808
  local SpawnTemplate=self.SpawnGroups[self.SpawnIndex].SpawnTemplate
18809
+ local SpawnZone=self.SpawnGroups[self.SpawnIndex].SpawnZone
18683
18810
  self:T(SpawnTemplate.name)
18684
18811
  if SpawnTemplate then
18685
18812
  local PointVec3=POINT_VEC3:New(SpawnTemplate.route.points[1].x,SpawnTemplate.route.points[1].alt,SpawnTemplate.route.points[1].y)
@@ -18699,6 +18826,23 @@ end
18699
18826
  if self.SpawnRandomizeUnits then
18700
18827
  for UnitID=1,#SpawnTemplate.units do
18701
18828
  local RandomVec2=PointVec3:GetRandomVec2InRadius(self.SpawnOuterRadius,self.SpawnInnerRadius)
18829
+ if(SpawnZone)then
18830
+ local inZone=SpawnZone:IsVec2InZone(RandomVec2)
18831
+ local numTries=1
18832
+ while(not inZone)and(numTries<20)do
18833
+ if not inZone then
18834
+ RandomVec2=PointVec3:GetRandomVec2InRadius(self.SpawnOuterRadius,self.SpawnInnerRadius)
18835
+ numTries=numTries+1
18836
+ inZone=SpawnZone:IsVec2InZone(RandomVec2)
18837
+ self:I("Retrying "..numTries.."spawn "..SpawnTemplate.name.." in Zone "..SpawnZone:GetName().."!")
18838
+ self:I(SpawnZone)
18839
+ end
18840
+ end
18841
+ if(not inZone)then
18842
+ self:I("Could not place unit within zone and within radius!")
18843
+ RandomVec2=SpawnZone:GetRandomVec2()
18844
+ end
18845
+ end
18702
18846
  SpawnTemplate.units[UnitID].x=RandomVec2.x
18703
18847
  SpawnTemplate.units[UnitID].y=RandomVec2.y
18704
18848
  self:T('SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
@@ -18736,12 +18880,14 @@ local cosHeading=math.cos(headingRad)
18736
18880
  local sinHeading=math.sin(headingRad)
18737
18881
  local unitVarRad=math.rad(self.SpawnInitGroupUnitVar or 0)
18738
18882
  for UnitID=1,#SpawnTemplate.units do
18883
+ if not self.SpawnRandomizeUnits then
18739
18884
  if UnitID>1 then
18740
18885
  local unitXOff=SpawnTemplate.units[UnitID].x-pivotX
18741
18886
  local unitYOff=SpawnTemplate.units[UnitID].y-pivotY
18742
18887
  SpawnTemplate.units[UnitID].x=pivotX+(unitXOff*cosHeading)-(unitYOff*sinHeading)
18743
18888
  SpawnTemplate.units[UnitID].y=pivotY+(unitYOff*cosHeading)+(unitXOff*sinHeading)
18744
18889
  end
18890
+ end
18745
18891
  local unitHeading=SpawnTemplate.units[UnitID].heading+headingRad
18746
18892
  SpawnTemplate.units[UnitID].heading=_HeadingRad(_RandomInRange(unitHeading-unitVarRad,unitHeading+unitVarRad))
18747
18893
  SpawnTemplate.units[UnitID].psi=-SpawnTemplate.units[UnitID].heading
@@ -18831,7 +18977,7 @@ SpawnGroup:SetAIOnOff(self.AIOnOff)
18831
18977
  end
18832
18978
  self:T3(SpawnTemplate.name)
18833
18979
  if self.SpawnFunctionHook then
18834
- self.SpawnHookScheduler:Schedule(nil,self.SpawnFunctionHook,{self.SpawnGroups[self.SpawnIndex].Group,unpack(self.SpawnFunctionArguments)},0.1)
18980
+ self.SpawnHookScheduler:Schedule(nil,self.SpawnFunctionHook,{self.SpawnGroups[self.SpawnIndex].Group,unpack(self.SpawnFunctionArguments)},0.3)
18835
18981
  end
18836
18982
  end
18837
18983
  self.SpawnGroups[self.SpawnIndex].Spawned=true
@@ -19866,6 +20012,7 @@ self:T("Preparing Spawn in Zone",SpawnZone:GetName())
19866
20012
  local SpawnVec2=SpawnZone:GetRandomVec2()
19867
20013
  self:T({SpawnVec2=SpawnVec2})
19868
20014
  local SpawnTemplate=self.SpawnGroups[SpawnIndex].SpawnTemplate
20015
+ self.SpawnGroups[SpawnIndex].SpawnZone=SpawnZone
19869
20016
  self:T({Route=SpawnTemplate.route})
19870
20017
  for UnitID=1,#SpawnTemplate.units do
19871
20018
  local UnitTemplate=SpawnTemplate.units[UnitID]
@@ -20713,7 +20860,7 @@ ClassName="PATHLINE",
20713
20860
  lid=nil,
20714
20861
  points={},
20715
20862
  }
20716
- PATHLINE.version="0.1.0"
20863
+ PATHLINE.version="0.1.1"
20717
20864
  function PATHLINE:New(Name)
20718
20865
  local self=BASE:Inherit(self,BASE:New())
20719
20866
  self.name=Name or"Unknown Path"
@@ -20778,11 +20925,12 @@ table.insert(vecs,point.vec2)
20778
20925
  end
20779
20926
  return vecs
20780
20927
  end
20781
- function PATHLINE:GetCoordinats()
20928
+ function PATHLINE:GetCoordinates()
20782
20929
  local vecs={}
20783
20930
  for _,_point in pairs(self.points)do
20784
20931
  local point=_point
20785
20932
  local coord=COORDINATE:NewFromVec3(point.vec3)
20933
+ table.insert(vecs,coord)
20786
20934
  end
20787
20935
  return vecs
20788
20936
  end
@@ -20791,7 +20939,7 @@ local N=self:GetNumberOfPoints()
20791
20939
  n=n or 1
20792
20940
  local point=nil
20793
20941
  if n>=1 and n<=N then
20794
- point=self.point[n]
20942
+ point=self.points[n]
20795
20943
  else
20796
20944
  self:E(self.lid..string.format("ERROR: No point in pathline for N=%s",tostring(n)))
20797
20945
  end
@@ -22454,21 +22602,39 @@ self:SetCommand(CommandSetFuel)
22454
22602
  end
22455
22603
  return self
22456
22604
  end
22457
- function CONTROLLABLE:CommandSetFrequency(Frequency,Modulation,Delay)
22605
+ function CONTROLLABLE:CommandSetFrequency(Frequency,Modulation,Power,Delay)
22458
22606
  local CommandSetFrequency={
22459
22607
  id='SetFrequency',
22460
22608
  params={
22461
22609
  frequency=Frequency*1000000,
22462
22610
  modulation=Modulation or radio.modulation.AM,
22611
+ power=Power or 10,
22463
22612
  },
22464
22613
  }
22465
22614
  if Delay and Delay>0 then
22466
- SCHEDULER:New(nil,self.CommandSetFrequency,{self,Frequency,Modulation},Delay)
22615
+ SCHEDULER:New(nil,self.CommandSetFrequency,{self,Frequency,Modulation,Power})
22467
22616
  else
22468
22617
  self:SetCommand(CommandSetFrequency)
22469
22618
  end
22470
22619
  return self
22471
22620
  end
22621
+ function CONTROLLABLE:CommandSetFrequencyForUnit(Frequency,Modulation,Power,UnitID,Delay)
22622
+ local CommandSetFrequencyForUnit={
22623
+ id='SetFrequencyForUnit',
22624
+ params={
22625
+ frequency=Frequency*1000000,
22626
+ modulation=Modulation or radio.modulation.AM,
22627
+ unitId=UnitID or self:GetID(),
22628
+ power=Power or 10,
22629
+ },
22630
+ }
22631
+ if Delay and Delay>0 then
22632
+ SCHEDULER:New(nil,self.CommandSetFrequencyForUnit,{self,Frequency,Modulation,Power,UnitID})
22633
+ else
22634
+ self:SetCommand(CommandSetFrequencyForUnit)
22635
+ end
22636
+ return self
22637
+ end
22472
22638
  function CONTROLLABLE:TaskEPLRS(SwitchOnOff,idx)
22473
22639
  if SwitchOnOff==nil then
22474
22640
  SwitchOnOff=true
@@ -24105,6 +24271,41 @@ return self
24105
24271
  end
24106
24272
  return nil
24107
24273
  end
24274
+ function CONTROLLABLE:SetOptionRadarUsing(Option)
24275
+ self:F2({self.ControllableName})
24276
+ if self:IsAir()then
24277
+ self:SetOption(AI.Option.Air.id.RADAR_USING,Option)
24278
+ end
24279
+ return self
24280
+ end
24281
+ function CONTROLLABLE:SetOptionRadarUsingNever()
24282
+ self:F2({self.ControllableName})
24283
+ if self:IsAir()then
24284
+ self:SetOption(AI.Option.Air.id.RADAR_USING,0)
24285
+ end
24286
+ return self
24287
+ end
24288
+ function CONTROLLABLE:SetOptionRadarUsingForAttackOnly()
24289
+ self:F2({self.ControllableName})
24290
+ if self:IsAir()then
24291
+ self:SetOption(AI.Option.Air.id.RADAR_USING,1)
24292
+ end
24293
+ return self
24294
+ end
24295
+ function CONTROLLABLE:SetOptionRadarUsingForSearchIfRequired()
24296
+ self:F2({self.ControllableName})
24297
+ if self:IsAir()then
24298
+ self:SetOption(AI.Option.Air.id.RADAR_USING,2)
24299
+ end
24300
+ return self
24301
+ end
24302
+ function CONTROLLABLE:SetOptionRadarUsingForContinousSearch()
24303
+ self:F2({self.ControllableName})
24304
+ if self:IsAir()then
24305
+ self:SetOption(AI.Option.Air.id.RADAR_USING,3)
24306
+ end
24307
+ return self
24308
+ end
24108
24309
  function CONTROLLABLE:RelocateGroundRandomInRadius(speed,radius,onroad,shortcut,formation,onland)
24109
24310
  self:F2({self.ControllableName})
24110
24311
  local _coord=self:GetCoordinate()
@@ -25327,7 +25528,14 @@ if DCSGroup then
25327
25528
  local DCSUnits=DCSGroup:getUnits()or{}
25328
25529
  local Units={}
25329
25530
  for Index,UnitData in pairs(DCSUnits)do
25531
+ local unit=UNIT:Find(UnitData)
25532
+ if unit then
25330
25533
  Units[#Units+1]=UNIT:Find(UnitData)
25534
+ else
25535
+ local UnitName=UnitData:getName()
25536
+ unit=_DATABASE:AddUnit(UnitName)
25537
+ Units[#Units+1]=unit
25538
+ end
25331
25539
  end
25332
25540
  self:T3(Units)
25333
25541
  return Units
@@ -25591,8 +25799,9 @@ end
25591
25799
  if n>0 then
25592
25800
  local Vec3={x=x/n,y=y/n,z=z/n}
25593
25801
  return Vec3
25802
+ else
25803
+ return self:GetVec3()
25594
25804
  end
25595
- return nil
25596
25805
  end
25597
25806
  function GROUP:GetPointVec2()
25598
25807
  self:F2(self.GroupName)
@@ -25613,10 +25822,15 @@ local Heading=self:GetHeading()
25613
25822
  coord.Heading=Heading
25614
25823
  return coord
25615
25824
  else
25825
+ local coord=self:GetCoordinate()
25826
+ if coord then
25827
+ return coord
25828
+ else
25616
25829
  BASE:E({"Cannot GetAverageCoordinate",Group=self,Alive=self:IsAlive()})
25617
25830
  return nil
25618
25831
  end
25619
25832
  end
25833
+ end
25620
25834
  function GROUP:GetCoordinate()
25621
25835
  local Units=self:GetUnits()or{}
25622
25836
  for _,_unit in pairs(Units)do
@@ -28770,7 +28984,12 @@ local function _createRunway(name,course,width,length,center)
28770
28984
  local bearing=-1*course
28771
28985
  local heading=math.deg(bearing)
28772
28986
  local runway={}
28987
+ local namefromheading=math.floor(heading/10)
28988
+ if self.AirbaseName==AIRBASE.Syria.Beirut_Rafic_Hariri and math.abs(namefromheading-name)>1 then
28989
+ runway.name=string.format("%02d",tonumber(namefromheading))
28990
+ else
28773
28991
  runway.name=string.format("%02d",tonumber(name))
28992
+ end
28774
28993
  runway.magheading=tonumber(runway.name)*10
28775
28994
  runway.heading=heading
28776
28995
  runway.width=width or 0
@@ -29132,11 +29351,25 @@ end
29132
29351
  function SCENERY:GetLife0()
29133
29352
  return self.Life0 or 0
29134
29353
  end
29135
- function SCENERY:IsAlive()
29354
+ function SCENERY:IsAlive(Threshold)
29355
+ if not Threshold then
29136
29356
  return self:GetLife()>=1 and true or false
29357
+ else
29358
+ return self:GetRelativeLife()>Threshold and true or false
29359
+ end
29137
29360
  end
29138
- function SCENERY:IsDead()
29361
+ function SCENERY:IsDead(Threshold)
29362
+ if not Threshold then
29139
29363
  return self:GetLife()<1 and true or false
29364
+ else
29365
+ return self:GetRelativeLife()<=Threshold and true or false
29366
+ end
29367
+ end
29368
+ function SCENERY:GetRelativeLife()
29369
+ local life=self:GetLife()
29370
+ local life0=self:GetLife0()
29371
+ local rlife=math.floor((life/life0)*100)
29372
+ return rlife
29140
29373
  end
29141
29374
  function SCENERY:GetThreatLevel()
29142
29375
  return 0,"Scenery"
@@ -31755,6 +31988,7 @@ self:SetMessagesScore(true)
31755
31988
  self:SetMessagesZone(true)
31756
31989
  self:SetScaleDestroyScore(10)
31757
31990
  self:SetScaleDestroyPenalty(30)
31991
+ self:SetScoreIncrementOnHit(0)
31758
31992
  self:SetFratricide(self.ScaleDestroyPenalty*3)
31759
31993
  self.penaltyonfratricide=true
31760
31994
  self:SetCoalitionChangePenalty(self.ScaleDestroyPenalty)
@@ -31831,6 +32065,10 @@ function SCORING:SetMessagesHit(OnOff)
31831
32065
  self.MessagesHit=OnOff
31832
32066
  return self
31833
32067
  end
32068
+ function SCORING:SetScoreIncrementOnHit(score)
32069
+ self.ScoreIncrementOnHit=score
32070
+ return self
32071
+ end
31834
32072
  function SCORING:IfMessagesHit()
31835
32073
  return self.MessagesHit
31836
32074
  end
@@ -32053,6 +32291,7 @@ local PlayerName=Event.IniUnit:GetPlayerName()
32053
32291
  Event.IniUnit.BirthTime=timer.getTime()
32054
32292
  if PlayerName then
32055
32293
  self:_AddPlayerFromUnit(Event.IniUnit)
32294
+ self.Players[PlayerName].PlayerKills=0
32056
32295
  self:SetScoringMenu(Event.IniGroup)
32057
32296
  end
32058
32297
  end
@@ -32176,6 +32415,8 @@ MESSAGE.Type.Update)
32176
32415
  end
32177
32416
  self:ScoreCSV(InitPlayerName,TargetPlayerName,"HIT_PENALTY",1,-10,InitUnitName,InitUnitCoalition,InitUnitCategory,InitUnitType,TargetUnitName,TargetUnitCoalition,TargetUnitCategory,TargetUnitType)
32178
32417
  else
32418
+ Player.Score=Player.Score+self.ScoreIncrementOnHit
32419
+ PlayerHit.Score=PlayerHit.Score+self.ScoreIncrementOnHit
32179
32420
  PlayerHit.ScoreHit=PlayerHit.ScoreHit+1
32180
32421
  if TargetPlayerName~=nil then
32181
32422
  MESSAGE:NewType(self.DisplayMessagePrefix.."Player '"..InitPlayerName.."' hit enemy player '"..TargetPlayerName.."' "..TargetUnitCategory.." ( "..TargetType.." ) "..PlayerHit.ScoreHit.." times. "..
@@ -32251,6 +32492,8 @@ MESSAGE.Type.Update
32251
32492
  :ToCoalitionIf(Event.WeaponCoalition,self:IfMessagesHit()and self:IfMessagesToCoalition())
32252
32493
  self:ScoreCSV(Event.WeaponPlayerName,TargetPlayerName,"HIT_PENALTY",1,-10,Event.WeaponName,Event.WeaponCoalition,Event.WeaponCategory,Event.WeaponTypeName,TargetUnitName,TargetUnitCoalition,TargetUnitCategory,TargetUnitType)
32253
32494
  else
32495
+ Player.Score=Player.Score+self.ScoreIncrementOnHit
32496
+ PlayerHit.Score=PlayerHit.Score+self.ScoreIncrementOnHit
32254
32497
  PlayerHit.ScoreHit=PlayerHit.ScoreHit+1
32255
32498
  MESSAGE:NewType(self.DisplayMessagePrefix.."Player '"..Event.WeaponPlayerName.."' hit enemy target "..TargetUnitCategory.." ( "..TargetType.." ) "..
32256
32499
  "Score: "..PlayerHit.Score..". Score Total:"..Player.Score-Player.Penalty,
@@ -32329,13 +32572,16 @@ self:F({ThreatLevel=ThreatPenalty,ThreatLevelTarget=ThreatLevelTarget,ThreatType
32329
32572
  Player.Penalty=Player.Penalty+ThreatPenalty
32330
32573
  TargetDestroy.Penalty=TargetDestroy.Penalty+ThreatPenalty
32331
32574
  TargetDestroy.PenaltyDestroy=TargetDestroy.PenaltyDestroy+1
32575
+ self:OnKillPvP(Player,TargetPlayerName,true,TargetThreatLevel,Player.ThreatLevel,ThreatPenalty)
32332
32576
  if Player.HitPlayers[TargetPlayerName]then
32577
+ self:OnKillPvP(Player,TargetPlayerName,true)
32333
32578
  MESSAGE:NewType(self.DisplayMessagePrefix.."Player '"..PlayerName.."' destroyed friendly player '"..TargetPlayerName.."' "..TargetUnitCategory.." ( "..ThreatTypeTarget.." ) "..
32334
32579
  "Penalty: -"..ThreatPenalty.." = "..Player.Score-Player.Penalty,
32335
32580
  MESSAGE.Type.Information)
32336
32581
  :ToAllIf(self:IfMessagesDestroy()and self:IfMessagesToAll())
32337
32582
  :ToCoalitionIf(InitCoalition,self:IfMessagesDestroy()and self:IfMessagesToCoalition())
32338
32583
  else
32584
+ self:OnKillPvE(Player,TargetUnitName,true,TargetThreatLevel,Player.ThreatLevel,ThreatPenalty)
32339
32585
  MESSAGE:NewType(self.DisplayMessagePrefix.."Player '"..PlayerName.."' destroyed friendly target "..TargetUnitCategory.." ( "..ThreatTypeTarget.." ) "..
32340
32586
  "Penalty: -"..ThreatPenalty.." = "..Player.Score-Player.Penalty,
32341
32587
  MESSAGE.Type.Information)
@@ -32354,12 +32600,19 @@ Player.Score=Player.Score+ThreatScore
32354
32600
  TargetDestroy.Score=TargetDestroy.Score+ThreatScore
32355
32601
  TargetDestroy.ScoreDestroy=TargetDestroy.ScoreDestroy+1
32356
32602
  if Player.HitPlayers[TargetPlayerName]then
32603
+ if Player.PlayerKills~=nil then
32604
+ Player.PlayerKills=Player.PlayerKills+1
32605
+ else
32606
+ Player.PlayerKills=1
32607
+ end
32608
+ self:OnKillPvP(Player,TargetPlayerName,false,TargetThreatLevel,Player.ThreatLevel,ThreatScore)
32357
32609
  MESSAGE:NewType(self.DisplayMessagePrefix.."Player '"..PlayerName.."' destroyed enemy player '"..TargetPlayerName.."' "..TargetUnitCategory.." ( "..ThreatTypeTarget.." ) "..
32358
32610
  "Score: +"..ThreatScore.." = "..Player.Score-Player.Penalty,
32359
32611
  MESSAGE.Type.Information)
32360
32612
  :ToAllIf(self:IfMessagesDestroy()and self:IfMessagesToAll())
32361
32613
  :ToCoalitionIf(InitCoalition,self:IfMessagesDestroy()and self:IfMessagesToCoalition())
32362
32614
  else
32615
+ self:OnKillPvE(Player,TargetUnitName,false,TargetThreatLevel,Player.ThreatLevel,ThreatScore)
32363
32616
  MESSAGE:NewType(self.DisplayMessagePrefix.."Player '"..PlayerName.."' destroyed enemy "..TargetUnitCategory.." ( "..ThreatTypeTarget.." ) "..
32364
32617
  "Score: +"..ThreatScore.." = "..Player.Score-Player.Penalty,
32365
32618
  MESSAGE.Type.Information)
@@ -32783,6 +33036,10 @@ function SCORING:SwitchAutoSave(OnOff)
32783
33036
  self.AutoSave=OnOff
32784
33037
  return self
32785
33038
  end
33039
+ function SCORING:OnKillPvP(Player,TargetPlayerName,IsTeamKill,TargetThreatLevel,PlayerThreatLevel,Score)
33040
+ end
33041
+ function SCORING:OnKillPvE(Player,TargetUnitName,IsTeamKill,TargetThreatLevel,PlayerThreatLevel,Score)
33042
+ end
32786
33043
  CLEANUP_AIRBASE={
32787
33044
  ClassName="CLEANUP_AIRBASE",
32788
33045
  TimeInterval=0.2,
@@ -41009,15 +41266,17 @@ end
41009
41266
  function RANGE:SetSRS(PathToSRS,Port,Coalition,Frequency,Modulation,Volume,PathToGoogleKey)
41010
41267
  if PathToSRS or MSRS.path then
41011
41268
  self.useSRS=true
41012
- self.controlmsrs=MSRS:New(PathToSRS or MSRS.path,Frequency or 256,Modulation or radio.modulation.AM,Volume or 1.0)
41269
+ self.controlmsrs=MSRS:New(PathToSRS or MSRS.path,Frequency or 256,Modulation or radio.modulation.AM)
41013
41270
  self.controlmsrs:SetPort(Port or MSRS.port)
41014
41271
  self.controlmsrs:SetCoalition(Coalition or coalition.side.BLUE)
41015
41272
  self.controlmsrs:SetLabel("RANGEC")
41273
+ self.controlmsrs:SetVolume(Volume or 1.0)
41016
41274
  self.controlsrsQ=MSRSQUEUE:New("CONTROL")
41017
- self.instructmsrs=MSRS:New(PathToSRS or MSRS.path,Frequency or 305,Modulation or radio.modulation.AM,Volume or 1.0)
41275
+ self.instructmsrs=MSRS:New(PathToSRS or MSRS.path,Frequency or 305,Modulation or radio.modulation.AM)
41018
41276
  self.instructmsrs:SetPort(Port or MSRS.port)
41019
41277
  self.instructmsrs:SetCoalition(Coalition or coalition.side.BLUE)
41020
41278
  self.instructmsrs:SetLabel("RANGEI")
41279
+ self.instructmsrs:SetVolume(Volume or 1.0)
41021
41280
  self.instructsrsQ=MSRSQUEUE:New("INSTRUCT")
41022
41281
  if PathToGoogleKey then
41023
41282
  self.controlmsrs:SetGoogle(PathToGoogleKey)
@@ -44526,7 +44785,7 @@ end
44526
44785
  end
44527
44786
  function ARTY:onafterRespawn(Controllable,From,Event,To)
44528
44787
  self:_EventFromTo("onafterRespawn",Event,From,To)
44529
- env.info("FF Respawning arty group")
44788
+ self:I("Respawning arty group")
44530
44789
  local group=self.Controllable
44531
44790
  self.Controllable=group:Respawn()
44532
44791
  self.respawning=false
@@ -47467,6 +47726,7 @@ if self:IsRunwayOperational()==false then
47467
47726
  local Trepair=self:GetRunwayRepairtime()
47468
47727
  self:I(self.lid..string.format("Runway destroyed! Will be repaired in %d sec",Trepair))
47469
47728
  if Trepair==0 then
47729
+ self.runwaydestroyed=nil
47470
47730
  self:RunwayRepaired()
47471
47731
  end
47472
47732
  end
@@ -48367,11 +48627,13 @@ function WAREHOUSE:onafterRunwayDestroyed(From,Event,To)
48367
48627
  local text=string.format("Warehouse %s: Runway %s destroyed!",self.alias,self.airbasename)
48368
48628
  self:_InfoMessage(text)
48369
48629
  self.runwaydestroyed=timer.getAbsTime()
48630
+ return self
48370
48631
  end
48371
48632
  function WAREHOUSE:onafterRunwayRepaired(From,Event,To)
48372
48633
  local text=string.format("Warehouse %s: Runway %s repaired!",self.alias,self.airbasename)
48373
48634
  self:_InfoMessage(text)
48374
48635
  self.runwaydestroyed=nil
48636
+ return self
48375
48637
  end
48376
48638
  function WAREHOUSE:onafterAssetSpawned(From,Event,To,group,asset,request)
48377
48639
  local text=string.format("Asset %s from request id=%d was spawned!",asset.spawngroupname,request.uid)
@@ -51281,17 +51543,17 @@ MEDIUM="Medium",
51281
51543
  LONG="Long",
51282
51544
  }
51283
51545
  MANTIS.SamData={
51284
- ["Hawk"]={Range=44,Blindspot=0,Height=9,Type="Medium",Radar="Hawk"},
51285
- ["NASAMS"]={Range=14,Blindspot=0,Height=3,Type="Short",Radar="NSAMS"},
51286
- ["Patriot"]={Range=99,Blindspot=0,Height=9,Type="Long",Radar="Patriot"},
51287
- ["Rapier"]={Range=6,Blindspot=0,Height=3,Type="Short",Radar="rapier"},
51546
+ ["Hawk"]={Range=35,Blindspot=0,Height=12,Type="Medium",Radar="Hawk"},
51547
+ ["NASAMS"]={Range=14,Blindspot=0,Height=7,Type="Short",Radar="NSAMS"},
51548
+ ["Patriot"]={Range=99,Blindspot=0,Height=25,Type="Long",Radar="Patriot"},
51549
+ ["Rapier"]={Range=10,Blindspot=0,Height=3,Type="Short",Radar="rapier"},
51288
51550
  ["SA-2"]={Range=40,Blindspot=7,Height=25,Type="Medium",Radar="S_75M_Volhov"},
51289
51551
  ["SA-3"]={Range=18,Blindspot=6,Height=18,Type="Short",Radar="5p73 s-125 ln"},
51290
51552
  ["SA-5"]={Range=250,Blindspot=7,Height=40,Type="Long",Radar="5N62V"},
51291
51553
  ["SA-6"]={Range=25,Blindspot=0,Height=8,Type="Medium",Radar="1S91"},
51292
51554
  ["SA-10"]={Range=119,Blindspot=0,Height=18,Type="Long",Radar="S-300PS 4"},
51293
51555
  ["SA-11"]={Range=35,Blindspot=0,Height=20,Type="Medium",Radar="SA-11"},
51294
- ["Roland"]={Range=8,Blindspot=0,Height=3,Type="Short",Radar="Roland"},
51556
+ ["Roland"]={Range=5,Blindspot=0,Height=5,Type="Short",Radar="Roland"},
51295
51557
  ["HQ-7"]={Range=12,Blindspot=0,Height=3,Type="Short",Radar="HQ-7"},
51296
51558
  ["SA-9"]={Range=4,Blindspot=0,Height=3,Type="Short",Radar="Strela"},
51297
51559
  ["SA-8"]={Range=10,Blindspot=0,Height=5,Type="Short",Radar="Osa 9A33"},
@@ -53467,7 +53729,7 @@ end
53467
53729
  function AIRBOSS:EnableSRS(PathToSRS,Port,Culture,Gender,Voice,GoogleCreds,Volume,AltBackend)
53468
53730
  local Frequency=self.AirbossRadio.frequency
53469
53731
  local Modulation=self.AirbossRadio.modulation
53470
- self.SRS=MSRS:New(PathToSRS,Frequency,Modulation,Volume,AltBackend)
53732
+ self.SRS=MSRS:New(PathToSRS,Frequency,Modulation,AltBackend)
53471
53733
  self.SRS:SetCoalition(self:GetCoalition())
53472
53734
  self.SRS:SetCoordinate(self:GetCoordinate())
53473
53735
  self.SRS:SetCulture(Culture or"en-US")
@@ -53476,6 +53738,7 @@ self.SRS:SetPath(PathToSRS)
53476
53738
  self.SRS:SetPort(Port or 5002)
53477
53739
  self.SRS:SetLabel(self.AirbossRadio.alias or"AIRBOSS")
53478
53740
  self.SRS:SetCoordinate(self.carrier:GetCoordinate())
53741
+ self.SRS:SetVolume(Volume or 1)
53479
53742
  if GoogleCreds then
53480
53743
  self.SRS:SetGoogle(GoogleCreds)
53481
53744
  end
@@ -58002,13 +58265,12 @@ local GXX,nXX=self:_Flightdata2Text(playerData,AIRBOSS.GroovePos.XX)
58002
58265
  local GIM,nIM=self:_Flightdata2Text(playerData,AIRBOSS.GroovePos.IM)
58003
58266
  local GIC,nIC=self:_Flightdata2Text(playerData,AIRBOSS.GroovePos.IC)
58004
58267
  local GAR,nAR=self:_Flightdata2Text(playerData,AIRBOSS.GroovePos.AR)
58268
+ local vtol=playerData.actype==AIRBOSS.AircraftCarrier.AV8B
58005
58269
  local G=GXX.." "..GIM.." ".." "..GIC.." "..GAR
58006
58270
  local N=nXX+nIM+nIC+nAR
58007
- local Nv=nXX+nIM
58008
58271
  local nL=count(G,'_')/2
58009
58272
  local nS=count(G,'%(')
58010
58273
  local nN=N-nS-nL
58011
- local nNv=Nv-nS-nL
58012
58274
  local Tgroove=playerData.Tgroove
58013
58275
  local TgrooveUnicorn=Tgroove and(Tgroove>=15.0 and Tgroove<=18.99)or false
58014
58276
  local TgrooveVstolUnicorn=Tgroove and(Tgroove>=60.0 and Tgroove<=65.0)and playerData.actype==AIRBOSS.AircraftCarrier.AV8B or false
@@ -58019,16 +58281,29 @@ grade="_OK_"
58019
58281
  points=5.0
58020
58282
  G="Unicorn"
58021
58283
  else
58022
- if nL>1 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then
58284
+ if vtol then
58285
+ local Gb=GXX.." "..GIM
58286
+ local N=nXX+nIM
58287
+ local nL=count(Gb,'_')/2
58288
+ local nS=count(Gb,'%(')
58289
+ local nN=N-nS-nL
58290
+ local Gv=GIC.." "..GAR
58291
+ local Nv=nIC+nAR
58292
+ local nLv=count(Gv,'_')/2
58293
+ local nSv=count(Gv,'%(')
58294
+ local nNv=Nv-nSv-nLv
58295
+ if nL>0 or nLv>1 then
58023
58296
  grade="--"
58024
58297
  points=2.0
58025
- elseif nNv>=1 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then
58298
+ elseif nN>0 or nNv>1 or nLv==1 then
58026
58299
  grade="(OK)"
58027
58300
  points=3.0
58028
- elseif nNv<1 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then
58301
+ else
58029
58302
  grade="OK"
58030
58303
  points=4.0
58031
- elseif nL>0 then
58304
+ end
58305
+ else
58306
+ if nL>0 then
58032
58307
  grade="--"
58033
58308
  points=2.0
58034
58309
  elseif nN>0 then
@@ -58039,6 +58314,7 @@ grade="OK"
58039
58314
  points=4.0
58040
58315
  end
58041
58316
  end
58317
+ end
58042
58318
  G=G:gsub("%)%(","")
58043
58319
  G=G:gsub("__","")
58044
58320
  local text="LSO grade:\n"
@@ -59795,6 +60071,10 @@ end
59795
60071
  if pilotcall then
59796
60072
  Sender="PilotCall"
59797
60073
  end
60074
+ if Sender==""then
60075
+ self:E(self.lid..string.format("ERROR: Sender unknown!"))
60076
+ return
60077
+ end
59798
60078
  local numbers=_split(number)
59799
60079
  local wait=0
59800
60080
  for i=1,#numbers do
@@ -62571,7 +62851,7 @@ ATIS.Messages={
62571
62851
  EN=
62572
62852
  {
62573
62853
  HOURS="hours",
62574
- TIME="hours",
62854
+ TIME="Hours",
62575
62855
  NOCLOUDINFO="Cloud coverage information not available",
62576
62856
  OVERCAST="Overcast",
62577
62857
  BROKEN="Broken clouds",
@@ -63020,24 +63300,40 @@ end
63020
63300
  end
63021
63301
  end
63022
63302
  function ATIS:SetSRS(PathToSRS,Gender,Culture,Voice,Port,GoogleKey)
63023
- if PathToSRS or MSRS.path then
63024
63303
  self.useSRS=true
63025
- self.msrs=MSRS:New(PathToSRS,self.frequency,self.modulation)
63026
- self.msrs:SetGender(Gender)
63027
- self.msrs:SetCulture(Culture)
63028
- self.msrs:SetVoice(Voice)
63029
- self.msrs:SetPort(Port)
63304
+ local path=PathToSRS or MSRS.path
63305
+ local gender=Gender or MSRS.gender
63306
+ local culture=Culture or MSRS.culture
63307
+ local voice=Voice or MSRS.voice
63308
+ local port=Port or MSRS.port or 5002
63309
+ self.msrs=MSRS:New(path,self.frequency,self.modulation)
63310
+ self.msrs:SetGender(gender)
63311
+ self.msrs:SetCulture(culture)
63312
+ self.msrs:SetPort(port)
63030
63313
  self.msrs:SetCoalition(self:GetCoalition())
63031
63314
  self.msrs:SetLabel("ATIS")
63032
- self.msrs:SetGoogle(GoogleKey)
63315
+ if GoogleKey then
63316
+ self.msrs:SetProviderOptionsGoogle(GoogleKey,GoogleKey)
63317
+ self.msrs:SetProvider(MSRS.Provider.GOOGLE)
63318
+ end
63319
+ if(not GoogleKey)and self.msrs:GetProvider()==MSRS.Provider.GOOGLE then
63320
+ voice=Voice or MSRS.poptions.gcloud.voice
63321
+ end
63322
+ self.msrs:SetVoice(voice)
63033
63323
  self.msrs:SetCoordinate(self.airbase:GetCoordinate())
63034
63324
  self.msrsQ=MSRSQUEUE:New("ATIS")
63035
63325
  self.msrsQ:SetTransmitOnlyWithPlayers(self.TransmitOnlyWithPlayers)
63036
63326
  if self.dTQueueCheck<=10 then
63037
63327
  self:SetQueueUpdateTime(90)
63038
63328
  end
63329
+ return self
63330
+ end
63331
+ function ATIS:SetSRSProvider(Provider)
63332
+ self:T(self.lid.."SetSRSProvider")
63333
+ if self.msrs then
63334
+ self.msrs:SetProvider(Provider)
63039
63335
  else
63040
- self:E(self.lid..string.format("ERROR: No SRS path specified!"))
63336
+ MESSAGE:New(self.lid.."Set up SRS first before trying to change the provider!",30,"ATIS"):ToAll():ToLog()
63041
63337
  end
63042
63338
  return self
63043
63339
  end
@@ -64628,7 +64924,7 @@ end
64628
64924
  function CTLD:_GenerateUHFrequencies()
64629
64925
  self:T(self.lid.." _GenerateUHFrequencies")
64630
64926
  self.FreeUHFFrequencies={}
64631
- self.FreeUHFFrequencies=UTILS.GenerateUHFrequencies()
64927
+ self.FreeUHFFrequencies=UTILS.GenerateUHFrequencies(243,320)
64632
64928
  return self
64633
64929
  end
64634
64930
  function CTLD:_GenerateFMFrequencies()
@@ -68141,7 +68437,7 @@ CSAR.AircraftType["Bell-47"]=2
68141
68437
  CSAR.AircraftType["UH-60L"]=10
68142
68438
  CSAR.AircraftType["AH-64D_BLK_II"]=2
68143
68439
  CSAR.AircraftType["Bronco-OV-10A"]=2
68144
- CSAR.version="1.0.18"
68440
+ CSAR.version="1.0.19"
68145
68441
  function CSAR:New(Coalition,Template,Alias)
68146
68442
  local self=BASE:Inherit(self,FSM:New())
68147
68443
  BASE:T({Coalition,Template,Alias})
@@ -68418,7 +68714,7 @@ end
68418
68714
  self:T({_spawnedGroup,_alias})
68419
68715
  local _GroupName=_spawnedGroup:GetName()or _alias
68420
68716
  self:_CreateDownedPilotTrack(_spawnedGroup,_GroupName,_coalition,_unitName,_text,_typeName,_freq,_playerName,wetfeet)
68421
- self:_InitSARForPilot(_spawnedGroup,_unitName,_freq,noMessage)
68717
+ self:_InitSARForPilot(_spawnedGroup,_unitName,_freq,noMessage,_playerName)
68422
68718
  return self
68423
68719
  end
68424
68720
  function CSAR:_SpawnCsarAtZone(_zone,_coalition,_description,_randomPoint,_nomessage,unitname,typename,forcedesc)
@@ -68653,7 +68949,7 @@ end
68653
68949
  end
68654
68950
  return self
68655
68951
  end
68656
- function CSAR:_InitSARForPilot(_downedGroup,_GroupName,_freq,_nomessage)
68952
+ function CSAR:_InitSARForPilot(_downedGroup,_GroupName,_freq,_nomessage,_playername)
68657
68953
  self:T(self.lid.." _InitSARForPilot")
68658
68954
  local _leader=_downedGroup:GetUnit(1)
68659
68955
  local _groupName=_GroupName
@@ -68672,7 +68968,7 @@ end
68672
68968
  for _,_heliName in pairs(self.csarUnits)do
68673
68969
  self:_CheckWoundedGroupStatus(_heliName,_groupName)
68674
68970
  end
68675
- self:__PilotDown(2,_downedGroup,_freqk,_groupName,_coordinatesText)
68971
+ self:__PilotDown(2,_downedGroup,_freqk,_groupName,_coordinatesText,_playername)
68676
68972
  return self
68677
68973
  end
68678
68974
  function CSAR:_CheckNameInDownedPilots(name)
@@ -69145,7 +69441,7 @@ self:T(self.lid.." _DisplayToAllSAR")
69145
69441
  local messagetime=_messagetime or self.messageTime
69146
69442
  if self.msrs then
69147
69443
  local voice=self.CSARVoice or MSRS.Voices.Google.Standard.en_GB_Standard_F
69148
- if self.msrs.google==nil then
69444
+ if self.msrs:GetProvider()==MSRS.Provider.WINDOWS then
69149
69445
  voice=self.CSARVoiceMS or MSRS.Voices.Microsoft.Hedda
69150
69446
  end
69151
69447
  self:I("Voice = "..voice)
@@ -69448,7 +69744,8 @@ self.msrs:SetCoalition(self.coalition)
69448
69744
  self.msrs:SetVoice(self.SRSVoice)
69449
69745
  self.msrs:SetGender(self.SRSGender)
69450
69746
  if self.SRSGPathToCredentials then
69451
- self.msrs:SetGoogle(self.SRSGPathToCredentials)
69747
+ self.msrs:SetProviderOptionsGoogle(self.SRSGPathToCredentials,self.SRSGPathToCredentials)
69748
+ self.msrs:SetProvider(MSRS.Provider.GOOGLE)
69452
69749
  end
69453
69750
  self.msrs:SetVolume(self.SRSVolume)
69454
69751
  self.msrs:SetLabel("CSAR")
@@ -69599,8 +69896,8 @@ end
69599
69896
  end
69600
69897
  return self
69601
69898
  end
69602
- function CSAR:onbeforePilotDown(From,Event,To,Group,Frequency,Leadername,CoordinatesText)
69603
- self:T({From,Event,To,Group,Frequency,Leadername,CoordinatesText})
69899
+ function CSAR:onbeforePilotDown(From,Event,To,Group,Frequency,Leadername,CoordinatesText,Playername)
69900
+ self:T({From,Event,To,Group,Frequency,Leadername,CoordinatesText,tostring(Playername)})
69604
69901
  return self
69605
69902
  end
69606
69903
  function CSAR:onbeforeLanded(From,Event,To,HeliName,Airbase)
@@ -78649,8 +78946,10 @@ self.power=power or 100
78649
78946
  return self
78650
78947
  end
78651
78948
  function RADIOQUEUE:SetSRS(PathToSRS,Port)
78652
- self.msrs=MSRS:New(PathToSRS,self.frequency/1000000,self.modulation)
78653
- self.msrs:SetPort(Port)
78949
+ local path=PathToSRS or MSRS.path
78950
+ local port=Port or MSRS.port
78951
+ self.msrs=MSRS:New(path,self.frequency/1000000,self.modulation)
78952
+ self.msrs:SetPort(port)
78654
78953
  return self
78655
78954
  end
78656
78955
  function RADIOQUEUE:SetDigit(digit,filename,duration,path,subtitle,subduration)
@@ -79173,6 +79472,39 @@ Microsoft={
79173
79472
  ["David"]="Microsoft David Desktop",
79174
79473
  ["Zira"]="Microsoft Zira Desktop",
79175
79474
  ["Hortense"]="Microsoft Hortense Desktop",
79475
+ ["de-DE-Hedda"]="Microsoft Hedda Desktop",
79476
+ ["en-GB-Hazel"]="Microsoft Hazel Desktop",
79477
+ ["en-US-David"]="Microsoft David Desktop",
79478
+ ["en-US-Zira"]="Microsoft Zira Desktop",
79479
+ ["fr-FR-Hortense"]="Microsoft Hortense Desktop",
79480
+ },
79481
+ MicrosoftGRPC={
79482
+ ["Hazel"]="Hazel",
79483
+ ["George"]="George",
79484
+ ["Susan"]="Susan",
79485
+ ["David"]="David",
79486
+ ["Zira"]="Zira",
79487
+ ["Mark"]="Mark",
79488
+ ["James"]="James",
79489
+ ["Catherine"]="Catherine",
79490
+ ["Richard"]="Richard",
79491
+ ["Linda"]="Linda",
79492
+ ["Ravi"]="Ravi",
79493
+ ["Heera"]="Heera",
79494
+ ["Sean"]="Sean",
79495
+ ["en_GB_Hazel"]="Hazel",
79496
+ ["en_GB_George"]="George",
79497
+ ["en_GB_Susan"]="Susan",
79498
+ ["en_US_David"]="David",
79499
+ ["en_US_Zira"]="Zira",
79500
+ ["en_US_Mark"]="Mark",
79501
+ ["en_AU_James"]="James",
79502
+ ["en_AU_Catherine"]="Catherine",
79503
+ ["en_CA_Richard"]="Richard",
79504
+ ["en_CA_Linda"]="Linda",
79505
+ ["en_IN_Ravi"]="Ravi",
79506
+ ["en_IN_Heera"]="Heera",
79507
+ ["en_IR_Sean"]="Sean",
79176
79508
  },
79177
79509
  Google={
79178
79510
  Standard={
@@ -79320,7 +79652,19 @@ return self
79320
79652
  end
79321
79653
  function MSRS:SetBackend(Backend)
79322
79654
  self:F({Backend=Backend})
79323
- self.backend=Backend or MSRS.Backend.SRSEXE
79655
+ Backend=Backend or MSRS.Backend.SRSEXE
79656
+ local function Checker(back)
79657
+ local ok=false
79658
+ for _,_backend in pairs(MSRS.Backend)do
79659
+ if tostring(back)==_backend then ok=true end
79660
+ end
79661
+ return ok
79662
+ end
79663
+ if Checker(Backend)then
79664
+ self.backend=Backend
79665
+ else
79666
+ MESSAGE:New("ERROR: Backend "..tostring(Backend).." is not supported!",30,"MSRS",true):ToLog():ToAll()
79667
+ end
79324
79668
  return self
79325
79669
  end
79326
79670
  function MSRS:SetBackendGRPC()
@@ -79334,11 +79678,9 @@ self:SetBackend(MSRS.Backend.SRSEXE)
79334
79678
  return self
79335
79679
  end
79336
79680
  function MSRS.SetDefaultBackend(Backend)
79337
- self:F({Backend=Backend})
79338
79681
  MSRS.backend=Backend or MSRS.Backend.SRSEXE
79339
79682
  end
79340
79683
  function MSRS.SetDefaultBackendGRPC()
79341
- self:F()
79342
79684
  MSRS.backend=MSRS.Backend.GRPC
79343
79685
  end
79344
79686
  function MSRS:GetBackend()
@@ -79503,15 +79845,20 @@ end
79503
79845
  return self
79504
79846
  end
79505
79847
  function MSRS:SetProvider(Provider)
79506
- self:F({Provider=Provider})
79848
+ BASE:F({Provider=Provider})
79849
+ if self then
79507
79850
  self.provider=Provider or MSRS.Provider.WINDOWS
79508
79851
  return self
79852
+ else
79853
+ MSRS.provider=Provider or MSRS.Provider.WINDOWS
79854
+ end
79855
+ return
79509
79856
  end
79510
79857
  function MSRS:GetProvider()
79511
79858
  return self.provider or MSRS.Provider.WINDOWS
79512
79859
  end
79513
79860
  function MSRS:SetProviderOptions(Provider,CredentialsFile,AccessKey,SecretKey,Region)
79514
- self:F({Provider,CredentialsFile,AccessKey,SecretKey,Region})
79861
+ BASE:F({Provider,CredentialsFile,AccessKey,SecretKey,Region})
79515
79862
  local option=MSRS._CreateProviderOptions(Provider,CredentialsFile,AccessKey,SecretKey,Region)
79516
79863
  if self then
79517
79864
  self.poptions=self.poptions or{}
@@ -79523,7 +79870,7 @@ end
79523
79870
  return option
79524
79871
  end
79525
79872
  function MSRS._CreateProviderOptions(Provider,CredentialsFile,AccessKey,SecretKey,Region)
79526
- self:F({Provider,CredentialsFile,AccessKey,SecretKey,Region})
79873
+ BASE:F({Provider,CredentialsFile,AccessKey,SecretKey,Region})
79527
79874
  local option={}
79528
79875
  option.provider=Provider
79529
79876
  option.credentials=CredentialsFile
@@ -79633,7 +79980,7 @@ end
79633
79980
  return self
79634
79981
  end
79635
79982
  function MSRS:PlayTextExt(Text,Delay,Frequencies,Modulations,Gender,Culture,Voice,Volume,Label,Coordinate)
79636
- self:F({Text,Delay,Frequencies,Modulations,Gender,Culture,Voice,Volume,Label,Coordinate})
79983
+ self:T({Text,Delay,Frequencies,Modulations,Gender,Culture,Voice,Volume,Label,Coordinate})
79637
79984
  if Delay and Delay>0 then
79638
79985
  self:ScheduleOnce(Delay,MSRS.PlayTextExt,self,Text,0,Frequencies,Modulations,Gender,Culture,Voice,Volume,Label,Coordinate)
79639
79986
  else
@@ -79893,7 +80240,7 @@ self.lid=string.format("MSRSQUEUE %s | ",self.alias)
79893
80240
  return self
79894
80241
  end
79895
80242
  function MSRSQUEUE:Clear()
79896
- self:I(self.lid.."Clearing MSRSQUEUE")
80243
+ self:T(self.lid.."Clearing MSRSQUEUE")
79897
80244
  self.queue={}
79898
80245
  return self
79899
80246
  end
@@ -79939,24 +80286,25 @@ transmission.msrs=msrs
79939
80286
  transmission.Tplay=tstart or timer.getAbsTime()
79940
80287
  transmission.subtitle=subtitle
79941
80288
  transmission.interval=interval or 0
79942
- transmission.frequency=frequency
79943
- transmission.modulation=modulation
80289
+ transmission.frequency=frequency or msrs.frequencies
80290
+ transmission.modulation=modulation or msrs.modulations
79944
80291
  transmission.subgroups=subgroups
79945
80292
  if transmission.subtitle then
79946
80293
  transmission.subduration=subduration or transmission.duration
79947
80294
  else
79948
80295
  transmission.subduration=0
79949
80296
  end
79950
- transmission.gender=gender
79951
- transmission.culture=culture
79952
- transmission.voice=voice
79953
- transmission.volume=volume
79954
- transmission.label=label
79955
- transmission.coordinate=coordinate
80297
+ transmission.gender=gender or msrs.gender
80298
+ transmission.culture=culture or msrs.culture
80299
+ transmission.voice=voice or msrs.voice
80300
+ transmission.volume=volume or msrs.volume
80301
+ transmission.label=label or msrs.Label
80302
+ transmission.coordinate=coordinate or msrs.coordinate
79956
80303
  self:AddTransmission(transmission)
79957
80304
  return transmission
79958
80305
  end
79959
80306
  function MSRSQUEUE:Broadcast(transmission)
80307
+ self:T(self.lid.."Broadcast")
79960
80308
  if transmission.frequency then
79961
80309
  transmission.msrs:PlayTextExt(transmission.text,nil,transmission.frequency,transmission.modulation,transmission.gender,transmission.culture,transmission.voice,transmission.volume,transmission.label,transmission.coordinate)
79962
80310
  else
@@ -0,0 +1 @@
1
+ FunkMan = SOCKET:New(10042, "127.0.0.1")
@@ -30,7 +30,7 @@ function detectShitHotBreak(objAirboss)
30
30
  -- Requirements for Shit Hot break are velocity >475 knots and less than 700 feet
31
31
  trigger.action.outText(player_name..' performing a Sierra Hotel Break around ' .. objAirboss.customconfig.alias .. ' !', 10)
32
32
  local sh_message_to_discord = ('**'..player_name..' is performing a Sierra Hotel Break at '..UTILS.Round(player_velocity, 0)..' knots and '..player_alt_feet..' feet!**')
33
- GemMan:SendTable({
33
+ FunkMan:SendTable({
34
34
  command="moose_text",
35
35
  text=sh_message_to_discord,
36
36
  msg_type='lso'
@@ -200,7 +200,7 @@ for index, airbossconfig in ipairs(AirBossConfig) do
200
200
  objAirboss:SetMaxSectionSize(4)
201
201
  objAirboss:SetMaxMarshalStacks(airbossconfig.maxstacks)
202
202
  objAirboss:SetDefaultPlayerSkill(airbossconfig.difficulty) -- other options EASY / HARD
203
- objAirboss:SetFunkManOn(10043, "127.0.0.1")
203
+ objAirboss:SetFunkManOn(10042, "127.0.0.1")
204
204
  if airbossconfig.wirecorrection then
205
205
  objAirboss:SetMPWireCorrection(airbossconfig.wirecorrection)
206
206
  else
@@ -350,16 +350,16 @@ for index, airbossconfig in ipairs(AirBossConfig) do
350
350
  myGrade.points = myGrade.points + 1.00
351
351
  client_performing_sh:Set(0)
352
352
  self:SetTrapSheet(self.trappath, "SH_unicorn_AIRBOSS-trapsheet-"..player_name)
353
- timer.scheduleFunction(
354
- function()
355
- trigger.action.outSound("AIRBOSS/Airboss Soundfiles/sureshot.ogg")
356
- end,
357
- {},
358
- timer.getTime() + 5
359
- )
360
353
  else
361
354
  self:SetTrapSheet(self.trappath, "unicorn_AIRBOSS-trapsheet-"..player_name)
362
355
  end
356
+ timer.scheduleFunction(
357
+ function()
358
+ trigger.action.outSound("AIRBOSS/Airboss Soundfiles/sureshot.ogg")
359
+ end,
360
+ {},
361
+ timer.getTime() + 5
362
+ )
363
363
 
364
364
  elseif string_grade == "OK" and player_wire >1 then
365
365
  if client_performing_sh:Get() == 1 then
@@ -401,7 +401,7 @@ for index, airbossconfig in ipairs(AirBossConfig) do
401
401
  if playerData.wire == 1 then
402
402
  myGrade.points = myGrade.points -1.00
403
403
  local onewire_to_discord = ('**'..player_name..' almost had a rampstrike with that 1-wire!**')
404
- GemMan:SendTable({
404
+ FunkMan:SendTable({
405
405
  command="moose_text",
406
406
  text=onewire_to_discord,
407
407
  msg_type='lso'
@@ -15,7 +15,7 @@ for index, traingingrangeconfig in ipairs(TrainingRangeConfig) do
15
15
  trainingRange:SetDefaultPlayerSmokeBomb(false)
16
16
  trainingRange:SetRangeRadius(0.2) -- bomb impact at more than 200m is out of range
17
17
  trainingRange:SetScoreBombDistance(100)-- bomb impact at more than 100m won't be taken into account
18
- trainingRange:SetFunkManOn(10043,"127.0.0.1")
18
+ trainingRange:SetFunkManOn(10042,"127.0.0.1")
19
19
  trainingRange:SetAutosaveOn()
20
20
  trainingRange:SetTargetSheet(traingingrangeconfig.targetsheetpath)
21
21
  if ( type(traingingrangeconfig.srs) ~= nil ) then
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jtff/miztemplate-lib",
3
- "version": "3.1.10",
3
+ "version": "3.2.0",
4
4
  "description": "JTFF mission template library",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -213,7 +213,7 @@ async function doInject(ciObject, sourceMizFileName, workspacePath,destinationMi
213
213
  // insertion des Librairies JTFF dans la file d'attente
214
214
  settingsArray.push(
215
215
  {
216
- file: "settings-gemman.lua",
216
+ file: "settings-funkman.lua",
217
217
  },
218
218
  {
219
219
  file: "settings-global.lua",
@@ -221,8 +221,8 @@ async function doInject(ciObject, sourceMizFileName, workspacePath,destinationMi
221
221
  );
222
222
  libsArray.push({
223
223
  folder: 'lib',
224
- scriptTitle: 'GemMan',
225
- scripts: ['gemman.lua'],
224
+ scriptTitle: 'FunkMan',
225
+ scripts: ['funkman.lua'],
226
226
  timing: 17,
227
227
  color: '0xffff00ff'
228
228
  });
@@ -1 +0,0 @@
1
- GemMan = SOCKET:New(10043, "127.0.0.1")