@jtff/miztemplate-lib 3.1.8 → 3.1.10
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/lua/lib/HoundElint.lua +7101 -0
- package/lua/lib/Moose_.lua +721 -494
- package/lua/lib/skynet-iads-compiled.lua +106 -60
- package/lua/src/020-mission_functions.lua +75 -69
- package/lua/src/110-set_clients.lua +6 -6
- package/lua/src/120-tankers.lua +26 -26
- package/lua/src/130-airboss.lua +45 -46
- package/lua/src/150-awacs.lua +22 -22
- package/lua/src/173-fox_zone_training.lua +4 -4
- package/lua/src/176-random_air_traffic.lua +3 -3
- package/lua/src/178-training-intercept.lua +12 -12
- package/lua/src/195-reaper-ondemand.lua +17 -16
- package/lua/src/199-skynet.lua +134 -101
- package/package.json +1 -1
- package/resources/sounds/AIRBOSS/Airboss Soundfiles/GetYourButtsUptoVipersOffice.ogg +0 -0
- package/resources/sounds/AIRBOSS/Airboss Soundfiles/GreatBallsOfFire.ogg +0 -0
- package/resources/sounds/AIRBOSS/Airboss Soundfiles/ffyrtp.ogg +0 -0
- package/resources/sounds/AIRBOSS/Airboss Soundfiles/sureshot.ogg +0 -0
- package/scripts/inject-scripts.js +4 -4
- /package/resources/sounds/{CTLD → CTLD CSAR}/beacon.ogg +0 -0
- /package/resources/sounds/{CTLD → CTLD CSAR}/beaconsilent.ogg +0 -0
package/lua/lib/Moose_.lua
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
env.info('*** MOOSE GITHUB Commit Hash ID:
|
|
1
|
+
env.info('*** MOOSE GITHUB Commit Hash ID: 2024-01-01T00:38:59+01:00-8dcd22f18c9bf740c53b69c7ba3901a9ada0bb2d ***')
|
|
2
2
|
env.info('*** MOOSE STATIC INCLUDE START *** ')
|
|
3
3
|
ENUMS={}
|
|
4
4
|
env.setErrorMessageBoxEnabled(false)
|
|
@@ -379,6 +379,7 @@ Galaxy="C-5",
|
|
|
379
379
|
Hawkeye="E-2D",
|
|
380
380
|
Sentry="E-3A",
|
|
381
381
|
Stratotanker="KC-135",
|
|
382
|
+
Gasstation="KC-135MPRS",
|
|
382
383
|
Extender="KC-10",
|
|
383
384
|
Orion="P-3C",
|
|
384
385
|
Viking="S-3B",
|
|
@@ -2312,15 +2313,15 @@ if string.find(type_name,"Hercules")and(unit:getDrawArgumentValue(1217)==1)then
|
|
|
2312
2313
|
BASE:T(unit_name.." side door is open")
|
|
2313
2314
|
return true
|
|
2314
2315
|
end
|
|
2315
|
-
if
|
|
2316
|
+
if type_name=="Bell-47"then
|
|
2316
2317
|
BASE:T(unit_name.." door is open")
|
|
2317
2318
|
return true
|
|
2318
2319
|
end
|
|
2319
|
-
if
|
|
2320
|
+
if type_name=="UH-60L"and(unit:getDrawArgumentValue(401)==1 or unit:getDrawArgumentValue(402)==1)then
|
|
2320
2321
|
BASE:T(unit_name.." cargo door is open")
|
|
2321
2322
|
return true
|
|
2322
2323
|
end
|
|
2323
|
-
if
|
|
2324
|
+
if type_name=="UH-60L"and(unit:getDrawArgumentValue(38)>0 or unit:getDrawArgumentValue(400)==1)then
|
|
2324
2325
|
BASE:T(unit_name.." front door(s) are open")
|
|
2325
2326
|
return true
|
|
2326
2327
|
end
|
|
@@ -9211,7 +9212,7 @@ Points={},
|
|
|
9211
9212
|
Coords={},
|
|
9212
9213
|
CenterVec2={x=0,y=0},
|
|
9213
9214
|
SurfaceArea=0,
|
|
9214
|
-
|
|
9215
|
+
DrawID={}
|
|
9215
9216
|
}
|
|
9216
9217
|
function _ZONE_TRIANGLE:New(p1,p2,p3)
|
|
9217
9218
|
local self=BASE:Inherit(self,ZONE_BASE:New())
|
|
@@ -9258,15 +9259,28 @@ if not FillAlpha then FillAlpha=1 end
|
|
|
9258
9259
|
for i=1,#self.Coords do
|
|
9259
9260
|
local c1=self.Coords[i]
|
|
9260
9261
|
local c2=self.Coords[i%#self.Coords+1]
|
|
9261
|
-
|
|
9262
|
+
local id=c1:LineToAll(c2,Coalition,Color,Alpha,LineType,ReadOnly)
|
|
9263
|
+
self.DrawID[#self.DrawID+1]=id
|
|
9262
9264
|
end
|
|
9263
|
-
|
|
9265
|
+
local newID=self.Coords[1]:MarkupToAllFreeForm({self.Coords[2],self.Coords[3]},Coalition,Color,Alpha,FillColor,FillAlpha,LineType,ReadOnly)
|
|
9266
|
+
self.DrawID[#self.DrawID+1]=newID
|
|
9267
|
+
return self.DrawID
|
|
9268
|
+
end
|
|
9269
|
+
function _ZONE_TRIANGLE:Fill(Coalition,FillColor,FillAlpha,ReadOnly)
|
|
9270
|
+
Coalition=Coalition or-1
|
|
9271
|
+
FillColor=FillColor
|
|
9272
|
+
FillAlpha=FillAlpha
|
|
9273
|
+
local newID=self.Coords[1]:MarkupToAllFreeForm({self.Coords[2],self.Coords[3]},Coalition,nil,nil,FillColor,FillAlpha,0,nil)
|
|
9274
|
+
self.DrawID[#self.DrawID+1]=newID
|
|
9275
|
+
return self.DrawID
|
|
9264
9276
|
end
|
|
9265
9277
|
ZONE_POLYGON_BASE={
|
|
9266
9278
|
ClassName="ZONE_POLYGON_BASE",
|
|
9267
9279
|
_Triangles={},
|
|
9268
9280
|
SurfaceArea=0,
|
|
9269
|
-
DrawID={}
|
|
9281
|
+
DrawID={},
|
|
9282
|
+
FillTriangles={},
|
|
9283
|
+
Borderlines={},
|
|
9270
9284
|
}
|
|
9271
9285
|
function ZONE_POLYGON_BASE:New(ZoneName,PointsArray)
|
|
9272
9286
|
local self=BASE:Inherit(self,ZONE_BASE:New(ZoneName))
|
|
@@ -9472,31 +9486,70 @@ if self._.Polygon and#self._.Polygon>=3 then
|
|
|
9472
9486
|
Coalition=Coalition or self:GetDrawCoalition()
|
|
9473
9487
|
self:SetDrawCoalition(Coalition)
|
|
9474
9488
|
Color=Color or self:GetColorRGB()
|
|
9475
|
-
Alpha=Alpha or
|
|
9476
|
-
self:SetColor(Color,Alpha)
|
|
9489
|
+
Alpha=Alpha or self:GetColorAlpha()
|
|
9477
9490
|
FillColor=FillColor or self:GetFillColorRGB()
|
|
9478
|
-
if not FillColor then
|
|
9479
|
-
UTILS.DeepCopy(Color)
|
|
9480
|
-
end
|
|
9481
9491
|
FillAlpha=FillAlpha or self:GetFillColorAlpha()
|
|
9482
|
-
if
|
|
9483
|
-
FillAlpha
|
|
9492
|
+
if FillColor then
|
|
9493
|
+
self:ReFill(FillColor,FillAlpha)
|
|
9494
|
+
end
|
|
9495
|
+
if Color then
|
|
9496
|
+
self:ReDrawBorderline(Color,Alpha,LineType)
|
|
9497
|
+
end
|
|
9498
|
+
end
|
|
9499
|
+
if false then
|
|
9500
|
+
local coords=self:GetVerticiesCoordinates()
|
|
9501
|
+
local coord=coords[1]
|
|
9502
|
+
table.remove(coords,1)
|
|
9503
|
+
coord:MarkupToAllFreeForm(coords,Coalition,Color,Alpha,FillColor,FillAlpha,LineType,ReadOnly,"Drew Polygon")
|
|
9504
|
+
if true then
|
|
9505
|
+
return
|
|
9506
|
+
end
|
|
9507
|
+
end
|
|
9508
|
+
return self
|
|
9509
|
+
end
|
|
9510
|
+
function ZONE_POLYGON_BASE:ReFill(Color,Alpha)
|
|
9511
|
+
local color=Color or self:GetFillColorRGB()or{1,0,0}
|
|
9512
|
+
local alpha=Alpha or self:GetFillColorAlpha()or 1
|
|
9513
|
+
local coalition=self:GetDrawCoalition()or-1
|
|
9514
|
+
if#self.FillTriangles>0 then
|
|
9515
|
+
for _,triangle in pairs(self._Triangles)do
|
|
9516
|
+
triangle:UndrawZone()
|
|
9517
|
+
end
|
|
9518
|
+
for _,_value in pairs(self.FillTriangles)do
|
|
9519
|
+
table.remove_by_value(self.DrawID,_value)
|
|
9520
|
+
end
|
|
9521
|
+
self.FillTriangles=nil
|
|
9522
|
+
self.FillTriangles={}
|
|
9484
9523
|
end
|
|
9485
|
-
self:SetFillColor(FillColor,FillAlpha)
|
|
9486
|
-
IncludeTriangles=IncludeTriangles or false
|
|
9487
|
-
if IncludeTriangles then
|
|
9488
9524
|
for _,triangle in pairs(self._Triangles)do
|
|
9489
|
-
local draw_ids=triangle:
|
|
9525
|
+
local draw_ids=triangle:Fill(coalition,color,alpha,nil)
|
|
9526
|
+
self.FillTriangles=draw_ids
|
|
9490
9527
|
table.combine(self.DrawID,draw_ids)
|
|
9491
9528
|
end
|
|
9492
|
-
|
|
9529
|
+
return self
|
|
9530
|
+
end
|
|
9531
|
+
function ZONE_POLYGON_BASE:ReDrawBorderline(Color,Alpha,LineType)
|
|
9532
|
+
local color=Color or self:GetFillColorRGB()or{1,0,0}
|
|
9533
|
+
local alpha=Alpha or self:GetFillColorAlpha()or 1
|
|
9534
|
+
local coalition=self:GetDrawCoalition()or-1
|
|
9535
|
+
local linetype=LineType or 1
|
|
9536
|
+
if#self.Borderlines>0 then
|
|
9537
|
+
for _,MarkID in pairs(self.Borderlines)do
|
|
9538
|
+
trigger.action.removeMark(MarkID)
|
|
9539
|
+
end
|
|
9540
|
+
for _,_value in pairs(self.Borderlines)do
|
|
9541
|
+
table.remove_by_value(self.DrawID,_value)
|
|
9542
|
+
end
|
|
9543
|
+
self.Borderlines=nil
|
|
9544
|
+
self.Borderlines={}
|
|
9545
|
+
end
|
|
9493
9546
|
local coords=self:GetVerticiesCoordinates()
|
|
9494
9547
|
for i=1,#coords do
|
|
9495
9548
|
local c1=coords[i]
|
|
9496
9549
|
local c2=coords[i%#coords+1]
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9550
|
+
local newID=c1:LineToAll(c2,coalition,color,alpha,linetype,nil)
|
|
9551
|
+
self.DrawID[#self.DrawID+1]=newID
|
|
9552
|
+
self.Borderlines[#self.Borderlines+1]=newID
|
|
9500
9553
|
end
|
|
9501
9554
|
return self
|
|
9502
9555
|
end
|
|
@@ -9679,6 +9732,7 @@ Radius=Radius or 1000
|
|
|
9679
9732
|
Alpha=Alpha or 1
|
|
9680
9733
|
Segments=Segments or 10
|
|
9681
9734
|
Closed=Closed or false
|
|
9735
|
+
local Limit
|
|
9682
9736
|
local i=1
|
|
9683
9737
|
local j=#self._.Polygon
|
|
9684
9738
|
if(Closed)then
|
|
@@ -10508,6 +10562,23 @@ table.remove(points,#points)
|
|
|
10508
10562
|
self:I(string.format("Register ZONE: %s (Polygon (free) drawing with %d vertices)",ZoneName,#points))
|
|
10509
10563
|
local Zone=ZONE_POLYGON:NewFromPointsArray(ZoneName,points)
|
|
10510
10564
|
Zone:SetColor({1,0,0},0.15)
|
|
10565
|
+
Zone:SetFillColor({1,0,0},0.15)
|
|
10566
|
+
if objectData.colorString then
|
|
10567
|
+
local color=string.gsub(objectData.colorString,"^0x","")
|
|
10568
|
+
local r=tonumber(string.sub(color,1,2),16)/255
|
|
10569
|
+
local g=tonumber(string.sub(color,3,4),16)/255
|
|
10570
|
+
local b=tonumber(string.sub(color,5,6),16)/255
|
|
10571
|
+
local a=tonumber(string.sub(color,7,8),16)/255
|
|
10572
|
+
Zone:SetColor({r,g,b},a)
|
|
10573
|
+
end
|
|
10574
|
+
if objectData.fillColorString then
|
|
10575
|
+
local color=string.gsub(objectData.colorString,"^0x","")
|
|
10576
|
+
local r=tonumber(string.sub(color,1,2),16)/255
|
|
10577
|
+
local g=tonumber(string.sub(color,3,4),16)/255
|
|
10578
|
+
local b=tonumber(string.sub(color,5,6),16)/255
|
|
10579
|
+
local a=tonumber(string.sub(color,7,8),16)/255
|
|
10580
|
+
Zone:SetFillColor({r,g,b},a)
|
|
10581
|
+
end
|
|
10511
10582
|
self.ZONENAMES[ZoneName]=ZoneName
|
|
10512
10583
|
self:AddZone(ZoneName,Zone)
|
|
10513
10584
|
elseif objectData.polygonMode and objectData.polygonMode=="rect"then
|
|
@@ -10523,6 +10594,22 @@ points[4]={x=vec2.x-h/2,y=vec2.y-w/2}
|
|
|
10523
10594
|
self:I(string.format("Register ZONE: %s (Polygon (rect) drawing with %d vertices)",ZoneName,#points))
|
|
10524
10595
|
local Zone=ZONE_POLYGON:NewFromPointsArray(ZoneName,points)
|
|
10525
10596
|
Zone:SetColor({1,0,0},0.15)
|
|
10597
|
+
if objectData.colorString then
|
|
10598
|
+
local color=string.gsub(objectData.colorString,"^0x","")
|
|
10599
|
+
local r=tonumber(string.sub(color,1,2),16)/255
|
|
10600
|
+
local g=tonumber(string.sub(color,3,4),16)/255
|
|
10601
|
+
local b=tonumber(string.sub(color,5,6),16)/255
|
|
10602
|
+
local a=tonumber(string.sub(color,7,8),16)/255
|
|
10603
|
+
Zone:SetColor({r,g,b},a)
|
|
10604
|
+
end
|
|
10605
|
+
if objectData.fillColorString then
|
|
10606
|
+
local color=string.gsub(objectData.colorString,"^0x","")
|
|
10607
|
+
local r=tonumber(string.sub(color,1,2),16)/255
|
|
10608
|
+
local g=tonumber(string.sub(color,3,4),16)/255
|
|
10609
|
+
local b=tonumber(string.sub(color,5,6),16)/255
|
|
10610
|
+
local a=tonumber(string.sub(color,7,8),16)/255
|
|
10611
|
+
Zone:SetFillColor({r,g,b},a)
|
|
10612
|
+
end
|
|
10526
10613
|
self.ZONENAMES[ZoneName]=ZoneName
|
|
10527
10614
|
self:AddZone(ZoneName,Zone)
|
|
10528
10615
|
elseif objectData.lineMode and(objectData.lineMode=="segments"or objectData.lineMode=="segment"or objectData.lineMode=="free")and objectData.points and#objectData.points>=2 then
|
|
@@ -11328,6 +11415,26 @@ self.CallScheduler=SCHEDULER:New(self)
|
|
|
11328
11415
|
self:SetEventPriority(2)
|
|
11329
11416
|
return self
|
|
11330
11417
|
end
|
|
11418
|
+
function SET_BASE:FilterFunction(ConditionFunction,...)
|
|
11419
|
+
local condition={}
|
|
11420
|
+
condition.func=ConditionFunction
|
|
11421
|
+
condition.arg={}
|
|
11422
|
+
if arg then
|
|
11423
|
+
condition.arg=arg
|
|
11424
|
+
end
|
|
11425
|
+
if not self.Filter.Functions then self.Filter.Functions={}end
|
|
11426
|
+
table.insert(self.Filter.Functions,condition)
|
|
11427
|
+
return self
|
|
11428
|
+
end
|
|
11429
|
+
function SET_BASE:_EvalFilterFunctions(Object)
|
|
11430
|
+
for _,_condition in pairs(self.Filter.Functions or{})do
|
|
11431
|
+
local condition=_condition
|
|
11432
|
+
if condition.func(Object,unpack(condition.arg))==false then
|
|
11433
|
+
return false
|
|
11434
|
+
end
|
|
11435
|
+
end
|
|
11436
|
+
return true
|
|
11437
|
+
end
|
|
11331
11438
|
function SET_BASE:Clear(TriggerEvent)
|
|
11332
11439
|
for Name,Object in pairs(self.Set)do
|
|
11333
11440
|
self:Remove(Name,not TriggerEvent)
|
|
@@ -11691,6 +11798,7 @@ Categories=nil,
|
|
|
11691
11798
|
Countries=nil,
|
|
11692
11799
|
GroupPrefixes=nil,
|
|
11693
11800
|
Zones=nil,
|
|
11801
|
+
Functions=nil,
|
|
11694
11802
|
},
|
|
11695
11803
|
FilterMeta={
|
|
11696
11804
|
Coalitions={
|
|
@@ -12140,7 +12248,7 @@ MGroupActive=true
|
|
|
12140
12248
|
end
|
|
12141
12249
|
MGroupInclude=MGroupInclude and MGroupActive
|
|
12142
12250
|
end
|
|
12143
|
-
if self.Filter.Coalitions then
|
|
12251
|
+
if self.Filter.Coalitions and MGroupInclude then
|
|
12144
12252
|
local MGroupCoalition=false
|
|
12145
12253
|
for CoalitionID,CoalitionName in pairs(self.Filter.Coalitions)do
|
|
12146
12254
|
self:T3({"Coalition:",MGroup:GetCoalition(),self.FilterMeta.Coalitions[CoalitionName],CoalitionName})
|
|
@@ -12150,7 +12258,7 @@ end
|
|
|
12150
12258
|
end
|
|
12151
12259
|
MGroupInclude=MGroupInclude and MGroupCoalition
|
|
12152
12260
|
end
|
|
12153
|
-
if self.Filter.Categories then
|
|
12261
|
+
if self.Filter.Categories and MGroupInclude then
|
|
12154
12262
|
local MGroupCategory=false
|
|
12155
12263
|
for CategoryID,CategoryName in pairs(self.Filter.Categories)do
|
|
12156
12264
|
self:T3({"Category:",MGroup:GetCategory(),self.FilterMeta.Categories[CategoryName],CategoryName})
|
|
@@ -12160,7 +12268,7 @@ end
|
|
|
12160
12268
|
end
|
|
12161
12269
|
MGroupInclude=MGroupInclude and MGroupCategory
|
|
12162
12270
|
end
|
|
12163
|
-
if self.Filter.Countries then
|
|
12271
|
+
if self.Filter.Countries and MGroupInclude then
|
|
12164
12272
|
local MGroupCountry=false
|
|
12165
12273
|
for CountryID,CountryName in pairs(self.Filter.Countries)do
|
|
12166
12274
|
self:T3({"Country:",MGroup:GetCountry(),CountryName})
|
|
@@ -12170,7 +12278,7 @@ end
|
|
|
12170
12278
|
end
|
|
12171
12279
|
MGroupInclude=MGroupInclude and MGroupCountry
|
|
12172
12280
|
end
|
|
12173
|
-
if self.Filter.GroupPrefixes then
|
|
12281
|
+
if self.Filter.GroupPrefixes and MGroupInclude then
|
|
12174
12282
|
local MGroupPrefix=false
|
|
12175
12283
|
for GroupPrefixId,GroupPrefix in pairs(self.Filter.GroupPrefixes)do
|
|
12176
12284
|
self:T3({"Prefix:",string.find(MGroup:GetName(),GroupPrefix,1),GroupPrefix})
|
|
@@ -12180,7 +12288,7 @@ end
|
|
|
12180
12288
|
end
|
|
12181
12289
|
MGroupInclude=MGroupInclude and MGroupPrefix
|
|
12182
12290
|
end
|
|
12183
|
-
if self.Filter.Zones then
|
|
12291
|
+
if self.Filter.Zones and MGroupInclude then
|
|
12184
12292
|
local MGroupZone=false
|
|
12185
12293
|
for ZoneName,Zone in pairs(self.Filter.Zones)do
|
|
12186
12294
|
if MGroup:IsInZone(Zone)then
|
|
@@ -12189,6 +12297,11 @@ end
|
|
|
12189
12297
|
end
|
|
12190
12298
|
MGroupInclude=MGroupInclude and MGroupZone
|
|
12191
12299
|
end
|
|
12300
|
+
if self.Filter.Functions and MGroupInclude then
|
|
12301
|
+
local MGroupFunc=false
|
|
12302
|
+
MGroupFunc=self:_EvalFilterFunctions(MGroup)
|
|
12303
|
+
MGroupInclude=MGroupInclude and MGroupFunc
|
|
12304
|
+
end
|
|
12192
12305
|
self:T2(MGroupInclude)
|
|
12193
12306
|
return MGroupInclude
|
|
12194
12307
|
end
|
|
@@ -12229,6 +12342,7 @@ Types=nil,
|
|
|
12229
12342
|
Countries=nil,
|
|
12230
12343
|
UnitPrefixes=nil,
|
|
12231
12344
|
Zones=nil,
|
|
12345
|
+
Functions=nil,
|
|
12232
12346
|
},
|
|
12233
12347
|
FilterMeta={
|
|
12234
12348
|
Coalitions={
|
|
@@ -12770,7 +12884,7 @@ MUnitActive=true
|
|
|
12770
12884
|
end
|
|
12771
12885
|
MUnitInclude=MUnitInclude and MUnitActive
|
|
12772
12886
|
end
|
|
12773
|
-
if self.Filter.Coalitions then
|
|
12887
|
+
if self.Filter.Coalitions and MUnitInclude then
|
|
12774
12888
|
local MUnitCoalition=false
|
|
12775
12889
|
for CoalitionID,CoalitionName in pairs(self.Filter.Coalitions)do
|
|
12776
12890
|
self:F({"Coalition:",MUnit:GetCoalition(),self.FilterMeta.Coalitions[CoalitionName],CoalitionName})
|
|
@@ -12780,7 +12894,7 @@ end
|
|
|
12780
12894
|
end
|
|
12781
12895
|
MUnitInclude=MUnitInclude and MUnitCoalition
|
|
12782
12896
|
end
|
|
12783
|
-
if self.Filter.Categories then
|
|
12897
|
+
if self.Filter.Categories and MUnitInclude then
|
|
12784
12898
|
local MUnitCategory=false
|
|
12785
12899
|
for CategoryID,CategoryName in pairs(self.Filter.Categories)do
|
|
12786
12900
|
self:T3({"Category:",MUnit:GetDesc().category,self.FilterMeta.Categories[CategoryName],CategoryName})
|
|
@@ -12790,7 +12904,7 @@ end
|
|
|
12790
12904
|
end
|
|
12791
12905
|
MUnitInclude=MUnitInclude and MUnitCategory
|
|
12792
12906
|
end
|
|
12793
|
-
if self.Filter.Types then
|
|
12907
|
+
if self.Filter.Types and MUnitInclude then
|
|
12794
12908
|
local MUnitType=false
|
|
12795
12909
|
for TypeID,TypeName in pairs(self.Filter.Types)do
|
|
12796
12910
|
self:T3({"Type:",MUnit:GetTypeName(),TypeName})
|
|
@@ -12800,7 +12914,7 @@ end
|
|
|
12800
12914
|
end
|
|
12801
12915
|
MUnitInclude=MUnitInclude and MUnitType
|
|
12802
12916
|
end
|
|
12803
|
-
if self.Filter.Countries then
|
|
12917
|
+
if self.Filter.Countries and MUnitInclude then
|
|
12804
12918
|
local MUnitCountry=false
|
|
12805
12919
|
for CountryID,CountryName in pairs(self.Filter.Countries)do
|
|
12806
12920
|
self:T3({"Country:",MUnit:GetCountry(),CountryName})
|
|
@@ -12810,7 +12924,7 @@ end
|
|
|
12810
12924
|
end
|
|
12811
12925
|
MUnitInclude=MUnitInclude and MUnitCountry
|
|
12812
12926
|
end
|
|
12813
|
-
if self.Filter.UnitPrefixes then
|
|
12927
|
+
if self.Filter.UnitPrefixes and MUnitInclude then
|
|
12814
12928
|
local MUnitPrefix=false
|
|
12815
12929
|
for UnitPrefixId,UnitPrefix in pairs(self.Filter.UnitPrefixes)do
|
|
12816
12930
|
self:T3({"Prefix:",string.find(MUnit:GetName(),UnitPrefix,1),UnitPrefix})
|
|
@@ -12820,7 +12934,7 @@ end
|
|
|
12820
12934
|
end
|
|
12821
12935
|
MUnitInclude=MUnitInclude and MUnitPrefix
|
|
12822
12936
|
end
|
|
12823
|
-
if self.Filter.RadarTypes then
|
|
12937
|
+
if self.Filter.RadarTypes and MUnitInclude then
|
|
12824
12938
|
local MUnitRadar=false
|
|
12825
12939
|
for RadarTypeID,RadarType in pairs(self.Filter.RadarTypes)do
|
|
12826
12940
|
self:T3({"Radar:",RadarType})
|
|
@@ -12833,7 +12947,7 @@ end
|
|
|
12833
12947
|
end
|
|
12834
12948
|
MUnitInclude=MUnitInclude and MUnitRadar
|
|
12835
12949
|
end
|
|
12836
|
-
if self.Filter.SEAD then
|
|
12950
|
+
if self.Filter.SEAD and MUnitInclude then
|
|
12837
12951
|
local MUnitSEAD=false
|
|
12838
12952
|
if MUnit:HasSEAD()==true then
|
|
12839
12953
|
self:T3("SEAD Found")
|
|
@@ -12842,7 +12956,7 @@ end
|
|
|
12842
12956
|
MUnitInclude=MUnitInclude and MUnitSEAD
|
|
12843
12957
|
end
|
|
12844
12958
|
end
|
|
12845
|
-
if self.Filter.Zones then
|
|
12959
|
+
if self.Filter.Zones and MUnitInclude then
|
|
12846
12960
|
local MGroupZone=false
|
|
12847
12961
|
for ZoneName,Zone in pairs(self.Filter.Zones)do
|
|
12848
12962
|
self:T3("Zone:",ZoneName)
|
|
@@ -12852,6 +12966,10 @@ end
|
|
|
12852
12966
|
end
|
|
12853
12967
|
MUnitInclude=MUnitInclude and MGroupZone
|
|
12854
12968
|
end
|
|
12969
|
+
if self.Filter.Functions and MUnitInclude then
|
|
12970
|
+
local MUnitFunc=self:_EvalFilterFunctions(MUnit)
|
|
12971
|
+
MUnitInclude=MUnitInclude and MUnitFunc
|
|
12972
|
+
end
|
|
12855
12973
|
self:T2(MUnitInclude)
|
|
12856
12974
|
return MUnitInclude
|
|
12857
12975
|
end
|
|
@@ -13602,7 +13720,7 @@ MClientActive=true
|
|
|
13602
13720
|
end
|
|
13603
13721
|
MClientInclude=MClientInclude and MClientActive
|
|
13604
13722
|
end
|
|
13605
|
-
if self.Filter.Coalitions then
|
|
13723
|
+
if self.Filter.Coalitions and MClientInclude then
|
|
13606
13724
|
local MClientCoalition=false
|
|
13607
13725
|
for CoalitionID,CoalitionName in pairs(self.Filter.Coalitions)do
|
|
13608
13726
|
local ClientCoalitionID=_DATABASE:GetCoalitionFromClientTemplate(MClientName)
|
|
@@ -13614,7 +13732,7 @@ end
|
|
|
13614
13732
|
self:T({"Evaluated Coalition",MClientCoalition})
|
|
13615
13733
|
MClientInclude=MClientInclude and MClientCoalition
|
|
13616
13734
|
end
|
|
13617
|
-
if self.Filter.Categories then
|
|
13735
|
+
if self.Filter.Categories and MClientInclude then
|
|
13618
13736
|
local MClientCategory=false
|
|
13619
13737
|
for CategoryID,CategoryName in pairs(self.Filter.Categories)do
|
|
13620
13738
|
local ClientCategoryID=_DATABASE:GetCategoryFromClientTemplate(MClientName)
|
|
@@ -13626,7 +13744,7 @@ end
|
|
|
13626
13744
|
self:T({"Evaluated Category",MClientCategory})
|
|
13627
13745
|
MClientInclude=MClientInclude and MClientCategory
|
|
13628
13746
|
end
|
|
13629
|
-
if self.Filter.Types then
|
|
13747
|
+
if self.Filter.Types and MClientInclude then
|
|
13630
13748
|
local MClientType=false
|
|
13631
13749
|
for TypeID,TypeName in pairs(self.Filter.Types)do
|
|
13632
13750
|
self:T3({"Type:",MClient:GetTypeName(),TypeName})
|
|
@@ -13637,7 +13755,7 @@ end
|
|
|
13637
13755
|
self:T({"Evaluated Type",MClientType})
|
|
13638
13756
|
MClientInclude=MClientInclude and MClientType
|
|
13639
13757
|
end
|
|
13640
|
-
if self.Filter.Countries then
|
|
13758
|
+
if self.Filter.Countries and MClientInclude then
|
|
13641
13759
|
local MClientCountry=false
|
|
13642
13760
|
for CountryID,CountryName in pairs(self.Filter.Countries)do
|
|
13643
13761
|
local ClientCountryID=_DATABASE:GetCountryFromClientTemplate(MClientName)
|
|
@@ -13649,7 +13767,7 @@ end
|
|
|
13649
13767
|
self:T({"Evaluated Country",MClientCountry})
|
|
13650
13768
|
MClientInclude=MClientInclude and MClientCountry
|
|
13651
13769
|
end
|
|
13652
|
-
if self.Filter.ClientPrefixes then
|
|
13770
|
+
if self.Filter.ClientPrefixes and MClientInclude then
|
|
13653
13771
|
local MClientPrefix=false
|
|
13654
13772
|
for ClientPrefixId,ClientPrefix in pairs(self.Filter.ClientPrefixes)do
|
|
13655
13773
|
self:T3({"Prefix:",string.find(MClient.UnitName,ClientPrefix,1),ClientPrefix})
|
|
@@ -13660,7 +13778,7 @@ end
|
|
|
13660
13778
|
self:T({"Evaluated Prefix",MClientPrefix})
|
|
13661
13779
|
MClientInclude=MClientInclude and MClientPrefix
|
|
13662
13780
|
end
|
|
13663
|
-
if self.Filter.Zones then
|
|
13781
|
+
if self.Filter.Zones and MClientInclude then
|
|
13664
13782
|
local MClientZone=false
|
|
13665
13783
|
for ZoneName,Zone in pairs(self.Filter.Zones)do
|
|
13666
13784
|
self:T3("Zone:",ZoneName)
|
|
@@ -13671,7 +13789,7 @@ end
|
|
|
13671
13789
|
end
|
|
13672
13790
|
MClientInclude=MClientInclude and MClientZone
|
|
13673
13791
|
end
|
|
13674
|
-
if self.Filter.Playernames then
|
|
13792
|
+
if self.Filter.Playernames and MClientInclude then
|
|
13675
13793
|
local MClientPlayername=false
|
|
13676
13794
|
local playername=MClient:GetPlayerName()or"Unknown"
|
|
13677
13795
|
for _,_Playername in pairs(self.Filter.Playernames)do
|
|
@@ -13682,7 +13800,7 @@ end
|
|
|
13682
13800
|
self:T({"Evaluated Playername",MClientPlayername})
|
|
13683
13801
|
MClientInclude=MClientInclude and MClientPlayername
|
|
13684
13802
|
end
|
|
13685
|
-
if self.Filter.Callsigns then
|
|
13803
|
+
if self.Filter.Callsigns and MClientInclude then
|
|
13686
13804
|
local MClientCallsigns=false
|
|
13687
13805
|
local callsign=MClient:GetCallsign()
|
|
13688
13806
|
for _,_Callsign in pairs(self.Filter.Callsigns)do
|
|
@@ -13693,6 +13811,10 @@ end
|
|
|
13693
13811
|
self:T({"Evaluated Callsign",MClientCallsigns})
|
|
13694
13812
|
MClientInclude=MClientInclude and MClientCallsigns
|
|
13695
13813
|
end
|
|
13814
|
+
if self.Filter.Functions and MClientInclude then
|
|
13815
|
+
local MClientFunc=self:_EvalFilterFunctions(MClient)
|
|
13816
|
+
MClientInclude=MClientInclude and MClientFunc
|
|
13817
|
+
end
|
|
13696
13818
|
end
|
|
13697
13819
|
self:T2(MClientInclude)
|
|
13698
13820
|
return MClientInclude
|
|
@@ -14012,7 +14134,6 @@ return AirbaseFound
|
|
|
14012
14134
|
end
|
|
14013
14135
|
function SET_AIRBASE:GetRandomAirbase()
|
|
14014
14136
|
local RandomAirbase=self:GetRandom()
|
|
14015
|
-
self:F({RandomAirbase=RandomAirbase:GetName()})
|
|
14016
14137
|
return RandomAirbase
|
|
14017
14138
|
end
|
|
14018
14139
|
function SET_AIRBASE:FilterCoalitions(Coalitions)
|
|
@@ -14102,7 +14223,7 @@ end
|
|
|
14102
14223
|
self:T({"Evaluated Coalition",MAirbaseCoalition})
|
|
14103
14224
|
MAirbaseInclude=MAirbaseInclude and MAirbaseCoalition
|
|
14104
14225
|
end
|
|
14105
|
-
if self.Filter.Categories then
|
|
14226
|
+
if self.Filter.Categories and MAirbaseInclude then
|
|
14106
14227
|
local MAirbaseCategory=false
|
|
14107
14228
|
for CategoryID,CategoryName in pairs(self.Filter.Categories)do
|
|
14108
14229
|
local AirbaseCategoryID=_DATABASE:GetCategoryFromAirbase(MAirbaseName)
|
|
@@ -15185,7 +15306,7 @@ MGroupActive=true
|
|
|
15185
15306
|
end
|
|
15186
15307
|
MGroupInclude=MGroupInclude and MGroupActive
|
|
15187
15308
|
end
|
|
15188
|
-
if self.Filter.Coalitions then
|
|
15309
|
+
if self.Filter.Coalitions and MGroupInclude then
|
|
15189
15310
|
local MGroupCoalition=false
|
|
15190
15311
|
for CoalitionID,CoalitionName in pairs(self.Filter.Coalitions)do
|
|
15191
15312
|
if self.FilterMeta.Coalitions[CoalitionName]and self.FilterMeta.Coalitions[CoalitionName]==MGroup:GetCoalition()then
|
|
@@ -15194,7 +15315,7 @@ end
|
|
|
15194
15315
|
end
|
|
15195
15316
|
MGroupInclude=MGroupInclude and MGroupCoalition
|
|
15196
15317
|
end
|
|
15197
|
-
if self.Filter.Categories then
|
|
15318
|
+
if self.Filter.Categories and MGroupInclude then
|
|
15198
15319
|
local MGroupCategory=false
|
|
15199
15320
|
for CategoryID,CategoryName in pairs(self.Filter.Categories)do
|
|
15200
15321
|
if self.FilterMeta.Categories[CategoryName]and self.FilterMeta.Categories[CategoryName]==MGroup:GetCategory()then
|
|
@@ -15203,7 +15324,7 @@ end
|
|
|
15203
15324
|
end
|
|
15204
15325
|
MGroupInclude=MGroupInclude and MGroupCategory
|
|
15205
15326
|
end
|
|
15206
|
-
if self.Filter.Countries then
|
|
15327
|
+
if self.Filter.Countries and MGroupInclude then
|
|
15207
15328
|
local MGroupCountry=false
|
|
15208
15329
|
for CountryID,CountryName in pairs(self.Filter.Countries)do
|
|
15209
15330
|
if country.id[CountryName]==MGroup:GetCountry()then
|
|
@@ -15212,7 +15333,7 @@ end
|
|
|
15212
15333
|
end
|
|
15213
15334
|
MGroupInclude=MGroupInclude and MGroupCountry
|
|
15214
15335
|
end
|
|
15215
|
-
if self.Filter.GroupPrefixes then
|
|
15336
|
+
if self.Filter.GroupPrefixes and MGroupInclude then
|
|
15216
15337
|
local MGroupPrefix=false
|
|
15217
15338
|
for GroupPrefixId,GroupPrefix in pairs(self.Filter.GroupPrefixes)do
|
|
15218
15339
|
if string.find(MGroup:GetName(),GroupPrefix:gsub("-","%%-"),1)then
|
|
@@ -16578,11 +16699,14 @@ Color,FillColor,LineType,ReadOnly,Text or"")
|
|
|
16578
16699
|
else
|
|
16579
16700
|
local s=string.format("trigger.action.markupToAll(7, %d, %d,",Coalition,MarkID)
|
|
16580
16701
|
for _,vec in pairs(vecs)do
|
|
16581
|
-
s=s..string.format("
|
|
16702
|
+
s=s..string.format("{x=%.1f, y=%.1f, z=%.1f},",vec.x,vec.y,vec.z)
|
|
16582
16703
|
end
|
|
16583
|
-
s=s..string.format("
|
|
16584
|
-
|
|
16585
|
-
s=s..string.format(",
|
|
16704
|
+
s=s..string.format("{%.3f, %.3f, %.3f, %.3f},",Color[1],Color[2],Color[3],Color[4])
|
|
16705
|
+
s=s..string.format("{%.3f, %.3f, %.3f, %.3f},",FillColor[1],FillColor[2],FillColor[3],FillColor[4])
|
|
16706
|
+
s=s..string.format("%d,",LineType or 1)
|
|
16707
|
+
s=s..string.format("%s",tostring(ReadOnly))
|
|
16708
|
+
if Text and type(Text)=="string"and string.len(Text)>0 then
|
|
16709
|
+
s=s..string.format(", \"%s\"",tostring(Text))
|
|
16586
16710
|
end
|
|
16587
16711
|
s=s..")"
|
|
16588
16712
|
local success=UTILS.DoString(s)
|
|
@@ -16892,6 +17016,36 @@ local lat,lon=coord.LOtoLL(self:GetVec3())
|
|
|
16892
17016
|
local MGRS=coord.LLtoMGRS(lat,lon)
|
|
16893
17017
|
return"MGRS "..UTILS.tostringMGRS(MGRS,MGRS_Accuracy)
|
|
16894
17018
|
end
|
|
17019
|
+
function COORDINATE:NewFromMGRSString(MGRSString)
|
|
17020
|
+
local myparts=UTILS.Split(MGRSString," ")
|
|
17021
|
+
local northing=tostring(myparts[5])or""
|
|
17022
|
+
local easting=tostring(myparts[4])or""
|
|
17023
|
+
if string.len(easting)<5 then easting=easting..string.rep("0",5-string.len(easting))end
|
|
17024
|
+
if string.len(northing)<5 then northing=northing..string.rep("0",5-string.len(northing))end
|
|
17025
|
+
local MGRS={
|
|
17026
|
+
UTMZone=myparts[2],
|
|
17027
|
+
MGRSDigraph=myparts[3],
|
|
17028
|
+
Easting=easting,
|
|
17029
|
+
Northing=northing,
|
|
17030
|
+
}
|
|
17031
|
+
local lat,lon=coord.MGRStoLL(MGRS)
|
|
17032
|
+
local point=coord.LLtoLO(lat,lon,0)
|
|
17033
|
+
local coord=COORDINATE:NewFromVec2({x=point.x,y=point.z})
|
|
17034
|
+
return coord
|
|
17035
|
+
end
|
|
17036
|
+
function COORDINATE:NewFromMGRS(UTMZone,MGRSDigraph,Easting,Northing)
|
|
17037
|
+
if string.len(Easting)<5 then Easting=Easting..string.rep("0",5-string.len(Easting))end
|
|
17038
|
+
if string.len(Northing)<5 then Northing=Northing..string.rep("0",5-string.len(Northing))end
|
|
17039
|
+
local MGRS={
|
|
17040
|
+
UTMZone=UTMZone,
|
|
17041
|
+
MGRSDigraph=MGRSDigraph,
|
|
17042
|
+
Easting=Easting,
|
|
17043
|
+
Northing=Northing,
|
|
17044
|
+
}
|
|
17045
|
+
local lat,lon=coord.MGRStoLL(MGRS)
|
|
17046
|
+
local point=coord.LLtoLO(lat,lon,0)
|
|
17047
|
+
local coord=COORDINATE:NewFromVec2({x=point.x,y=point.z})
|
|
17048
|
+
end
|
|
16895
17049
|
function COORDINATE:ToStringFromRP(ReferenceCoord,ReferenceName,Controllable,Settings,MagVar)
|
|
16896
17050
|
self:F2({ReferenceCoord=ReferenceCoord,ReferenceName=ReferenceName})
|
|
16897
17051
|
local Settings=Settings or(Controllable and _DATABASE:GetPlayerSettings(Controllable:GetPlayerName()))or _SETTINGS
|
|
@@ -17479,7 +17633,6 @@ _MESSAGESRS.Culture=Culture or"en-GB"
|
|
|
17479
17633
|
_MESSAGESRS.MSRS:SetGender(Gender)
|
|
17480
17634
|
_MESSAGESRS.Gender=Gender or"female"
|
|
17481
17635
|
_MESSAGESRS.MSRS:SetGoogle(PathToCredentials)
|
|
17482
|
-
_MESSAGESRS.google=PathToCredentials
|
|
17483
17636
|
_MESSAGESRS.MSRS:SetLabel(Label or"MESSAGE")
|
|
17484
17637
|
_MESSAGESRS.label=Label or"MESSAGE"
|
|
17485
17638
|
_MESSAGESRS.MSRS:SetPort(Port or 5002)
|
|
@@ -23815,32 +23968,35 @@ self:SetOption(AI.Option.Air.id.PROHIBIT_AB,Prohibit)
|
|
|
23815
23968
|
end
|
|
23816
23969
|
return self
|
|
23817
23970
|
end
|
|
23818
|
-
function CONTROLLABLE:
|
|
23971
|
+
function CONTROLLABLE:OptionECM(ECMvalue)
|
|
23819
23972
|
self:F2({self.ControllableName})
|
|
23973
|
+
local DCSControllable=self:GetDCSObject()
|
|
23974
|
+
if DCSControllable then
|
|
23975
|
+
local Controller=self:_GetController()
|
|
23820
23976
|
if self:IsAir()then
|
|
23821
|
-
|
|
23977
|
+
Controller:setOption(AI.Option.Air.id.ECM_USING,ECMvalue or 1)
|
|
23978
|
+
end
|
|
23822
23979
|
end
|
|
23823
23980
|
return self
|
|
23824
23981
|
end
|
|
23825
|
-
function CONTROLLABLE:
|
|
23982
|
+
function CONTROLLABLE:OptionECM_Never()
|
|
23826
23983
|
self:F2({self.ControllableName})
|
|
23827
|
-
|
|
23828
|
-
self
|
|
23984
|
+
self:OptionECM(0)
|
|
23985
|
+
return self
|
|
23829
23986
|
end
|
|
23987
|
+
function CONTROLLABLE:OptionECM_OnlyLockByRadar()
|
|
23988
|
+
self:F2({self.ControllableName})
|
|
23989
|
+
self:OptionECM(1)
|
|
23830
23990
|
return self
|
|
23831
23991
|
end
|
|
23832
23992
|
function CONTROLLABLE:OptionECM_DetectedLockByRadar()
|
|
23833
23993
|
self:F2({self.ControllableName})
|
|
23834
|
-
|
|
23835
|
-
self:SetOption(AI.Option.Air.id.ECM_USING,2)
|
|
23836
|
-
end
|
|
23994
|
+
self:OptionECM(2)
|
|
23837
23995
|
return self
|
|
23838
23996
|
end
|
|
23839
23997
|
function CONTROLLABLE:OptionECM_AlwaysOn()
|
|
23840
23998
|
self:F2({self.ControllableName})
|
|
23841
|
-
|
|
23842
|
-
self:SetOption(AI.Option.Air.id.ECM_USING,3)
|
|
23843
|
-
end
|
|
23999
|
+
self:OptionECM(3)
|
|
23844
24000
|
return self
|
|
23845
24001
|
end
|
|
23846
24002
|
function CONTROLLABLE:WayPointInitialize(WayPoints)
|
|
@@ -23949,12 +24105,19 @@ return self
|
|
|
23949
24105
|
end
|
|
23950
24106
|
return nil
|
|
23951
24107
|
end
|
|
23952
|
-
function CONTROLLABLE:RelocateGroundRandomInRadius(speed,radius,onroad,shortcut,formation)
|
|
24108
|
+
function CONTROLLABLE:RelocateGroundRandomInRadius(speed,radius,onroad,shortcut,formation,onland)
|
|
23953
24109
|
self:F2({self.ControllableName})
|
|
23954
24110
|
local _coord=self:GetCoordinate()
|
|
23955
24111
|
local _radius=radius or 500
|
|
23956
24112
|
local _speed=speed or 20
|
|
23957
24113
|
local _tocoord=_coord:GetRandomCoordinateInRadius(_radius,100)
|
|
24114
|
+
if onland then
|
|
24115
|
+
for i=1,50 do
|
|
24116
|
+
local island=_tocoord:GetSurfaceType()==land.SurfaceType.LAND and true or false
|
|
24117
|
+
if island then break end
|
|
24118
|
+
_tocoord=_coord:GetRandomCoordinateInRadius(_radius,100)
|
|
24119
|
+
end
|
|
24120
|
+
end
|
|
23958
24121
|
local _onroad=onroad or true
|
|
23959
24122
|
local _grptsk={}
|
|
23960
24123
|
local _candoroad=false
|
|
@@ -24858,7 +25021,7 @@ local Task={
|
|
|
24858
25021
|
table.insert(TaskAerobatics.params["maneuversSequency"],Task)
|
|
24859
25022
|
return TaskAerobatics
|
|
24860
25023
|
end
|
|
24861
|
-
function CONTROLLABLE:PatrolRaceTrack(Point1,Point2,Altitude,Speed,Formation,Delay)
|
|
25024
|
+
function CONTROLLABLE:PatrolRaceTrack(Point1,Point2,Altitude,Speed,Formation,AGL,Delay)
|
|
24862
25025
|
local PatrolGroup=self
|
|
24863
25026
|
if not self:IsInstanceOf("GROUP")then
|
|
24864
25027
|
PatrolGroup=self:GetGroup()
|
|
@@ -24872,8 +25035,10 @@ end
|
|
|
24872
25035
|
local FromCoord=PatrolGroup:GetCoordinate()
|
|
24873
25036
|
local ToCoord=Point1:GetCoordinate()
|
|
24874
25037
|
if Altitude then
|
|
24875
|
-
|
|
24876
|
-
|
|
25038
|
+
local asl=true
|
|
25039
|
+
if AGL then asl=false end
|
|
25040
|
+
FromCoord:SetAltitude(Altitude,asl)
|
|
25041
|
+
ToCoord:SetAltitude(Altitude,asl)
|
|
24877
25042
|
end
|
|
24878
25043
|
local Route={}
|
|
24879
25044
|
Route[#Route+1]=FromCoord:WaypointAir(AltType,COORDINATE.WaypointType.TurningPoint,COORDINATE.WaypointAction.TurningPoint,Speed,true,nil,DCSTasks,description,timeReFuAr)
|
|
@@ -26451,6 +26616,32 @@ report:Add("==================")
|
|
|
26451
26616
|
local text=report:Text()
|
|
26452
26617
|
return tSTN,text
|
|
26453
26618
|
end
|
|
26619
|
+
function GROUP:IsSAM()
|
|
26620
|
+
local issam=false
|
|
26621
|
+
local units=self:GetUnits()
|
|
26622
|
+
for _,_unit in pairs(units or{})do
|
|
26623
|
+
local unit=_unit
|
|
26624
|
+
if unit:HasSEAD()and unit:IsGround()and(not unit:HasAttribute("Mobile AAA"))then
|
|
26625
|
+
issam=true
|
|
26626
|
+
break
|
|
26627
|
+
end
|
|
26628
|
+
end
|
|
26629
|
+
return issam
|
|
26630
|
+
end
|
|
26631
|
+
function GROUP:IsAAA()
|
|
26632
|
+
local issam=false
|
|
26633
|
+
local units=self:GetUnits()
|
|
26634
|
+
for _,_unit in pairs(units or{})do
|
|
26635
|
+
local unit=_unit
|
|
26636
|
+
local desc=unit:GetDesc()or{}
|
|
26637
|
+
local attr=desc.attributes or{}
|
|
26638
|
+
if unit:HasSEAD()then return false end
|
|
26639
|
+
if attr["AAA"]or attr["SAM related"]then
|
|
26640
|
+
issam=true
|
|
26641
|
+
end
|
|
26642
|
+
end
|
|
26643
|
+
return issam
|
|
26644
|
+
end
|
|
26454
26645
|
UNIT={
|
|
26455
26646
|
ClassName="UNIT",
|
|
26456
26647
|
UnitName=nil,
|
|
@@ -30223,7 +30414,7 @@ Reported={},
|
|
|
30223
30414
|
}
|
|
30224
30415
|
function CARGO:New(Type,Name,Weight,LoadRadius,NearRadius)
|
|
30225
30416
|
local self=BASE:Inherit(self,FSM:New())
|
|
30226
|
-
self:
|
|
30417
|
+
self:T({Type,Name,Weight,LoadRadius,NearRadius})
|
|
30227
30418
|
self:SetStartState("UnLoaded")
|
|
30228
30419
|
self:AddTransition({"UnLoaded","Boarding"},"Board","Boarding")
|
|
30229
30420
|
self:AddTransition("Boarding","Boarding","Boarding")
|
|
@@ -30368,7 +30559,7 @@ function CARGO:IsDeployed()
|
|
|
30368
30559
|
return self.Deployed
|
|
30369
30560
|
end
|
|
30370
30561
|
function CARGO:Spawn(PointVec2)
|
|
30371
|
-
self:
|
|
30562
|
+
self:T()
|
|
30372
30563
|
end
|
|
30373
30564
|
function CARGO:Flare(FlareColor)
|
|
30374
30565
|
if self:IsUnLoaded()then
|
|
@@ -30418,7 +30609,7 @@ function CARGO:GetLoadRadius()
|
|
|
30418
30609
|
return self.LoadRadius
|
|
30419
30610
|
end
|
|
30420
30611
|
function CARGO:IsInLoadRadius(Coordinate)
|
|
30421
|
-
self:
|
|
30612
|
+
self:T({Coordinate,LoadRadius=self.LoadRadius})
|
|
30422
30613
|
local Distance=0
|
|
30423
30614
|
if self:IsUnLoaded()then
|
|
30424
30615
|
local CargoCoordinate=self.CargoObject:GetCoordinate()
|
|
@@ -30431,7 +30622,7 @@ end
|
|
|
30431
30622
|
return false
|
|
30432
30623
|
end
|
|
30433
30624
|
function CARGO:IsInReportRadius(Coordinate)
|
|
30434
|
-
self:
|
|
30625
|
+
self:T({Coordinate})
|
|
30435
30626
|
local Distance=0
|
|
30436
30627
|
if self:IsUnLoaded()then
|
|
30437
30628
|
Distance=Coordinate:Get2DDistance(self.CargoObject:GetCoordinate())
|
|
@@ -30533,7 +30724,7 @@ ClassName="CARGO_REPRESENTABLE"
|
|
|
30533
30724
|
}
|
|
30534
30725
|
function CARGO_REPRESENTABLE:New(CargoObject,Type,Name,LoadRadius,NearRadius)
|
|
30535
30726
|
local self=BASE:Inherit(self,CARGO:New(Type,Name,0,LoadRadius,NearRadius))
|
|
30536
|
-
self:
|
|
30727
|
+
self:T({Type,Name,LoadRadius,NearRadius})
|
|
30537
30728
|
local Desc=CargoObject:GetDesc()
|
|
30538
30729
|
self:T({Desc=Desc})
|
|
30539
30730
|
local Weight=math.random(80,120)
|
|
@@ -30548,7 +30739,7 @@ self:SetWeight(Weight)
|
|
|
30548
30739
|
return self
|
|
30549
30740
|
end
|
|
30550
30741
|
function CARGO_REPRESENTABLE:Destroy()
|
|
30551
|
-
self:
|
|
30742
|
+
self:T({CargoName=self:GetName()})
|
|
30552
30743
|
return self
|
|
30553
30744
|
end
|
|
30554
30745
|
function CARGO_REPRESENTABLE:RouteTo(ToPointVec2,Speed)
|
|
@@ -30566,12 +30757,12 @@ local CoordinateZone=ZONE_RADIUS:New("Zone",self:GetCoordinate():GetVec2(),500)
|
|
|
30566
30757
|
CoordinateZone:Scan({Object.Category.UNIT})
|
|
30567
30758
|
for _,DCSUnit in pairs(CoordinateZone:GetScannedUnits())do
|
|
30568
30759
|
local NearUnit=UNIT:Find(DCSUnit)
|
|
30569
|
-
self:
|
|
30760
|
+
self:T({NearUnit=NearUnit})
|
|
30570
30761
|
local NearUnitCoalition=NearUnit:GetCoalition()
|
|
30571
30762
|
local CargoCoalition=self:GetCoalition()
|
|
30572
30763
|
if NearUnitCoalition==CargoCoalition then
|
|
30573
30764
|
local Attributes=NearUnit:GetDesc()
|
|
30574
|
-
self:
|
|
30765
|
+
self:T({Desc=Attributes})
|
|
30575
30766
|
if NearUnit:HasAttribute("Trucks")then
|
|
30576
30767
|
MESSAGE:New(Message,20,NearUnit:GetCallsign().." reporting - Cargo "..self:GetName()):ToGroup(TaskGroup)
|
|
30577
30768
|
break
|
|
@@ -30586,7 +30777,7 @@ ClassName="CARGO_REPORTABLE"
|
|
|
30586
30777
|
}
|
|
30587
30778
|
function CARGO_REPORTABLE:New(Type,Name,Weight,LoadRadius,NearRadius)
|
|
30588
30779
|
local self=BASE:Inherit(self,CARGO:New(Type,Name,Weight,LoadRadius,NearRadius))
|
|
30589
|
-
self:
|
|
30780
|
+
self:T({Type,Name,Weight,LoadRadius,NearRadius})
|
|
30590
30781
|
return self
|
|
30591
30782
|
end
|
|
30592
30783
|
function CARGO_REPORTABLE:MessageToGroup(Message,TaskGroup,Name)
|
|
@@ -30599,13 +30790,13 @@ ClassName="CARGO_PACKAGE"
|
|
|
30599
30790
|
}
|
|
30600
30791
|
function CARGO_PACKAGE:New(CargoCarrier,Type,Name,Weight,LoadRadius,NearRadius)
|
|
30601
30792
|
local self=BASE:Inherit(self,CARGO_REPRESENTABLE:New(CargoCarrier,Type,Name,Weight,LoadRadius,NearRadius))
|
|
30602
|
-
self:
|
|
30793
|
+
self:T({Type,Name,Weight,LoadRadius,NearRadius})
|
|
30603
30794
|
self:T(CargoCarrier)
|
|
30604
30795
|
self.CargoCarrier=CargoCarrier
|
|
30605
30796
|
return self
|
|
30606
30797
|
end
|
|
30607
30798
|
function CARGO_PACKAGE:onafterOnBoard(From,Event,To,CargoCarrier,Speed,BoardDistance,LoadDistance,Angle)
|
|
30608
|
-
self:
|
|
30799
|
+
self:T()
|
|
30609
30800
|
self.CargoInAir=self.CargoCarrier:InAir()
|
|
30610
30801
|
self:T(self.CargoInAir)
|
|
30611
30802
|
if not self.CargoInAir then
|
|
@@ -30623,7 +30814,7 @@ end
|
|
|
30623
30814
|
self:Boarded(CargoCarrier,Speed,BoardDistance,LoadDistance,Angle)
|
|
30624
30815
|
end
|
|
30625
30816
|
function CARGO_PACKAGE:IsNear(CargoCarrier)
|
|
30626
|
-
self:
|
|
30817
|
+
self:T()
|
|
30627
30818
|
local CargoCarrierPoint=CargoCarrier:GetCoordinate()
|
|
30628
30819
|
local Distance=CargoCarrierPoint:Get2DDistance(self.CargoCarrier:GetCoordinate())
|
|
30629
30820
|
self:T(Distance)
|
|
@@ -30634,7 +30825,7 @@ return false
|
|
|
30634
30825
|
end
|
|
30635
30826
|
end
|
|
30636
30827
|
function CARGO_PACKAGE:onafterOnBoarded(From,Event,To,CargoCarrier,Speed,BoardDistance,LoadDistance,Angle)
|
|
30637
|
-
self:
|
|
30828
|
+
self:T()
|
|
30638
30829
|
if self:IsNear(CargoCarrier)then
|
|
30639
30830
|
self:__Load(1,CargoCarrier,Speed,LoadDistance,Angle)
|
|
30640
30831
|
else
|
|
@@ -30642,7 +30833,7 @@ self:__Boarded(1,CargoCarrier,Speed,BoardDistance,LoadDistance,Angle)
|
|
|
30642
30833
|
end
|
|
30643
30834
|
end
|
|
30644
30835
|
function CARGO_PACKAGE:onafterUnBoard(From,Event,To,CargoCarrier,Speed,UnLoadDistance,UnBoardDistance,Radius,Angle)
|
|
30645
|
-
self:
|
|
30836
|
+
self:T()
|
|
30646
30837
|
self.CargoInAir=self.CargoCarrier:InAir()
|
|
30647
30838
|
self:T(self.CargoInAir)
|
|
30648
30839
|
if not self.CargoInAir then
|
|
@@ -30661,7 +30852,7 @@ end
|
|
|
30661
30852
|
self:__UnBoarded(1,CargoCarrier,Speed)
|
|
30662
30853
|
end
|
|
30663
30854
|
function CARGO_PACKAGE:onafterUnBoarded(From,Event,To,CargoCarrier,Speed)
|
|
30664
|
-
self:
|
|
30855
|
+
self:T()
|
|
30665
30856
|
if self:IsNear(CargoCarrier)then
|
|
30666
30857
|
self:__UnLoad(1,CargoCarrier,Speed)
|
|
30667
30858
|
else
|
|
@@ -30669,7 +30860,7 @@ self:__UnBoarded(1,CargoCarrier,Speed)
|
|
|
30669
30860
|
end
|
|
30670
30861
|
end
|
|
30671
30862
|
function CARGO_PACKAGE:onafterLoad(From,Event,To,CargoCarrier,Speed,LoadDistance,Angle)
|
|
30672
|
-
self:
|
|
30863
|
+
self:T()
|
|
30673
30864
|
self.CargoCarrier=CargoCarrier
|
|
30674
30865
|
local StartPointVec2=self.CargoCarrier:GetPointVec2()
|
|
30675
30866
|
local CargoCarrierHeading=self.CargoCarrier:GetHeading()
|
|
@@ -30682,7 +30873,7 @@ local TaskRoute=self.CargoCarrier:TaskRoute(Points)
|
|
|
30682
30873
|
self.CargoCarrier:SetTask(TaskRoute,1)
|
|
30683
30874
|
end
|
|
30684
30875
|
function CARGO_PACKAGE:onafterUnLoad(From,Event,To,CargoCarrier,Speed,Distance,Angle)
|
|
30685
|
-
self:
|
|
30876
|
+
self:T()
|
|
30686
30877
|
local StartPointVec2=self.CargoCarrier:GetPointVec2()
|
|
30687
30878
|
local CargoCarrierHeading=self.CargoCarrier:GetHeading()
|
|
30688
30879
|
local CargoDeployHeading=((CargoCarrierHeading+Angle)>=360)and(CargoCarrierHeading+Angle-360)or(CargoCarrierHeading+Angle)
|
|
@@ -30707,7 +30898,7 @@ self:SetEventPriority(5)
|
|
|
30707
30898
|
return self
|
|
30708
30899
|
end
|
|
30709
30900
|
function CARGO_UNIT:onenterUnBoarding(From,Event,To,ToPointVec2,NearRadius)
|
|
30710
|
-
self:
|
|
30901
|
+
self:T({From,Event,To,ToPointVec2,NearRadius})
|
|
30711
30902
|
local Angle=180
|
|
30712
30903
|
local Speed=60
|
|
30713
30904
|
local DeployDistance=9
|
|
@@ -30730,7 +30921,7 @@ self.CargoObject:ReSpawnAt(ToPointVec2,CargoDeployHeading)
|
|
|
30730
30921
|
else
|
|
30731
30922
|
self.CargoObject:ReSpawnAt(FromPointVec2,CargoDeployHeading)
|
|
30732
30923
|
end
|
|
30733
|
-
self:
|
|
30924
|
+
self:T({"CargoUnits:",self.CargoObject:GetGroup():GetName()})
|
|
30734
30925
|
self.CargoCarrier=nil
|
|
30735
30926
|
local Points={}
|
|
30736
30927
|
Points[#Points+1]=FromPointVec2:WaypointGround(Speed,"Vee")
|
|
@@ -30746,7 +30937,7 @@ end
|
|
|
30746
30937
|
end
|
|
30747
30938
|
end
|
|
30748
30939
|
function CARGO_UNIT:onleaveUnBoarding(From,Event,To,ToPointVec2,NearRadius)
|
|
30749
|
-
self:
|
|
30940
|
+
self:T({From,Event,To,ToPointVec2,NearRadius})
|
|
30750
30941
|
local Angle=180
|
|
30751
30942
|
local Speed=10
|
|
30752
30943
|
local Distance=5
|
|
@@ -30755,7 +30946,7 @@ return true
|
|
|
30755
30946
|
end
|
|
30756
30947
|
end
|
|
30757
30948
|
function CARGO_UNIT:onafterUnBoarding(From,Event,To,ToPointVec2,NearRadius)
|
|
30758
|
-
self:
|
|
30949
|
+
self:T({From,Event,To,ToPointVec2,NearRadius})
|
|
30759
30950
|
self.CargoInAir=self.CargoObject:InAir()
|
|
30760
30951
|
self:T(self.CargoInAir)
|
|
30761
30952
|
if not self.CargoInAir then
|
|
@@ -30763,7 +30954,7 @@ end
|
|
|
30763
30954
|
self:__UnLoad(1,ToPointVec2,NearRadius)
|
|
30764
30955
|
end
|
|
30765
30956
|
function CARGO_UNIT:onenterUnLoaded(From,Event,To,ToPointVec2)
|
|
30766
|
-
self:
|
|
30957
|
+
self:T({ToPointVec2,From,Event,To})
|
|
30767
30958
|
local Angle=180
|
|
30768
30959
|
local Speed=10
|
|
30769
30960
|
local Distance=5
|
|
@@ -30784,7 +30975,7 @@ self.OnUnLoadedCallBack=nil
|
|
|
30784
30975
|
end
|
|
30785
30976
|
end
|
|
30786
30977
|
function CARGO_UNIT:onafterBoard(From,Event,To,CargoCarrier,NearRadius,...)
|
|
30787
|
-
self:
|
|
30978
|
+
self:T({From,Event,To,CargoCarrier,NearRadius=NearRadius})
|
|
30788
30979
|
self.CargoInAir=self.CargoObject:InAir()
|
|
30789
30980
|
local Desc=self.CargoObject:GetDesc()
|
|
30790
30981
|
local MaxSpeed=Desc.speedMaxOffRoad
|
|
@@ -30818,8 +31009,8 @@ end
|
|
|
30818
31009
|
end
|
|
30819
31010
|
end
|
|
30820
31011
|
function CARGO_UNIT:onafterBoarding(From,Event,To,CargoCarrier,NearRadius,...)
|
|
30821
|
-
self:
|
|
30822
|
-
self:
|
|
31012
|
+
self:T({From,Event,To,CargoCarrier:GetName(),NearRadius=NearRadius})
|
|
31013
|
+
self:T({IsAlive=self.CargoObject:IsAlive()})
|
|
30823
31014
|
if CargoCarrier and CargoCarrier:IsAlive()then
|
|
30824
31015
|
if(CargoCarrier:IsAir()and not CargoCarrier:InAir())or true then
|
|
30825
31016
|
local NearRadius=NearRadius or CargoCarrier:GetBoundingRadius(NearRadius)+5
|
|
@@ -30857,11 +31048,11 @@ self:CancelBoarding(CargoCarrier,NearRadius,...)
|
|
|
30857
31048
|
self.CargoObject:SetCommand(self.CargoObject:CommandStopRoute(true))
|
|
30858
31049
|
end
|
|
30859
31050
|
else
|
|
30860
|
-
self:
|
|
31051
|
+
self:T("Something is wrong")
|
|
30861
31052
|
end
|
|
30862
31053
|
end
|
|
30863
31054
|
function CARGO_UNIT:onenterLoaded(From,Event,To,CargoCarrier)
|
|
30864
|
-
self:
|
|
31055
|
+
self:T({From,Event,To,CargoCarrier})
|
|
30865
31056
|
self.CargoCarrier=CargoCarrier
|
|
30866
31057
|
if self.CargoObject then
|
|
30867
31058
|
self.CargoObject:Destroy(false)
|
|
@@ -30888,7 +31079,7 @@ ClassName="CARGO_SLINGLOAD"
|
|
|
30888
31079
|
}
|
|
30889
31080
|
function CARGO_SLINGLOAD:New(CargoStatic,Type,Name,LoadRadius,NearRadius)
|
|
30890
31081
|
local self=BASE:Inherit(self,CARGO_REPRESENTABLE:New(CargoStatic,Type,Name,nil,LoadRadius,NearRadius))
|
|
30891
|
-
self:
|
|
31082
|
+
self:T({Type,Name,NearRadius})
|
|
30892
31083
|
self.CargoObject=CargoStatic
|
|
30893
31084
|
_EVENTDISPATCHER:CreateEventNewCargo(self)
|
|
30894
31085
|
self:HandleEvent(EVENTS.Dead,self.OnEventCargoDead)
|
|
@@ -30999,7 +31190,7 @@ ClassName="CARGO_CRATE"
|
|
|
30999
31190
|
}
|
|
31000
31191
|
function CARGO_CRATE:New(CargoStatic,Type,Name,LoadRadius,NearRadius)
|
|
31001
31192
|
local self=BASE:Inherit(self,CARGO_REPRESENTABLE:New(CargoStatic,Type,Name,nil,LoadRadius,NearRadius))
|
|
31002
|
-
self:
|
|
31193
|
+
self:T({Type,Name,NearRadius})
|
|
31003
31194
|
self.CargoObject=CargoStatic
|
|
31004
31195
|
_EVENTDISPATCHER:CreateEventNewCargo(self)
|
|
31005
31196
|
self:HandleEvent(EVENTS.Dead,self.OnEventCargoDead)
|
|
@@ -31102,21 +31293,21 @@ end
|
|
|
31102
31293
|
return Alive
|
|
31103
31294
|
end
|
|
31104
31295
|
function CARGO_CRATE:RouteTo(Coordinate)
|
|
31105
|
-
self:
|
|
31296
|
+
self:T({Coordinate=Coordinate})
|
|
31106
31297
|
end
|
|
31107
31298
|
function CARGO_CRATE:IsNear(CargoCarrier,NearRadius)
|
|
31108
|
-
self:
|
|
31299
|
+
self:T({NearRadius=NearRadius})
|
|
31109
31300
|
return self:IsNear(CargoCarrier:GetCoordinate(),NearRadius)
|
|
31110
31301
|
end
|
|
31111
31302
|
function CARGO_CRATE:Respawn()
|
|
31112
|
-
self:
|
|
31303
|
+
self:T({"Respawning crate "..self:GetName()})
|
|
31113
31304
|
if self.CargoObject then
|
|
31114
31305
|
self.CargoObject:ReSpawn()
|
|
31115
31306
|
self:__Reset(-0.1)
|
|
31116
31307
|
end
|
|
31117
31308
|
end
|
|
31118
31309
|
function CARGO_CRATE:onafterReset()
|
|
31119
|
-
self:
|
|
31310
|
+
self:T({"Reset crate "..self:GetName()})
|
|
31120
31311
|
if self.CargoObject then
|
|
31121
31312
|
self:SetDeployed(false)
|
|
31122
31313
|
self:SetStartState("UnLoaded")
|
|
@@ -31145,7 +31336,7 @@ ClassName="CARGO_GROUP",
|
|
|
31145
31336
|
}
|
|
31146
31337
|
function CARGO_GROUP:New(CargoGroup,Type,Name,LoadRadius,NearRadius)
|
|
31147
31338
|
local self=BASE:Inherit(self,CARGO_REPORTABLE:New(Type,Name,0,LoadRadius,NearRadius))
|
|
31148
|
-
self:
|
|
31339
|
+
self:T({Type,Name,LoadRadius})
|
|
31149
31340
|
self.CargoSet=SET_CARGO:New()
|
|
31150
31341
|
self.CargoGroup=CargoGroup
|
|
31151
31342
|
self.Grouped=true
|
|
@@ -31189,7 +31380,7 @@ self:SetEventPriority(4)
|
|
|
31189
31380
|
return self
|
|
31190
31381
|
end
|
|
31191
31382
|
function CARGO_GROUP:Respawn()
|
|
31192
|
-
self:
|
|
31383
|
+
self:T({"Respawning"})
|
|
31193
31384
|
for CargoID,CargoData in pairs(self.CargoSet:GetSet())do
|
|
31194
31385
|
local Cargo=CargoData
|
|
31195
31386
|
Cargo:Destroy()
|
|
@@ -31230,7 +31421,7 @@ self.CargoObject=nil
|
|
|
31230
31421
|
end
|
|
31231
31422
|
end
|
|
31232
31423
|
function CARGO_GROUP:Regroup()
|
|
31233
|
-
self:
|
|
31424
|
+
self:T("Regroup")
|
|
31234
31425
|
if self.Grouped==false then
|
|
31235
31426
|
self.Grouped=true
|
|
31236
31427
|
local GroupTemplate=UTILS.DeepCopy(self.CargoTemplate)
|
|
@@ -31239,7 +31430,7 @@ GroupTemplate.groupId=nil
|
|
|
31239
31430
|
GroupTemplate.units={}
|
|
31240
31431
|
for CargoUnitName,CargoUnit in pairs(self.CargoSet:GetSet())do
|
|
31241
31432
|
local CargoUnit=CargoUnit
|
|
31242
|
-
self:
|
|
31433
|
+
self:T({CargoUnit:GetName(),UnLoaded=CargoUnit:IsUnLoaded()})
|
|
31243
31434
|
if CargoUnit:IsUnLoaded()then
|
|
31244
31435
|
CargoUnit.CargoObject:Destroy()
|
|
31245
31436
|
GroupTemplate.units[#GroupTemplate.units+1]=self.CargoUnitTemplate[CargoUnitName]
|
|
@@ -31250,12 +31441,12 @@ GroupTemplate.units[#GroupTemplate.units].heading=CargoUnit:GetHeading()
|
|
|
31250
31441
|
end
|
|
31251
31442
|
end
|
|
31252
31443
|
self.CargoGroup=GROUP:NewTemplate(GroupTemplate,GroupTemplate.CoalitionID,GroupTemplate.CategoryID,GroupTemplate.CountryID)
|
|
31253
|
-
self:
|
|
31444
|
+
self:T({"Regroup",GroupTemplate})
|
|
31254
31445
|
self.CargoObject=_DATABASE:Spawn(GroupTemplate)
|
|
31255
31446
|
end
|
|
31256
31447
|
end
|
|
31257
31448
|
function CARGO_GROUP:OnEventCargoDead(EventData)
|
|
31258
|
-
self:
|
|
31449
|
+
self:T(EventData)
|
|
31259
31450
|
local Destroyed=false
|
|
31260
31451
|
if self:IsDestroyed()or self:IsUnLoaded()or self:IsBoarding()or self:IsUnboarding()then
|
|
31261
31452
|
Destroyed=true
|
|
@@ -31277,15 +31468,15 @@ end
|
|
|
31277
31468
|
end
|
|
31278
31469
|
if Destroyed then
|
|
31279
31470
|
self:Destroyed()
|
|
31280
|
-
self:
|
|
31471
|
+
self:T({"Cargo group destroyed"})
|
|
31281
31472
|
end
|
|
31282
31473
|
end
|
|
31283
31474
|
function CARGO_GROUP:onafterBoard(From,Event,To,CargoCarrier,NearRadius,...)
|
|
31284
|
-
self:
|
|
31475
|
+
self:T({CargoCarrier.UnitName,From,Event,To,NearRadius=NearRadius})
|
|
31285
31476
|
NearRadius=NearRadius or self.NearRadius
|
|
31286
31477
|
self.CargoSet:ForEach(
|
|
31287
31478
|
function(Cargo,...)
|
|
31288
|
-
self:
|
|
31479
|
+
self:T({"Board Unit",Cargo:GetName(),Cargo:IsDestroyed(),Cargo.CargoObject:IsAlive()})
|
|
31289
31480
|
local CargoGroup=Cargo.CargoObject
|
|
31290
31481
|
CargoGroup:OptionAlarmStateGreen()
|
|
31291
31482
|
Cargo:__Board(1,CargoCarrier,NearRadius,...)
|
|
@@ -31326,7 +31517,7 @@ if not Cancelled then
|
|
|
31326
31517
|
if not Boarded then
|
|
31327
31518
|
self:__Boarding(-5,CargoCarrier,NearRadius,...)
|
|
31328
31519
|
else
|
|
31329
|
-
self:
|
|
31520
|
+
self:T("Group Cargo is loaded")
|
|
31330
31521
|
self:__Load(1,CargoCarrier,...)
|
|
31331
31522
|
end
|
|
31332
31523
|
else
|
|
@@ -31337,7 +31528,7 @@ self:__Destroyed(1,CargoCarrier,NearRadius,...)
|
|
|
31337
31528
|
end
|
|
31338
31529
|
end
|
|
31339
31530
|
function CARGO_GROUP:onafterUnBoard(From,Event,To,ToPointVec2,NearRadius,...)
|
|
31340
|
-
self:
|
|
31531
|
+
self:T({From,Event,To,ToPointVec2,NearRadius})
|
|
31341
31532
|
NearRadius=NearRadius or 25
|
|
31342
31533
|
local Timer=1
|
|
31343
31534
|
if From=="Loaded"then
|
|
@@ -31446,12 +31637,12 @@ end
|
|
|
31446
31637
|
)
|
|
31447
31638
|
end
|
|
31448
31639
|
function CARGO_GROUP:IsNear(CargoCarrier,NearRadius)
|
|
31449
|
-
self:
|
|
31640
|
+
self:T({NearRadius=NearRadius})
|
|
31450
31641
|
for _,Cargo in pairs(self.CargoSet:GetSet())do
|
|
31451
31642
|
local Cargo=Cargo
|
|
31452
31643
|
if Cargo:IsAlive()then
|
|
31453
31644
|
if Cargo:IsNear(CargoCarrier:GetCoordinate(),NearRadius)then
|
|
31454
|
-
self:
|
|
31645
|
+
self:T("Near")
|
|
31455
31646
|
return true
|
|
31456
31647
|
end
|
|
31457
31648
|
end
|
|
@@ -31473,7 +31664,7 @@ Distance=Coordinate:Get2DDistance(CargoCoordinate)
|
|
|
31473
31664
|
else
|
|
31474
31665
|
return false
|
|
31475
31666
|
end
|
|
31476
|
-
self:
|
|
31667
|
+
self:T({Distance=Distance,LoadRadius=self.LoadRadius})
|
|
31477
31668
|
if Distance<=self.LoadRadius then
|
|
31478
31669
|
return true
|
|
31479
31670
|
else
|
|
@@ -31485,7 +31676,7 @@ end
|
|
|
31485
31676
|
function CARGO_GROUP:IsInReportRadius(Coordinate)
|
|
31486
31677
|
local Cargo=self:GetFirstAlive()
|
|
31487
31678
|
if Cargo then
|
|
31488
|
-
self:
|
|
31679
|
+
self:T({Cargo})
|
|
31489
31680
|
local Distance=0
|
|
31490
31681
|
if Cargo:IsUnLoaded()then
|
|
31491
31682
|
Distance=Coordinate:Get2DDistance(Cargo.CargoObject:GetCoordinate())
|
|
@@ -32968,7 +33159,7 @@ self:HandleEvent(EVENTS.Shot,self.HandleEventShot)
|
|
|
32968
33159
|
self:SetStartState("Running")
|
|
32969
33160
|
self:AddTransition("*","ManageEvasion","*")
|
|
32970
33161
|
self:AddTransition("*","CalculateHitZone","*")
|
|
32971
|
-
self:I("*** SEAD - Started Version 0.4.
|
|
33162
|
+
self:I("*** SEAD - Started Version 0.4.6")
|
|
32972
33163
|
return self
|
|
32973
33164
|
end
|
|
32974
33165
|
function SEAD:UpdateSet(SEADGroupPrefixes)
|
|
@@ -33140,7 +33331,7 @@ if self.UseEmissionsOnOff then
|
|
|
33140
33331
|
grp:EnableEmission(false)
|
|
33141
33332
|
end
|
|
33142
33333
|
grp:OptionAlarmStateGreen()
|
|
33143
|
-
grp:RelocateGroundRandomInRadius(20,300,false,false,"Diamond")
|
|
33334
|
+
grp:RelocateGroundRandomInRadius(20,300,false,false,"Diamond",true)
|
|
33144
33335
|
if self.UseCallBack then
|
|
33145
33336
|
local object=self.CallBack
|
|
33146
33337
|
object:SeadSuppressionStart(grp,name,attacker)
|
|
@@ -35023,9 +35214,9 @@ local minheight=self.RadarBlurMinHeight or 250
|
|
|
35023
35214
|
local thresheight=self.RadarBlurThresHeight or 90
|
|
35024
35215
|
local thresblur=self.RadarBlurThresBlur or 85
|
|
35025
35216
|
local dist=math.floor(Distance)
|
|
35026
|
-
if dist<=
|
|
35027
|
-
thresheight=(((dist*dist)/
|
|
35028
|
-
thresblur=(((dist*dist)/
|
|
35217
|
+
if dist<=self.RadarBlurClosing then
|
|
35218
|
+
thresheight=(((dist*dist)/self.RadarBlurClosingSquare)*thresheight)
|
|
35219
|
+
thresblur=(((dist*dist)/self.RadarBlurClosingSquare)*thresblur)
|
|
35029
35220
|
end
|
|
35030
35221
|
local fheight=math.floor(math.random(1,10000)/100)
|
|
35031
35222
|
local fblur=math.floor(math.random(1,10000)/100)
|
|
@@ -35199,11 +35390,13 @@ self._.FilterCategories[FilterCategories]=FilterCategories
|
|
|
35199
35390
|
end
|
|
35200
35391
|
return self
|
|
35201
35392
|
end
|
|
35202
|
-
function DETECTION_BASE:SetRadarBlur(minheight,thresheight,thresblur)
|
|
35393
|
+
function DETECTION_BASE:SetRadarBlur(minheight,thresheight,thresblur,closing)
|
|
35203
35394
|
self.RadarBlur=true
|
|
35204
35395
|
self.RadarBlurMinHeight=minheight or 250
|
|
35205
35396
|
self.RadarBlurThresHeight=thresheight or 90
|
|
35206
35397
|
self.RadarBlurThresBlur=thresblur or 85
|
|
35398
|
+
self.RadarBlurClosing=closing or 20
|
|
35399
|
+
self.RadarBlurClosingSquare=self.RadarBlurClosing*self.RadarBlurClosing
|
|
35207
35400
|
return self
|
|
35208
35401
|
end
|
|
35209
35402
|
end
|
|
@@ -38334,7 +38527,7 @@ if takeoff==RAT.wp.air then
|
|
|
38334
38527
|
departure=departure:GetZone()
|
|
38335
38528
|
end
|
|
38336
38529
|
elseif self:_ZoneExists(_departure)then
|
|
38337
|
-
departure=ZONE:
|
|
38530
|
+
departure=ZONE:FindByName(_departure)
|
|
38338
38531
|
else
|
|
38339
38532
|
local text=string.format("ERROR! Specified departure airport %s does not exist for %s.",_departure,self.alias)
|
|
38340
38533
|
self:E(RAT.id..text)
|
|
@@ -38405,7 +38598,7 @@ if landing==RAT.wp.air or self.returnzone then
|
|
|
38405
38598
|
destination=destination:GetZone()
|
|
38406
38599
|
end
|
|
38407
38600
|
elseif self:_ZoneExists(_destination)then
|
|
38408
|
-
destination=ZONE:
|
|
38601
|
+
destination=ZONE:FindByName(_destination)
|
|
38409
38602
|
else
|
|
38410
38603
|
local text=string.format("ERROR: Specified destination airport/zone %s does not exist for %s!",_destination,self.alias)
|
|
38411
38604
|
self:E(RAT.id.."ERROR: "..text)
|
|
@@ -38740,7 +38933,7 @@ end
|
|
|
38740
38933
|
end
|
|
38741
38934
|
elseif self:_ZoneExists(name)then
|
|
38742
38935
|
if takeoff==RAT.wp.air then
|
|
38743
|
-
dep=ZONE:
|
|
38936
|
+
dep=ZONE:FindByName(name)
|
|
38744
38937
|
else
|
|
38745
38938
|
self:E(RAT.id..string.format("ERROR! Takeoff is not in air. Cannot use %s as departure.",name))
|
|
38746
38939
|
end
|
|
@@ -38812,7 +39005,7 @@ end
|
|
|
38812
39005
|
end
|
|
38813
39006
|
elseif self:_ZoneExists(name)then
|
|
38814
39007
|
if landing==RAT.wp.air then
|
|
38815
|
-
dest=ZONE:
|
|
39008
|
+
dest=ZONE:FindByName(name)
|
|
38816
39009
|
else
|
|
38817
39010
|
self:E(RAT.id..string.format("ERROR! Landing is not in air. Cannot use zone %s as destination!",name))
|
|
38818
39011
|
end
|
|
@@ -39774,7 +39967,7 @@ end
|
|
|
39774
39967
|
return false
|
|
39775
39968
|
end
|
|
39776
39969
|
function RAT:_ZoneExists(name)
|
|
39777
|
-
local z=
|
|
39970
|
+
local z=ZONE:FindByName(name)
|
|
39778
39971
|
if z then
|
|
39779
39972
|
return true
|
|
39780
39973
|
end
|
|
@@ -40814,15 +41007,15 @@ self.trackmissiles=false
|
|
|
40814
41007
|
return self
|
|
40815
41008
|
end
|
|
40816
41009
|
function RANGE:SetSRS(PathToSRS,Port,Coalition,Frequency,Modulation,Volume,PathToGoogleKey)
|
|
40817
|
-
if PathToSRS then
|
|
41010
|
+
if PathToSRS or MSRS.path then
|
|
40818
41011
|
self.useSRS=true
|
|
40819
|
-
self.controlmsrs=MSRS:New(PathToSRS,Frequency or 256,Modulation or radio.modulation.AM,Volume or 1.0)
|
|
40820
|
-
self.controlmsrs:SetPort(Port)
|
|
41012
|
+
self.controlmsrs=MSRS:New(PathToSRS or MSRS.path,Frequency or 256,Modulation or radio.modulation.AM,Volume or 1.0)
|
|
41013
|
+
self.controlmsrs:SetPort(Port or MSRS.port)
|
|
40821
41014
|
self.controlmsrs:SetCoalition(Coalition or coalition.side.BLUE)
|
|
40822
41015
|
self.controlmsrs:SetLabel("RANGEC")
|
|
40823
41016
|
self.controlsrsQ=MSRSQUEUE:New("CONTROL")
|
|
40824
|
-
self.instructmsrs=MSRS:New(PathToSRS,Frequency or 305,Modulation or radio.modulation.AM,Volume or 1.0)
|
|
40825
|
-
self.instructmsrs:SetPort(Port)
|
|
41017
|
+
self.instructmsrs=MSRS:New(PathToSRS or MSRS.path,Frequency or 305,Modulation or radio.modulation.AM,Volume or 1.0)
|
|
41018
|
+
self.instructmsrs:SetPort(Port or MSRS.port)
|
|
40826
41019
|
self.instructmsrs:SetCoalition(Coalition or coalition.side.BLUE)
|
|
40827
41020
|
self.instructmsrs:SetLabel("RANGEI")
|
|
40828
41021
|
self.instructsrsQ=MSRSQUEUE:New("INSTRUCT")
|
|
@@ -41111,6 +41304,7 @@ return fouldist
|
|
|
41111
41304
|
end
|
|
41112
41305
|
function RANGE:OnEventBirth(EventData)
|
|
41113
41306
|
self:F({eventbirth=EventData})
|
|
41307
|
+
if not EventData.IniPlayerName then return end
|
|
41114
41308
|
local _unitName=EventData.IniUnitName
|
|
41115
41309
|
local _unit,_playername=self:_GetPlayerUnitAndName(_unitName)
|
|
41116
41310
|
self:T3(self.lid.."BIRTH: unit = "..tostring(EventData.IniUnitName))
|
|
@@ -41367,7 +41561,7 @@ function RANGE:onafterExitRange(From,Event,To,player)
|
|
|
41367
41561
|
if self.instructor then
|
|
41368
41562
|
if self.useSRS then
|
|
41369
41563
|
local text="You left the bombing range zone. "
|
|
41370
|
-
local r=math.random(
|
|
41564
|
+
local r=math.random(5)
|
|
41371
41565
|
if r==1 then
|
|
41372
41566
|
text=text.."Have a nice day!"
|
|
41373
41567
|
elseif r==2 then
|
|
@@ -51105,7 +51299,7 @@ MANTIS.SamData={
|
|
|
51105
51299
|
["SA-15"]={Range=11,Blindspot=0,Height=6,Type="Short",Radar="Tor 9A331"},
|
|
51106
51300
|
["SA-13"]={Range=5,Blindspot=0,Height=3,Type="Short",Radar="Strela"},
|
|
51107
51301
|
["Avenger"]={Range=4,Blindspot=0,Height=3,Type="Short",Radar="Avenger"},
|
|
51108
|
-
["
|
|
51302
|
+
["Chaparral"]={Range=8,Blindspot=0,Height=3,Type="Short",Radar="Chaparral"},
|
|
51109
51303
|
["Linebacker"]={Range=4,Blindspot=0,Height=3,Type="Short",Radar="Linebacker"},
|
|
51110
51304
|
["Silkworm"]={Range=90,Blindspot=1,Height=0.2,Type="Long",Radar="Silkworm"},
|
|
51111
51305
|
["SA-10B"]={Range=75,Blindspot=0,Height=18,Type="Medium",Radar="SA-10B"},
|
|
@@ -51263,7 +51457,7 @@ end
|
|
|
51263
51457
|
if self.HQ_Template_CC then
|
|
51264
51458
|
self.HQ_CC=GROUP:FindByName(self.HQ_Template_CC)
|
|
51265
51459
|
end
|
|
51266
|
-
self.version="0.8.
|
|
51460
|
+
self.version="0.8.16"
|
|
51267
51461
|
self:I(string.format("***** Starting MANTIS Version %s *****",self.version))
|
|
51268
51462
|
self:SetStartState("Stopped")
|
|
51269
51463
|
self:AddTransition("Stopped","Start","Running")
|
|
@@ -51524,7 +51718,7 @@ local HQGroup=self.HQ_CC
|
|
|
51524
51718
|
if self.autorelocateunits.HQ and self.HQ_CC and HQGroup:IsAlive()then
|
|
51525
51719
|
local _hqgrp=self.HQ_CC
|
|
51526
51720
|
local text=self.lid.." Relocating HQ"
|
|
51527
|
-
_hqgrp:RelocateGroundRandomInRadius(20,500,true,true)
|
|
51721
|
+
_hqgrp:RelocateGroundRandomInRadius(20,500,true,true,nil,true)
|
|
51528
51722
|
end
|
|
51529
51723
|
if self.autorelocateunits.EWR then
|
|
51530
51724
|
local EWR_GRP=SET_GROUP:New():FilterPrefixes(self.EWR_Templates_Prefix):FilterCoalitions(self.Coalition):FilterOnce()
|
|
@@ -51534,7 +51728,7 @@ if _grp:IsAlive()and _grp:IsGround()then
|
|
|
51534
51728
|
local text=self.lid.." Relocating EWR ".._grp:GetName()
|
|
51535
51729
|
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
|
51536
51730
|
if self.verbose then self:I(text)end
|
|
51537
|
-
_grp:RelocateGroundRandomInRadius(20,500,true,true)
|
|
51731
|
+
_grp:RelocateGroundRandomInRadius(20,500,true,true,nil,true)
|
|
51538
51732
|
end
|
|
51539
51733
|
end
|
|
51540
51734
|
end
|
|
@@ -52762,7 +52956,7 @@ HARD="TOPGUN Graduate",
|
|
|
52762
52956
|
}
|
|
52763
52957
|
AIRBOSS.MenuF10={}
|
|
52764
52958
|
AIRBOSS.MenuF10Root=nil
|
|
52765
|
-
AIRBOSS.version="1.3.
|
|
52959
|
+
AIRBOSS.version="1.3.3"
|
|
52766
52960
|
function AIRBOSS:New(carriername,alias)
|
|
52767
52961
|
local self=BASE:Inherit(self,FSM:New())
|
|
52768
52962
|
self:F2({carriername=carriername,alias=alias})
|
|
@@ -53281,6 +53475,7 @@ self.SRS:SetGender(Gender or"male")
|
|
|
53281
53475
|
self.SRS:SetPath(PathToSRS)
|
|
53282
53476
|
self.SRS:SetPort(Port or 5002)
|
|
53283
53477
|
self.SRS:SetLabel(self.AirbossRadio.alias or"AIRBOSS")
|
|
53478
|
+
self.SRS:SetCoordinate(self.carrier:GetCoordinate())
|
|
53284
53479
|
if GoogleCreds then
|
|
53285
53480
|
self.SRS:SetGoogle(GoogleCreds)
|
|
53286
53481
|
end
|
|
@@ -55958,7 +56153,7 @@ self:E(self.lid.."ERROR: EventData=nil in event BIRTH!")
|
|
|
55958
56153
|
self:E(EventData)
|
|
55959
56154
|
return
|
|
55960
56155
|
end
|
|
55961
|
-
if EventData.IniUnit==nil then
|
|
56156
|
+
if EventData.IniUnit==nil and(not EventData.IniObjectCategory==Object.Category.STATIC)then
|
|
55962
56157
|
self:E(self.lid.."ERROR: EventData.IniUnit=nil in event BIRTH!")
|
|
55963
56158
|
self:E(EventData)
|
|
55964
56159
|
return
|
|
@@ -57409,7 +57604,7 @@ text=text..string.format("\nWind Vx=%.1f Vy=%.1f Vz=%.1f m/s",wind.x,wind.y,wind
|
|
|
57409
57604
|
end
|
|
57410
57605
|
text=text..string.format("\nPitch=%.1f° | Roll=%.1f° | Yaw=%.1f°",pitch,roll,yaw)
|
|
57411
57606
|
text=text..string.format("\nClimb Angle=%.1f° | Rate=%d ft/min",unit:GetClimbAngle(),velo.y*196.85)
|
|
57412
|
-
local dist=self:_GetOptLandingCoordinate():Get3DDistance(playerData.unit)
|
|
57607
|
+
local dist=self:_GetOptLandingCoordinate():Get3DDistance(playerData.unit:GetVec3())
|
|
57413
57608
|
local vplayer=playerData.unit:GetVelocityKMH()
|
|
57414
57609
|
local vcarrier=self.carrier:GetVelocityKMH()
|
|
57415
57610
|
local dv=math.abs(vplayer-vcarrier)
|
|
@@ -59273,7 +59468,7 @@ self.PilotRadio.alias="PILOT"
|
|
|
59273
59468
|
self.PilotRadio.voice=Voice or MSRS.Voices.Microsoft.David
|
|
59274
59469
|
self.PilotRadio.gender=Gender or"male"
|
|
59275
59470
|
self.PilotRadio.culture=Culture or"en-US"
|
|
59276
|
-
if(not Voice)and self.SRS and self.SRS.
|
|
59471
|
+
if(not Voice)and self.SRS and self.SRS:GetProvider()==MSRS.Provider.GOOGLE then
|
|
59277
59472
|
self.PilotRadio.voice=MSRS.Voices.Google.Standard.en_US_Standard_J
|
|
59278
59473
|
end
|
|
59279
59474
|
return self
|
|
@@ -62556,7 +62751,7 @@ DELIMITER="Punto",
|
|
|
62556
62751
|
}
|
|
62557
62752
|
ATIS.locale="en"
|
|
62558
62753
|
_ATIS={}
|
|
62559
|
-
ATIS.version="0.
|
|
62754
|
+
ATIS.version="1.0.0"
|
|
62560
62755
|
function ATIS:New(AirbaseName,Frequency,Modulation)
|
|
62561
62756
|
local self=BASE:Inherit(self,FSM:New())
|
|
62562
62757
|
self.airbasename=AirbaseName
|
|
@@ -64275,7 +64470,7 @@ CTLD.UnitTypeCapabilities={
|
|
|
64275
64470
|
["AH-64D_BLK_II"]={type="AH-64D_BLK_II",crates=false,troops=true,cratelimit=0,trooplimit=2,length=17,cargoweightlimit=200},
|
|
64276
64471
|
["Bronco-OV-10A"]={type="Bronco-OV-10A",crates=false,troops=true,cratelimit=0,trooplimit=5,length=13,cargoweightlimit=1450},
|
|
64277
64472
|
}
|
|
64278
|
-
CTLD.version="1.0.
|
|
64473
|
+
CTLD.version="1.0.45"
|
|
64279
64474
|
function CTLD:New(Coalition,Prefixes,Alias)
|
|
64280
64475
|
local self=BASE:Inherit(self,FSM:New())
|
|
64281
64476
|
BASE:T({Coalition,Prefixes,Alias})
|
|
@@ -64982,10 +65177,12 @@ realcargo=CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,true,false,crat
|
|
|
64982
65177
|
table.insert(droppedcargo,realcargo)
|
|
64983
65178
|
else
|
|
64984
65179
|
realcargo=CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,false,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],false,cargotype.PerCrateMass,nil,subcat)
|
|
64985
|
-
Cargo:RemoveStock()
|
|
64986
65180
|
end
|
|
64987
65181
|
table.insert(self.Spawned_Cargo,realcargo)
|
|
64988
65182
|
end
|
|
65183
|
+
if not(drop or pack)then
|
|
65184
|
+
Cargo:RemoveStock()
|
|
65185
|
+
end
|
|
64989
65186
|
local text=string.format("Crates for %s have been positioned near you!",cratename)
|
|
64990
65187
|
if drop then
|
|
64991
65188
|
text=string.format("Crates for %s have been dropped!",cratename)
|
|
@@ -78076,6 +78273,15 @@ trigger.action.outSoundForUnit(Unit:GetID(),self.UserSoundFileName)
|
|
|
78076
78273
|
end
|
|
78077
78274
|
return self
|
|
78078
78275
|
end
|
|
78276
|
+
function USERSOUND:ToClient(Client,Delay)
|
|
78277
|
+
Delay=Delay or 0
|
|
78278
|
+
if Delay>0 then
|
|
78279
|
+
SCHEDULER:New(nil,USERSOUND.ToClient,{self,Client},Delay)
|
|
78280
|
+
else
|
|
78281
|
+
trigger.action.outSoundForUnit(Client:GetID(),self.UserSoundFileName)
|
|
78282
|
+
end
|
|
78283
|
+
return self
|
|
78284
|
+
end
|
|
78079
78285
|
end
|
|
78080
78286
|
do
|
|
78081
78287
|
SOUNDBASE={
|
|
@@ -78118,18 +78324,25 @@ subtitle=nil,
|
|
|
78118
78324
|
subduration=0,
|
|
78119
78325
|
useSRS=false,
|
|
78120
78326
|
}
|
|
78121
|
-
function SOUNDFILE:New(FileName,Path,Duration)
|
|
78327
|
+
function SOUNDFILE:New(FileName,Path,Duration,UseSrs)
|
|
78122
78328
|
local self=BASE:Inherit(self,BASE:New())
|
|
78329
|
+
self:F({FileName,Path,Duration,UseSrs})
|
|
78123
78330
|
self:SetFileName(FileName)
|
|
78331
|
+
self:SetPlayWithSRS(UseSrs or false)
|
|
78124
78332
|
self:SetPath(Path)
|
|
78125
78333
|
self:SetDuration(Duration)
|
|
78126
|
-
self:T(string.format("New SOUNDFILE: file name=%s, path=%s",self.filename,self.path))
|
|
78127
78334
|
return self
|
|
78128
78335
|
end
|
|
78129
78336
|
function SOUNDFILE:SetPath(Path)
|
|
78130
|
-
self
|
|
78131
|
-
if not Path
|
|
78132
|
-
self.
|
|
78337
|
+
self:F({Path})
|
|
78338
|
+
if not Path then
|
|
78339
|
+
if self.useSRS then
|
|
78340
|
+
self.path=lfs.tempdir().."Mission\\l10n\\DEFAULT"
|
|
78341
|
+
else
|
|
78342
|
+
self.path="l10n/DEFAULT/"
|
|
78343
|
+
end
|
|
78344
|
+
else
|
|
78345
|
+
self.path=Path
|
|
78133
78346
|
end
|
|
78134
78347
|
local nmax=1000;local n=1
|
|
78135
78348
|
while(self.path:sub(-1)=="/"or self.path:sub(-1)==[[\]])and n<=nmax do
|
|
@@ -78137,6 +78350,7 @@ self.path=self.path:sub(1,#self.path-1)
|
|
|
78137
78350
|
n=n+1
|
|
78138
78351
|
end
|
|
78139
78352
|
self.path=self.path.."/"
|
|
78353
|
+
self:T("self.path="..self.path)
|
|
78140
78354
|
return self
|
|
78141
78355
|
end
|
|
78142
78356
|
function SOUNDFILE:GetPath()
|
|
@@ -78164,11 +78378,13 @@ local name=string.format("%s%s",path,filename)
|
|
|
78164
78378
|
return name
|
|
78165
78379
|
end
|
|
78166
78380
|
function SOUNDFILE:SetPlayWithSRS(Switch)
|
|
78381
|
+
self:F({Switch})
|
|
78167
78382
|
if Switch==true or Switch==nil then
|
|
78168
78383
|
self.useSRS=true
|
|
78169
78384
|
else
|
|
78170
78385
|
self.useSRS=false
|
|
78171
78386
|
end
|
|
78387
|
+
self:T("self.useSRS="..tostring(self.useSRS))
|
|
78172
78388
|
return self
|
|
78173
78389
|
end
|
|
78174
78390
|
end
|
|
@@ -78932,6 +79148,7 @@ ClassName="MSRS",
|
|
|
78932
79148
|
lid=nil,
|
|
78933
79149
|
port=5002,
|
|
78934
79150
|
name="MSRS",
|
|
79151
|
+
backend="srsexe",
|
|
78935
79152
|
frequencies={},
|
|
78936
79153
|
modulations={},
|
|
78937
79154
|
coalition=0,
|
|
@@ -78941,14 +79158,14 @@ voice=nil,
|
|
|
78941
79158
|
volume=1,
|
|
78942
79159
|
speed=1,
|
|
78943
79160
|
coordinate=nil,
|
|
79161
|
+
provider="win",
|
|
78944
79162
|
Label="ROBOT",
|
|
78945
|
-
AltBackend=nil,
|
|
78946
79163
|
ConfigFileName="Moose_MSRS.lua",
|
|
78947
79164
|
ConfigFilePath="Config\\",
|
|
78948
79165
|
ConfigLoaded=false,
|
|
78949
|
-
|
|
79166
|
+
poptions={},
|
|
78950
79167
|
}
|
|
78951
|
-
MSRS.version="0.
|
|
79168
|
+
MSRS.version="0.3.0"
|
|
78952
79169
|
MSRS.Voices={
|
|
78953
79170
|
Microsoft={
|
|
78954
79171
|
["Hedda"]="Microsoft Hedda Desktop",
|
|
@@ -79047,47 +79264,52 @@ Wavenet={
|
|
|
79047
79264
|
},
|
|
79048
79265
|
},
|
|
79049
79266
|
}
|
|
79050
|
-
MSRS.
|
|
79051
|
-
|
|
79052
|
-
|
|
79053
|
-
|
|
79054
|
-
MSRS.
|
|
79055
|
-
|
|
79056
|
-
|
|
79057
|
-
|
|
79058
|
-
|
|
79267
|
+
MSRS.Backend={
|
|
79268
|
+
SRSEXE="srsexe",
|
|
79269
|
+
GRPC="grpc",
|
|
79270
|
+
}
|
|
79271
|
+
MSRS.Provider={
|
|
79272
|
+
WINDOWS="win",
|
|
79273
|
+
GOOGLE="gcloud",
|
|
79274
|
+
AZURE="azure",
|
|
79275
|
+
AMAZON="aws",
|
|
79276
|
+
}
|
|
79277
|
+
function MSRS.uuid()
|
|
79278
|
+
local random=math.random
|
|
79279
|
+
local template='yxxx-xxxxxxxxxxxx'
|
|
79280
|
+
return string.gsub(template,'[xy]',function(c)
|
|
79281
|
+
local v=(c=='x')and random(0,0xf)or random(8,0xb)
|
|
79282
|
+
return string.format('%x',v)
|
|
79283
|
+
end)
|
|
79284
|
+
end
|
|
79285
|
+
function MSRS:New(Path,Frequency,Modulation,Backend)
|
|
79286
|
+
local self=BASE:Inherit(self,BASE:New())
|
|
79287
|
+
self:F({Path,Frequency,Modulation,Backend})
|
|
79059
79288
|
Frequency=Frequency or 143
|
|
79060
79289
|
Modulation=Modulation or radio.modulation.AM
|
|
79061
|
-
|
|
79062
|
-
if type(AltBackend)=="table"or type(self.AltBackend)=="table"then
|
|
79063
|
-
local Backend=UTILS.DeepCopy(AltBackend)or UTILS.DeepCopy(self.AltBackend)
|
|
79064
|
-
Backend.Vars=Backend.Vars or{}
|
|
79065
|
-
Backend.Vars.PathToSRS=PathToSRS
|
|
79066
|
-
Backend.Vars.Frequency=UTILS.DeepCopy(Frequency)
|
|
79067
|
-
Backend.Vars.Modulation=UTILS.DeepCopy(Modulation)
|
|
79068
|
-
Backend.Vars.Volume=Volume
|
|
79069
|
-
Backend.Functions=Backend.Functions or{}
|
|
79070
|
-
return self:_NewAltBackend(Backend)
|
|
79071
|
-
end
|
|
79290
|
+
self.lid=string.format("%s-%s | ","unknown",self.version)
|
|
79072
79291
|
if not self.ConfigLoaded then
|
|
79073
|
-
self:SetPath(
|
|
79292
|
+
self:SetPath(Path)
|
|
79074
79293
|
self:SetPort()
|
|
79075
79294
|
self:SetFrequencies(Frequency)
|
|
79076
79295
|
self:SetModulations(Modulation)
|
|
79077
79296
|
self:SetGender()
|
|
79078
79297
|
self:SetCoalition()
|
|
79079
79298
|
self:SetLabel()
|
|
79080
|
-
self:SetVolume(
|
|
79299
|
+
self:SetVolume()
|
|
79300
|
+
self:SetBackend(Backend)
|
|
79081
79301
|
else
|
|
79082
|
-
if
|
|
79083
|
-
self:SetPath(
|
|
79302
|
+
if Path then
|
|
79303
|
+
self:SetPath(Path)
|
|
79084
79304
|
end
|
|
79085
79305
|
if Frequency then
|
|
79086
79306
|
self:SetFrequencies(Frequency)
|
|
79307
|
+
end
|
|
79308
|
+
if Modulation then
|
|
79087
79309
|
self:SetModulations(Modulation)
|
|
79088
79310
|
end
|
|
79089
|
-
if
|
|
79090
|
-
self:
|
|
79311
|
+
if Backend then
|
|
79312
|
+
self:SetBackend(Backend)
|
|
79091
79313
|
end
|
|
79092
79314
|
end
|
|
79093
79315
|
self.lid=string.format("%s-%s | ",self.name,self.version)
|
|
@@ -79096,26 +79318,48 @@ self:E(self.lid.."***** ERROR - io or os NOT desanitized! MSRS will not work!")
|
|
|
79096
79318
|
end
|
|
79097
79319
|
return self
|
|
79098
79320
|
end
|
|
79099
|
-
function MSRS:
|
|
79100
|
-
|
|
79101
|
-
self
|
|
79102
|
-
return
|
|
79321
|
+
function MSRS:SetBackend(Backend)
|
|
79322
|
+
self:F({Backend=Backend})
|
|
79323
|
+
self.backend=Backend or MSRS.Backend.SRSEXE
|
|
79324
|
+
return self
|
|
79103
79325
|
end
|
|
79104
|
-
|
|
79105
|
-
self
|
|
79326
|
+
function MSRS:SetBackendGRPC()
|
|
79327
|
+
self:F()
|
|
79328
|
+
self:SetBackend(MSRS.Backend.GRPC)
|
|
79329
|
+
return self
|
|
79330
|
+
end
|
|
79331
|
+
function MSRS:SetBackendSRSEXE()
|
|
79332
|
+
self:F()
|
|
79333
|
+
self:SetBackend(MSRS.Backend.SRSEXE)
|
|
79334
|
+
return self
|
|
79335
|
+
end
|
|
79336
|
+
function MSRS.SetDefaultBackend(Backend)
|
|
79337
|
+
self:F({Backend=Backend})
|
|
79338
|
+
MSRS.backend=Backend or MSRS.Backend.SRSEXE
|
|
79339
|
+
end
|
|
79340
|
+
function MSRS.SetDefaultBackendGRPC()
|
|
79341
|
+
self:F()
|
|
79342
|
+
MSRS.backend=MSRS.Backend.GRPC
|
|
79343
|
+
end
|
|
79344
|
+
function MSRS:GetBackend()
|
|
79345
|
+
return self.backend
|
|
79346
|
+
end
|
|
79347
|
+
function MSRS:SetPath(Path)
|
|
79348
|
+
self:F({Path=Path})
|
|
79349
|
+
self.path=Path or"C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
|
79106
79350
|
local n=1;local nmax=1000
|
|
79107
79351
|
while(self.path:sub(-1)=="/"or self.path:sub(-1)==[[\]])and n<=nmax do
|
|
79108
79352
|
self.path=self.path:sub(1,#self.path-1)
|
|
79109
79353
|
n=n+1
|
|
79110
79354
|
end
|
|
79111
|
-
self:
|
|
79112
|
-
end
|
|
79355
|
+
self:F(string.format("SRS path=%s",self:GetPath()))
|
|
79113
79356
|
return self
|
|
79114
79357
|
end
|
|
79115
79358
|
function MSRS:GetPath()
|
|
79116
79359
|
return self.path
|
|
79117
79360
|
end
|
|
79118
79361
|
function MSRS:SetVolume(Volume)
|
|
79362
|
+
self:F({Volume=Volume})
|
|
79119
79363
|
local volume=Volume or 1
|
|
79120
79364
|
if volume>1 then volume=1 elseif volume<0 then volume=0 end
|
|
79121
79365
|
self.volume=volume
|
|
@@ -79125,6 +79369,7 @@ function MSRS:GetVolume()
|
|
|
79125
79369
|
return self.volume
|
|
79126
79370
|
end
|
|
79127
79371
|
function MSRS:SetLabel(Label)
|
|
79372
|
+
self:F({Label=Label})
|
|
79128
79373
|
self.Label=Label or"ROBOT"
|
|
79129
79374
|
return self
|
|
79130
79375
|
end
|
|
@@ -79132,13 +79377,16 @@ function MSRS:GetLabel()
|
|
|
79132
79377
|
return self.Label
|
|
79133
79378
|
end
|
|
79134
79379
|
function MSRS:SetPort(Port)
|
|
79380
|
+
self:F({Port=Port})
|
|
79135
79381
|
self.port=Port or 5002
|
|
79382
|
+
self:T(string.format("SRS port=%s",self:GetPort()))
|
|
79136
79383
|
return self
|
|
79137
79384
|
end
|
|
79138
79385
|
function MSRS:GetPort()
|
|
79139
79386
|
return self.port
|
|
79140
79387
|
end
|
|
79141
79388
|
function MSRS:SetCoalition(Coalition)
|
|
79389
|
+
self:F({Coalition=Coalition})
|
|
79142
79390
|
self.coalition=Coalition or 0
|
|
79143
79391
|
return self
|
|
79144
79392
|
end
|
|
@@ -79146,17 +79394,14 @@ function MSRS:GetCoalition()
|
|
|
79146
79394
|
return self.coalition
|
|
79147
79395
|
end
|
|
79148
79396
|
function MSRS:SetFrequencies(Frequencies)
|
|
79149
|
-
|
|
79150
|
-
|
|
79151
|
-
end
|
|
79152
|
-
self.frequencies=Frequencies
|
|
79397
|
+
self:F(Frequencies)
|
|
79398
|
+
self.frequencies=UTILS.EnsureTable(Frequencies,false)
|
|
79153
79399
|
return self
|
|
79154
79400
|
end
|
|
79155
79401
|
function MSRS:AddFrequencies(Frequencies)
|
|
79156
|
-
|
|
79157
|
-
Frequencies
|
|
79158
|
-
|
|
79159
|
-
for _,_freq in pairs(Frequencies)do
|
|
79402
|
+
self:F(Frequencies)
|
|
79403
|
+
for _,_freq in pairs(UTILS.EnsureTable(Frequencies,false))do
|
|
79404
|
+
self:T(self.lid..string.format("Adding frequency %s",tostring(_freq)))
|
|
79160
79405
|
table.insert(self.frequencies,_freq)
|
|
79161
79406
|
end
|
|
79162
79407
|
return self
|
|
@@ -79165,17 +79410,15 @@ function MSRS:GetFrequencies()
|
|
|
79165
79410
|
return self.frequencies
|
|
79166
79411
|
end
|
|
79167
79412
|
function MSRS:SetModulations(Modulations)
|
|
79168
|
-
|
|
79169
|
-
|
|
79170
|
-
|
|
79171
|
-
self.modulations
|
|
79413
|
+
self:F(Modulations)
|
|
79414
|
+
self.modulations=UTILS.EnsureTable(Modulations,false)
|
|
79415
|
+
self:T(self.lid.."Modulations:")
|
|
79416
|
+
self:T(self.modulations)
|
|
79172
79417
|
return self
|
|
79173
79418
|
end
|
|
79174
79419
|
function MSRS:AddModulations(Modulations)
|
|
79175
|
-
|
|
79176
|
-
Modulations
|
|
79177
|
-
end
|
|
79178
|
-
for _,_mod in pairs(Modulations)do
|
|
79420
|
+
self:F(Modulations)
|
|
79421
|
+
for _,_mod in pairs(UTILS.EnsureTable(Modulations,false))do
|
|
79179
79422
|
table.insert(self.modulations,_mod)
|
|
79180
79423
|
end
|
|
79181
79424
|
return self
|
|
@@ -79184,92 +79427,176 @@ function MSRS:GetModulations()
|
|
|
79184
79427
|
return self.modulations
|
|
79185
79428
|
end
|
|
79186
79429
|
function MSRS:SetGender(Gender)
|
|
79430
|
+
self:F({Gender=Gender})
|
|
79187
79431
|
Gender=Gender or"female"
|
|
79188
79432
|
self.gender=Gender:lower()
|
|
79189
79433
|
self:T("Setting gender to "..tostring(self.gender))
|
|
79190
79434
|
return self
|
|
79191
79435
|
end
|
|
79192
79436
|
function MSRS:SetCulture(Culture)
|
|
79437
|
+
self:F({Culture=Culture})
|
|
79193
79438
|
self.culture=Culture
|
|
79194
79439
|
return self
|
|
79195
79440
|
end
|
|
79196
79441
|
function MSRS:SetVoice(Voice)
|
|
79442
|
+
self:F({Voice=Voice})
|
|
79197
79443
|
self.voice=Voice
|
|
79198
79444
|
return self
|
|
79199
79445
|
end
|
|
79200
|
-
function MSRS:
|
|
79201
|
-
self
|
|
79202
|
-
|
|
79203
|
-
self.
|
|
79446
|
+
function MSRS:SetVoiceProvider(Voice,Provider)
|
|
79447
|
+
self:F({Voice=Voice,Provider=Provider})
|
|
79448
|
+
self.poptions=self.poptions or{}
|
|
79449
|
+
self.poptions[Provider or self:GetProvider()]=Voice
|
|
79450
|
+
return self
|
|
79451
|
+
end
|
|
79452
|
+
function MSRS:SetVoiceWindows(Voice)
|
|
79453
|
+
self:F({Voice=Voice})
|
|
79454
|
+
self:SetVoiceProvider(Voice or"Microsoft Hazel Desktop",MSRS.Provider.WINDOWS)
|
|
79455
|
+
return self
|
|
79456
|
+
end
|
|
79457
|
+
function MSRS:SetVoiceGoogle(Voice)
|
|
79458
|
+
self:F({Voice=Voice})
|
|
79459
|
+
self:SetVoiceProvider(Voice or MSRS.Voices.Google.Standard.en_GB_Standard_A,MSRS.Provider.GOOGLE)
|
|
79460
|
+
return self
|
|
79461
|
+
end
|
|
79462
|
+
function MSRS:SetVoiceAzure(Voice)
|
|
79463
|
+
self:F({Voice=Voice})
|
|
79464
|
+
self:SetVoiceProvider(Voice or"en-US-AriaNeural",MSRS.Provider.AZURE)
|
|
79465
|
+
return self
|
|
79466
|
+
end
|
|
79467
|
+
function MSRS:SetVoiceAmazon(Voice)
|
|
79468
|
+
self:F({Voice=Voice})
|
|
79469
|
+
self:SetVoiceProvider(Voice or"Brian",MSRS.Provider.AMAZON)
|
|
79204
79470
|
return self
|
|
79205
79471
|
end
|
|
79472
|
+
function MSRS:GetVoice(Provider)
|
|
79473
|
+
Provider=Provider or self.provider
|
|
79474
|
+
if Provider and self.poptions[Provider]and self.poptions[Provider].voice then
|
|
79475
|
+
return self.poptions[Provider].voice
|
|
79476
|
+
else
|
|
79477
|
+
return self.voice
|
|
79478
|
+
end
|
|
79479
|
+
end
|
|
79206
79480
|
function MSRS:SetCoordinate(Coordinate)
|
|
79481
|
+
self:F(Coordinate)
|
|
79207
79482
|
self.coordinate=Coordinate
|
|
79208
79483
|
return self
|
|
79209
79484
|
end
|
|
79210
79485
|
function MSRS:SetGoogle(PathToCredentials)
|
|
79486
|
+
self:F({PathToCredentials=PathToCredentials})
|
|
79211
79487
|
if PathToCredentials then
|
|
79212
|
-
self.
|
|
79213
|
-
self
|
|
79214
|
-
self.provider="gcloud"
|
|
79215
|
-
self.GRPCOptions.DefaultProvider="gcloud"
|
|
79216
|
-
self.GRPCOptions.gcloud.key=PathToCredentials
|
|
79217
|
-
self.ttsprovider="Google"
|
|
79488
|
+
self.provider=MSRS.Provider.GOOGLE
|
|
79489
|
+
self:SetProviderOptionsGoogle(PathToCredentials,PathToCredentials)
|
|
79218
79490
|
end
|
|
79219
79491
|
return self
|
|
79220
79492
|
end
|
|
79221
79493
|
function MSRS:SetGoogleAPIKey(APIKey)
|
|
79494
|
+
self:F({APIKey=APIKey})
|
|
79222
79495
|
if APIKey then
|
|
79223
|
-
self.
|
|
79224
|
-
self.
|
|
79225
|
-
self.
|
|
79226
|
-
|
|
79496
|
+
self.provider=MSRS.Provider.GOOGLE
|
|
79497
|
+
if self.poptions[MSRS.Provider.GOOGLE]then
|
|
79498
|
+
self.poptions[MSRS.Provider.GOOGLE].key=APIKey
|
|
79499
|
+
else
|
|
79500
|
+
self:SetProviderOptionsGoogle(nil,APIKey)
|
|
79501
|
+
end
|
|
79502
|
+
end
|
|
79503
|
+
return self
|
|
79504
|
+
end
|
|
79505
|
+
function MSRS:SetProvider(Provider)
|
|
79506
|
+
self:F({Provider=Provider})
|
|
79507
|
+
self.provider=Provider or MSRS.Provider.WINDOWS
|
|
79508
|
+
return self
|
|
79509
|
+
end
|
|
79510
|
+
function MSRS:GetProvider()
|
|
79511
|
+
return self.provider or MSRS.Provider.WINDOWS
|
|
79512
|
+
end
|
|
79513
|
+
function MSRS:SetProviderOptions(Provider,CredentialsFile,AccessKey,SecretKey,Region)
|
|
79514
|
+
self:F({Provider,CredentialsFile,AccessKey,SecretKey,Region})
|
|
79515
|
+
local option=MSRS._CreateProviderOptions(Provider,CredentialsFile,AccessKey,SecretKey,Region)
|
|
79516
|
+
if self then
|
|
79517
|
+
self.poptions=self.poptions or{}
|
|
79518
|
+
self.poptions[Provider]=option
|
|
79519
|
+
else
|
|
79520
|
+
MSRS.poptions=MSRS.poptions or{}
|
|
79521
|
+
MSRS.poptions[Provider]=option
|
|
79522
|
+
end
|
|
79523
|
+
return option
|
|
79524
|
+
end
|
|
79525
|
+
function MSRS._CreateProviderOptions(Provider,CredentialsFile,AccessKey,SecretKey,Region)
|
|
79526
|
+
self:F({Provider,CredentialsFile,AccessKey,SecretKey,Region})
|
|
79527
|
+
local option={}
|
|
79528
|
+
option.provider=Provider
|
|
79529
|
+
option.credentials=CredentialsFile
|
|
79530
|
+
option.key=AccessKey
|
|
79531
|
+
option.secret=SecretKey
|
|
79532
|
+
option.region=Region
|
|
79533
|
+
return option
|
|
79534
|
+
end
|
|
79535
|
+
function MSRS:SetProviderOptionsGoogle(CredentialsFile,AccessKey)
|
|
79536
|
+
self:F({CredentialsFile,AccessKey})
|
|
79537
|
+
self:SetProviderOptions(MSRS.Provider.GOOGLE,CredentialsFile,AccessKey)
|
|
79538
|
+
return self
|
|
79539
|
+
end
|
|
79540
|
+
function MSRS:SetProviderOptionsAmazon(AccessKey,SecretKey,Region)
|
|
79541
|
+
self:F({AccessKey,SecretKey,Region})
|
|
79542
|
+
self:SetProviderOptions(MSRS.Provider.AMAZON,nil,AccessKey,SecretKey,Region)
|
|
79543
|
+
return self
|
|
79227
79544
|
end
|
|
79545
|
+
function MSRS:SetProviderOptionsAzure(AccessKey,Region)
|
|
79546
|
+
self:F({AccessKey,Region})
|
|
79547
|
+
self:SetProviderOptions(MSRS.Provider.AZURE,nil,AccessKey,nil,Region)
|
|
79228
79548
|
return self
|
|
79229
79549
|
end
|
|
79550
|
+
function MSRS:GetProviderOptions(Provider)
|
|
79551
|
+
return self.poptions[Provider or self.provider]or{}
|
|
79552
|
+
end
|
|
79230
79553
|
function MSRS:SetTTSProviderGoogle()
|
|
79231
|
-
self
|
|
79554
|
+
self:F()
|
|
79555
|
+
self:SetProvider(MSRS.Provider.GOOGLE)
|
|
79232
79556
|
return self
|
|
79233
79557
|
end
|
|
79234
79558
|
function MSRS:SetTTSProviderMicrosoft()
|
|
79235
|
-
self
|
|
79559
|
+
self:F()
|
|
79560
|
+
self:SetProvider(MSRS.Provider.WINDOWS)
|
|
79561
|
+
return self
|
|
79562
|
+
end
|
|
79563
|
+
function MSRS:SetTTSProviderAzure()
|
|
79564
|
+
self:F()
|
|
79565
|
+
self:SetProvider(MSRS.Provider.AZURE)
|
|
79566
|
+
return self
|
|
79567
|
+
end
|
|
79568
|
+
function MSRS:SetTTSProviderAmazon()
|
|
79569
|
+
self:F()
|
|
79570
|
+
self:SetProvider(MSRS.Provider.AMAZON)
|
|
79236
79571
|
return self
|
|
79237
79572
|
end
|
|
79238
79573
|
function MSRS:Help()
|
|
79239
|
-
|
|
79240
|
-
local
|
|
79241
|
-
local
|
|
79574
|
+
self:F()
|
|
79575
|
+
local path=self:GetPath()
|
|
79576
|
+
local exe="DCS-SR-ExternalAudio.exe"
|
|
79577
|
+
local filename=os.getenv('TMP').."\\MSRS-help-"..MSRS.uuid()..".txt"
|
|
79242
79578
|
local command=string.format("%s/%s --help > %s",path,exe,filename)
|
|
79243
79579
|
os.execute(command)
|
|
79244
79580
|
local f=assert(io.open(filename,"rb"))
|
|
79245
79581
|
local data=f:read("*all")
|
|
79246
79582
|
f:close()
|
|
79247
|
-
env.info("SRS
|
|
79583
|
+
env.info("SRS help output:")
|
|
79248
79584
|
env.info("======================================================================")
|
|
79249
79585
|
env.info(data)
|
|
79250
79586
|
env.info("======================================================================")
|
|
79251
79587
|
return self
|
|
79252
79588
|
end
|
|
79253
|
-
function MSRS.SetDefaultBackend(Backend)
|
|
79254
|
-
if type(Backend)=="table"then
|
|
79255
|
-
MSRS.AltBackend=UTILS.DeepCopy(Backend)
|
|
79256
|
-
else
|
|
79257
|
-
return false
|
|
79258
|
-
end
|
|
79259
|
-
return true
|
|
79260
|
-
end
|
|
79261
|
-
function MSRS.ResetDefaultBackend()
|
|
79262
|
-
MSRS.AltBackend=nil
|
|
79263
|
-
return true
|
|
79264
|
-
end
|
|
79265
|
-
function MSRS.SetDefaultBackendGRPC()
|
|
79266
|
-
return MSRS.SetDefaultBackend(MSRS_BACKEND_DCSGRPC)
|
|
79267
|
-
end
|
|
79268
79589
|
function MSRS:PlaySoundFile(Soundfile,Delay)
|
|
79590
|
+
self:F({Soundfile,Delay})
|
|
79591
|
+
local soundfile=Soundfile:GetName()
|
|
79592
|
+
local exists=UTILS.FileExists(soundfile)
|
|
79593
|
+
if not exists then
|
|
79594
|
+
self:E("ERROR: MSRS sound file does not exist! File="..soundfile)
|
|
79595
|
+
return self
|
|
79596
|
+
end
|
|
79269
79597
|
if Delay and Delay>0 then
|
|
79270
79598
|
self:ScheduleOnce(Delay,MSRS.PlaySoundFile,self,Soundfile,0)
|
|
79271
79599
|
else
|
|
79272
|
-
local soundfile=Soundfile:GetName()
|
|
79273
79600
|
local command=self:_GetCommand()
|
|
79274
79601
|
command=command..' --file="'..tostring(soundfile)..'"'
|
|
79275
79602
|
self:_ExecCommand(command)
|
|
@@ -79277,42 +79604,53 @@ end
|
|
|
79277
79604
|
return self
|
|
79278
79605
|
end
|
|
79279
79606
|
function MSRS:PlaySoundText(SoundText,Delay)
|
|
79607
|
+
self:F({SoundText,Delay})
|
|
79280
79608
|
if Delay and Delay>0 then
|
|
79281
79609
|
self:ScheduleOnce(Delay,MSRS.PlaySoundText,self,SoundText,0)
|
|
79282
79610
|
else
|
|
79611
|
+
if self.backend==MSRS.Backend.GRPC then
|
|
79612
|
+
self:_DCSgRPCtts(SoundText.text,nil,SoundText.gender,SoundText.culture,SoundText.voice,SoundText.volume,SoundText.label,SoundText.coordinate)
|
|
79613
|
+
else
|
|
79283
79614
|
local command=self:_GetCommand(nil,nil,nil,SoundText.gender,SoundText.voice,SoundText.culture,SoundText.volume,SoundText.speed)
|
|
79284
79615
|
command=command..string.format(" --text=\"%s\"",tostring(SoundText.text))
|
|
79285
79616
|
self:_ExecCommand(command)
|
|
79286
79617
|
end
|
|
79618
|
+
end
|
|
79287
79619
|
return self
|
|
79288
79620
|
end
|
|
79289
79621
|
function MSRS:PlayText(Text,Delay,Coordinate)
|
|
79622
|
+
self:F({Text,Delay,Coordinate})
|
|
79290
79623
|
if Delay and Delay>0 then
|
|
79291
79624
|
self:ScheduleOnce(Delay,MSRS.PlayText,self,Text,nil,Coordinate)
|
|
79292
79625
|
else
|
|
79293
|
-
|
|
79294
|
-
|
|
79295
|
-
self:
|
|
79626
|
+
if self.backend==MSRS.Backend.GRPC then
|
|
79627
|
+
self:T(self.lid.."Transmitting")
|
|
79628
|
+
self:_DCSgRPCtts(Text,nil,nil,nil,nil,nil,nil,Coordinate)
|
|
79629
|
+
else
|
|
79630
|
+
self:PlayTextExt(Text,Delay,nil,nil,nil,nil,nil,nil,nil,Coordinate)
|
|
79631
|
+
end
|
|
79296
79632
|
end
|
|
79297
79633
|
return self
|
|
79298
79634
|
end
|
|
79299
79635
|
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})
|
|
79300
79637
|
if Delay and Delay>0 then
|
|
79301
79638
|
self:ScheduleOnce(Delay,MSRS.PlayTextExt,self,Text,0,Frequencies,Modulations,Gender,Culture,Voice,Volume,Label,Coordinate)
|
|
79302
79639
|
else
|
|
79303
|
-
|
|
79304
|
-
|
|
79305
|
-
|
|
79306
|
-
|
|
79307
|
-
Modulations={Modulations}
|
|
79308
|
-
end
|
|
79309
|
-
local command=self:_GetCommand(Frequencies,Modulations,nil,Gender,Voice,Culture,Volume,nil,nil,Label,Coordinate)
|
|
79640
|
+
Frequencies=Frequencies or self:GetFrequencies()
|
|
79641
|
+
Modulations=Modulations or self:GetModulations()
|
|
79642
|
+
if self.backend==MSRS.Backend.SRSEXE then
|
|
79643
|
+
local command=self:_GetCommand(UTILS.EnsureTable(Frequencies,false),UTILS.EnsureTable(Modulations,false),nil,Gender,Voice,Culture,Volume,nil,nil,Label,Coordinate)
|
|
79310
79644
|
command=command..string.format(" --text=\"%s\"",tostring(Text))
|
|
79311
79645
|
self:_ExecCommand(command)
|
|
79646
|
+
elseif self.backend==MSRS.Backend.GRPC then
|
|
79647
|
+
self:_DCSgRPCtts(Text,Frequencies,Gender,Culture,Voice,Volume,Label,Coordinate)
|
|
79648
|
+
end
|
|
79312
79649
|
end
|
|
79313
79650
|
return self
|
|
79314
79651
|
end
|
|
79315
79652
|
function MSRS:PlayTextFile(TextFile,Delay)
|
|
79653
|
+
self:F({TextFile,Delay})
|
|
79316
79654
|
if Delay and Delay>0 then
|
|
79317
79655
|
self:ScheduleOnce(Delay,MSRS.PlayTextFile,self,TextFile,0)
|
|
79318
79656
|
else
|
|
@@ -79325,51 +79663,96 @@ local command=self:_GetCommand()
|
|
|
79325
79663
|
command=command..string.format(" --textFile=\"%s\"",tostring(TextFile))
|
|
79326
79664
|
self:T(string.format("MSRS TextFile command=%s",command))
|
|
79327
79665
|
local l=string.len(command)
|
|
79666
|
+
self:T(string.format("Command length=%d",l))
|
|
79328
79667
|
self:_ExecCommand(command)
|
|
79329
79668
|
end
|
|
79330
79669
|
return self
|
|
79331
79670
|
end
|
|
79332
|
-
function MSRS:
|
|
79333
|
-
|
|
79334
|
-
|
|
79335
|
-
|
|
79336
|
-
|
|
79337
|
-
|
|
79671
|
+
function MSRS:_GetLatLongAlt(Coordinate)
|
|
79672
|
+
self:F({Coordinate=Coordinate})
|
|
79673
|
+
local lat=0.0
|
|
79674
|
+
local lon=0.0
|
|
79675
|
+
local alt=0.0
|
|
79676
|
+
if Coordinate then
|
|
79677
|
+
lat,lon,alt=coord.LOtoLL(Coordinate)
|
|
79338
79678
|
end
|
|
79679
|
+
return lat,lon,math.floor(alt)
|
|
79339
79680
|
end
|
|
79340
|
-
|
|
79341
|
-
|
|
79342
|
-
self
|
|
79681
|
+
function MSRS:_GetCommand(freqs,modus,coal,gender,voice,culture,volume,speed,port,label,coordinate)
|
|
79682
|
+
self:F({freqs,modus,coal,gender,voice,culture,volume,speed,port,label,coordinate})
|
|
79683
|
+
local path=self:GetPath()
|
|
79684
|
+
local exe="DCS-SR-ExternalAudio.exe"
|
|
79685
|
+
local fullPath=string.format("%s\\%s",path,exe)
|
|
79686
|
+
freqs=table.concat(freqs or self.frequencies,",")
|
|
79687
|
+
modus=table.concat(modus or self.modulations,",")
|
|
79688
|
+
coal=coal or self.coalition
|
|
79689
|
+
gender=gender or self.gender
|
|
79690
|
+
voice=voice or self:GetVoice(self.provider)or self.voice
|
|
79691
|
+
culture=culture or self.culture
|
|
79692
|
+
volume=volume or self.volume
|
|
79693
|
+
speed=speed or self.speed
|
|
79694
|
+
port=port or self.port
|
|
79695
|
+
label=label or self.Label
|
|
79696
|
+
coordinate=coordinate or self.coordinate
|
|
79697
|
+
modus=modus:gsub("0","AM")
|
|
79698
|
+
modus=modus:gsub("1","FM")
|
|
79699
|
+
local command=string.format('"%s\\%s" -f "%s" -m "%s" -c %s -p %s -n "%s" -v "%.1f"',path,exe,freqs,modus,coal,port,label,volume)
|
|
79700
|
+
if voice then
|
|
79701
|
+
command=command..string.format(" --voice=\"%s\"",tostring(voice))
|
|
79702
|
+
else
|
|
79703
|
+
if gender and gender~="female"then
|
|
79704
|
+
command=command..string.format(" -g %s",tostring(gender))
|
|
79343
79705
|
end
|
|
79344
|
-
if
|
|
79345
|
-
|
|
79706
|
+
if culture and culture~="en-GB"then
|
|
79707
|
+
command=command..string.format(" -l %s",tostring(culture))
|
|
79346
79708
|
end
|
|
79347
|
-
|
|
79709
|
+
end
|
|
79710
|
+
if coordinate then
|
|
79711
|
+
local lat,lon,alt=self:_GetLatLongAlt(coordinate)
|
|
79712
|
+
command=command..string.format(" -L %.4f -O %.4f -A %d",lat,lon,alt)
|
|
79713
|
+
end
|
|
79714
|
+
if self.provider==MSRS.Provider.GOOGLE then
|
|
79715
|
+
local pops=self:GetProviderOptions()
|
|
79716
|
+
command=command..string.format(' --ssml -G "%s"',pops.credentials)
|
|
79717
|
+
elseif self.provider==MSRS.Provider.WINDOWS then
|
|
79718
|
+
else
|
|
79719
|
+
self:E("ERROR: SRS only supports WINWOWS and GOOGLE as TTS providers! Use DCS-gRPC backend for other providers such as ")
|
|
79720
|
+
end
|
|
79721
|
+
if not UTILS.FileExists(fullPath)then
|
|
79722
|
+
self:E("ERROR: MSRS SRS executable does not exist! FullPath="..fullPath)
|
|
79723
|
+
command="CommandNotFound"
|
|
79724
|
+
end
|
|
79725
|
+
self:T("MSRS command from _GetCommand="..command)
|
|
79726
|
+
return command
|
|
79348
79727
|
end
|
|
79349
79728
|
function MSRS:_ExecCommand(command)
|
|
79350
|
-
self:
|
|
79351
|
-
|
|
79729
|
+
self:F({command=command})
|
|
79730
|
+
if string.find(command,"CommandNotFound")then return 0 end
|
|
79731
|
+
local batContent=command.." && exit"
|
|
79732
|
+
local filename=os.getenv('TMP').."\\MSRS-"..MSRS.uuid()..".bat"
|
|
79352
79733
|
local script=io.open(filename,"w+")
|
|
79353
|
-
script:write(
|
|
79734
|
+
script:write(batContent)
|
|
79354
79735
|
script:close()
|
|
79355
|
-
|
|
79736
|
+
self:T("MSRS batch file created: "..filename)
|
|
79737
|
+
self:T("MSRS batch content: "..batContent)
|
|
79356
79738
|
local res=nil
|
|
79357
79739
|
if true then
|
|
79358
|
-
local filenvbs=os.getenv('TMP').."\\MSRS-"..
|
|
79740
|
+
local filenvbs=os.getenv('TMP').."\\MSRS-"..MSRS.uuid()..".vbs"
|
|
79359
79741
|
local script=io.open(filenvbs,"w+")
|
|
79360
79742
|
script:write(string.format('Dim WinScriptHost\n'))
|
|
79361
79743
|
script:write(string.format('Set WinScriptHost = CreateObject("WScript.Shell")\n'))
|
|
79362
79744
|
script:write(string.format('WinScriptHost.Run Chr(34) & "%s" & Chr(34), 0\n',filename))
|
|
79363
79745
|
script:write(string.format('Set WinScriptHost = Nothing'))
|
|
79364
79746
|
script:close()
|
|
79747
|
+
self:T("MSRS vbs file created to start batch="..filenvbs)
|
|
79365
79748
|
local runvbs=string.format('cscript.exe //Nologo //B "%s"',filenvbs)
|
|
79366
|
-
self:T("MSRS execute command="..command)
|
|
79367
79749
|
self:T("MSRS execute VBS command="..runvbs)
|
|
79368
79750
|
res=os.execute(runvbs)
|
|
79369
79751
|
timer.scheduleFunction(os.remove,filename,timer.getTime()+1)
|
|
79370
79752
|
timer.scheduleFunction(os.remove,filenvbs,timer.getTime()+1)
|
|
79753
|
+
self:T("MSRS vbs and batch file removed")
|
|
79371
79754
|
elseif false then
|
|
79372
|
-
local filenvbs=os.getenv('TMP').."\\MSRS-"..
|
|
79755
|
+
local filenvbs=os.getenv('TMP').."\\MSRS-"..MSRS.uuid()..".vbs"
|
|
79373
79756
|
local script=io.open(filenvbs,"w+")
|
|
79374
79757
|
script:write(string.format('Set oShell = CreateObject ("Wscript.Shell")\n'))
|
|
79375
79758
|
script:write(string.format('Dim strArgs\n'))
|
|
@@ -79379,52 +79762,53 @@ script:close()
|
|
|
79379
79762
|
local runvbs=string.format('cscript.exe //Nologo //B "%s"',filenvbs)
|
|
79380
79763
|
res=os.execute(runvbs)
|
|
79381
79764
|
else
|
|
79765
|
+
command=string.format('start /b "" "%s"',filename)
|
|
79382
79766
|
self:T("MSRS execute command="..command)
|
|
79383
79767
|
res=os.execute(command)
|
|
79384
79768
|
timer.scheduleFunction(os.remove,filename,timer.getTime()+1)
|
|
79385
79769
|
end
|
|
79386
79770
|
return res
|
|
79387
79771
|
end
|
|
79388
|
-
function MSRS:
|
|
79389
|
-
|
|
79390
|
-
|
|
79772
|
+
function MSRS:_DCSgRPCtts(Text,Frequencies,Gender,Culture,Voice,Volume,Label,Coordinate)
|
|
79773
|
+
self:F("MSRS_BACKEND_DCSGRPC:_DCSgRPCtts()")
|
|
79774
|
+
self:F({Text,Frequencies,Gender,Culture,Voice,Volume,Label,Coordinate})
|
|
79775
|
+
local options={}
|
|
79776
|
+
local ssml=Text or''
|
|
79777
|
+
Frequencies=UTILS.EnsureTable(Frequencies,true)or self:GetFrequencies()
|
|
79778
|
+
options.plaintext=Text
|
|
79779
|
+
options.srsClientName=Label or self.Label
|
|
79780
|
+
if self.coordinate then
|
|
79781
|
+
options.position={}
|
|
79782
|
+
options.position.lat,options.position.lon,options.position.alt=self:_GetLatLongAlt(self.coordinate)
|
|
79391
79783
|
end
|
|
79392
|
-
|
|
79393
|
-
local
|
|
79394
|
-
|
|
79395
|
-
|
|
79396
|
-
|
|
79397
|
-
|
|
79398
|
-
|
|
79399
|
-
voice=
|
|
79400
|
-
culture=culture or self.culture
|
|
79401
|
-
volume=volume or self.volume
|
|
79402
|
-
speed=speed or self.speed
|
|
79403
|
-
port=port or self.port
|
|
79404
|
-
label=label or self.Label
|
|
79405
|
-
coordinate=coordinate or self.coordinate
|
|
79406
|
-
modus=modus:gsub("0","AM")
|
|
79407
|
-
modus=modus:gsub("1","FM")
|
|
79408
|
-
local command=string.format('"%s\\%s" -f "%s" -m "%s" -c %s -p %s -n "%s" -v "%.1f"',path,exe,freqs,modus,coal,port,label,volume)
|
|
79409
|
-
if voice then
|
|
79410
|
-
command=command..string.format(" --voice=\"%s\"",tostring(voice))
|
|
79784
|
+
options.coalition=UTILS.GetCoalitionName(self.coalition):lower()
|
|
79785
|
+
local provider=self.provider or MSRS.Provider.WINDOWS
|
|
79786
|
+
self:F({provider=provider})
|
|
79787
|
+
options.provider={}
|
|
79788
|
+
options.provider[provider]=self:GetProviderOptions(provider)
|
|
79789
|
+
Voice=Voice or self:GetVoice(self.provider)or self.voice
|
|
79790
|
+
if Voice then
|
|
79791
|
+
options.provider[provider].voice=Voice
|
|
79411
79792
|
else
|
|
79412
|
-
|
|
79413
|
-
|
|
79793
|
+
local preTag,genderProp,langProp,postTag='','','',''
|
|
79794
|
+
local gender=""
|
|
79795
|
+
if self.gender then
|
|
79796
|
+
gender=string.format(' gender=\"%s\"',self.gender)
|
|
79414
79797
|
end
|
|
79415
|
-
|
|
79416
|
-
|
|
79798
|
+
local language=""
|
|
79799
|
+
if self.culture then
|
|
79800
|
+
language=string.format(' language=\"%s\"',self.culture)
|
|
79417
79801
|
end
|
|
79802
|
+
if self.gender or self.culture then
|
|
79803
|
+
ssml=string.format("<voice%s%s>%s</voice>",gender,language,Text)
|
|
79418
79804
|
end
|
|
79419
|
-
if coordinate then
|
|
79420
|
-
local lat,lon,alt=self:_GetLatLongAlt(coordinate)
|
|
79421
|
-
command=command..string.format(" -L %.4f -O %.4f -A %d",lat,lon,alt)
|
|
79422
79805
|
end
|
|
79423
|
-
|
|
79424
|
-
|
|
79806
|
+
for _,freq in pairs(Frequencies)do
|
|
79807
|
+
self:F("Calling GRPC.tts with the following parameter:")
|
|
79808
|
+
self:F({ssml=ssml,freq=freq,options=options})
|
|
79809
|
+
self:F(options.provider[provider])
|
|
79810
|
+
GRPC.tts(ssml,freq*1e6,options)
|
|
79425
79811
|
end
|
|
79426
|
-
self:T("MSRS command="..command)
|
|
79427
|
-
return command
|
|
79428
79812
|
end
|
|
79429
79813
|
function MSRS:LoadConfigFile(Path,Filename)
|
|
79430
79814
|
if lfs==nil then
|
|
@@ -79436,63 +79820,30 @@ local file=Filename or MSRS.ConfigFileName or"Moose_MSRS.lua"
|
|
|
79436
79820
|
local pathandfile=path..file
|
|
79437
79821
|
local filexsists=UTILS.FileExists(pathandfile)
|
|
79438
79822
|
if filexsists and not MSRS.ConfigLoaded then
|
|
79823
|
+
env.info("FF reading config file")
|
|
79439
79824
|
assert(loadfile(path..file))()
|
|
79440
79825
|
if MSRS_Config then
|
|
79441
|
-
|
|
79442
|
-
|
|
79443
|
-
|
|
79444
|
-
|
|
79445
|
-
|
|
79446
|
-
|
|
79826
|
+
local Self=self or MSRS
|
|
79827
|
+
Self.path=MSRS_Config.Path or"C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
|
79828
|
+
Self.port=MSRS_Config.Port or 5002
|
|
79829
|
+
Self.backend=MSRS_Config.Backend or MSRS.Backend.SRSEXE
|
|
79830
|
+
Self.frequencies=MSRS_Config.Frequency or{127,243}
|
|
79831
|
+
Self.modulations=MSRS_Config.Modulation or{0,0}
|
|
79832
|
+
Self.coalition=MSRS_Config.Coalition or 0
|
|
79447
79833
|
if MSRS_Config.Coordinate then
|
|
79448
|
-
|
|
79449
|
-
end
|
|
79450
|
-
self.culture=MSRS_Config.Culture or"en-GB"
|
|
79451
|
-
self.gender=MSRS_Config.Gender or"male"
|
|
79452
|
-
self.google=MSRS_Config.Google
|
|
79453
|
-
if MSRS_Config.Provider then
|
|
79454
|
-
self.ttsprovider=MSRS_Config.Provider
|
|
79455
|
-
end
|
|
79456
|
-
self.Label=MSRS_Config.Label or"MSRS"
|
|
79457
|
-
self.voice=MSRS_Config.Voice
|
|
79458
|
-
if MSRS_Config.GRPC then
|
|
79459
|
-
self.provider=MSRS_Config.GRPC.DefaultProvider
|
|
79460
|
-
if MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider]then
|
|
79461
|
-
self.APIKey=MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].key
|
|
79462
|
-
self.defaultVoice=MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].defaultVoice
|
|
79463
|
-
self.region=MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].secret
|
|
79464
|
-
self.secret=MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].region
|
|
79465
|
-
end
|
|
79466
|
-
end
|
|
79467
|
-
self.ConfigLoaded=true
|
|
79468
|
-
else
|
|
79469
|
-
MSRS.path=MSRS_Config.Path or"C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
|
79470
|
-
MSRS.port=MSRS_Config.Port or 5002
|
|
79471
|
-
MSRS.frequencies=MSRS_Config.Frequency or{127,243}
|
|
79472
|
-
MSRS.modulations=MSRS_Config.Modulation or{0,0}
|
|
79473
|
-
MSRS.coalition=MSRS_Config.Coalition or 0
|
|
79474
|
-
if MSRS_Config.Coordinate then
|
|
79475
|
-
MSRS.coordinate=COORDINATE:New(MSRS_Config.Coordinate[1],MSRS_Config.Coordinate[2],MSRS_Config.Coordinate[3])
|
|
79476
|
-
end
|
|
79477
|
-
MSRS.culture=MSRS_Config.Culture or"en-GB"
|
|
79478
|
-
MSRS.gender=MSRS_Config.Gender or"male"
|
|
79479
|
-
MSRS.google=MSRS_Config.Google
|
|
79480
|
-
if MSRS_Config.Provider then
|
|
79481
|
-
MSRS.ttsprovider=MSRS_Config.Provider
|
|
79482
|
-
end
|
|
79483
|
-
MSRS.Label=MSRS_Config.Label or"MSRS"
|
|
79484
|
-
MSRS.voice=MSRS_Config.Voice
|
|
79485
|
-
if MSRS_Config.GRPC then
|
|
79486
|
-
MSRS.provider=MSRS_Config.GRPC.DefaultProvider
|
|
79487
|
-
if MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider]then
|
|
79488
|
-
MSRS.APIKey=MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].key
|
|
79489
|
-
MSRS.defaultVoice=MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].defaultVoice
|
|
79490
|
-
MSRS.region=MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].secret
|
|
79491
|
-
MSRS.secret=MSRS_Config.GRPC[MSRS_Config.GRPC.DefaultProvider].region
|
|
79834
|
+
Self.coordinate=COORDINATE:New(MSRS_Config.Coordinate[1],MSRS_Config.Coordinate[2],MSRS_Config.Coordinate[3])
|
|
79492
79835
|
end
|
|
79836
|
+
Self.culture=MSRS_Config.Culture or"en-GB"
|
|
79837
|
+
Self.gender=MSRS_Config.Gender or"male"
|
|
79838
|
+
Self.Label=MSRS_Config.Label or"MSRS"
|
|
79839
|
+
Self.voice=MSRS_Config.Voice
|
|
79840
|
+
Self.provider=MSRS_Config.Provider or MSRS.Provider.WINDOWS
|
|
79841
|
+
for _,provider in pairs(MSRS.Provider)do
|
|
79842
|
+
if MSRS_Config[provider]then
|
|
79843
|
+
Self.poptions[provider]=MSRS_Config[provider]
|
|
79493
79844
|
end
|
|
79494
|
-
MSRS.ConfigLoaded=true
|
|
79495
79845
|
end
|
|
79846
|
+
Self.ConfigLoaded=true
|
|
79496
79847
|
end
|
|
79497
79848
|
env.info("MSRS - Successfully loaded default configuration from disk!",false)
|
|
79498
79849
|
end
|
|
@@ -79502,151 +79853,27 @@ return false
|
|
|
79502
79853
|
end
|
|
79503
79854
|
return true
|
|
79504
79855
|
end
|
|
79505
|
-
|
|
79506
|
-
|
|
79507
|
-
|
|
79508
|
-
|
|
79509
|
-
|
|
79510
|
-
|
|
79511
|
-
|
|
79512
|
-
end
|
|
79513
|
-
MSRS_BACKEND_DCSGRPC.Functions.SetPath=function(self)
|
|
79514
|
-
return self
|
|
79515
|
-
end
|
|
79516
|
-
MSRS_BACKEND_DCSGRPC.Functions.GetPath=function(self)
|
|
79517
|
-
return''
|
|
79518
|
-
end
|
|
79519
|
-
MSRS_BACKEND_DCSGRPC.Functions.SetVolume=function(self)
|
|
79520
|
-
BASE:I('NOTE: MSRS:SetVolume() not used with DCS-gRPC backend.')
|
|
79521
|
-
return self
|
|
79522
|
-
end
|
|
79523
|
-
MSRS_BACKEND_DCSGRPC.Functions.GetVolume=function(self)
|
|
79524
|
-
BASE:I('NOTE: MSRS:GetVolume() not used with DCS-gRPC backend.')
|
|
79525
|
-
return 1
|
|
79526
|
-
end
|
|
79527
|
-
MSRS_BACKEND_DCSGRPC.Functions.SetGender=function(self,Gender)
|
|
79528
|
-
if Gender then
|
|
79529
|
-
self.gender=Gender:lower()
|
|
79530
|
-
end
|
|
79531
|
-
self:T("Setting gender to "..tostring(self.gender))
|
|
79532
|
-
return self
|
|
79533
|
-
end
|
|
79534
|
-
MSRS_BACKEND_DCSGRPC.Functions.SetGoogle=function(self)
|
|
79535
|
-
self.provider='gcloud'
|
|
79536
|
-
return self
|
|
79537
|
-
end
|
|
79538
|
-
MSRS_BACKEND_DCSGRPC.Functions.SetAPIKey=function(self,key)
|
|
79539
|
-
self.APIKey=key
|
|
79540
|
-
return self
|
|
79541
|
-
end
|
|
79542
|
-
MSRS_BACKEND_DCSGRPC.Functions.SetDefaultVoice=function(self,voice)
|
|
79543
|
-
self.defaultVoice=voice
|
|
79544
|
-
return self
|
|
79545
|
-
end
|
|
79546
|
-
MSRS_BACKEND_DCSGRPC.Functions.SetAWS=function(self)
|
|
79547
|
-
self.provider='aws'
|
|
79548
|
-
return self
|
|
79549
|
-
end
|
|
79550
|
-
MSRS_BACKEND_DCSGRPC.Functions.SetAzure=function(self)
|
|
79551
|
-
self.provider='azure'
|
|
79552
|
-
return self
|
|
79553
|
-
end
|
|
79554
|
-
MSRS_BACKEND_DCSGRPC.Functions.SetWin=function(self)
|
|
79555
|
-
self.provider='win'
|
|
79556
|
-
return self
|
|
79557
|
-
end
|
|
79558
|
-
MSRS_BACKEND_DCSGRPC.Functions.Help=function(self)
|
|
79559
|
-
env.info('For DCS-gRPC help, please see: https://github.com/DCS-gRPC/rust-server')
|
|
79560
|
-
return self
|
|
79561
|
-
end
|
|
79562
|
-
MSRS_BACKEND_DCSGRPC.Functions.PlaySoundFile=function(self)
|
|
79563
|
-
BASE:E("ERROR: MSRS:PlaySoundFile() is not supported by the DCS-gRPC backend.")
|
|
79564
|
-
return self
|
|
79565
|
-
end
|
|
79566
|
-
MSRS_BACKEND_DCSGRPC.Functions.PlaySoundText=function(self,SoundText,Delay)
|
|
79567
|
-
if Delay and Delay>0 then
|
|
79568
|
-
self:ScheduleOnce(Delay,self.PlaySoundText,self,SoundText,0)
|
|
79569
|
-
else
|
|
79570
|
-
self:_DCSgRPCtts(tostring(SoundText.text))
|
|
79571
|
-
end
|
|
79572
|
-
return self
|
|
79573
|
-
end
|
|
79574
|
-
MSRS_BACKEND_DCSGRPC.Functions.PlayText=function(self,Text,Delay)
|
|
79575
|
-
if Delay and Delay>0 then
|
|
79576
|
-
self:ScheduleOnce(Delay,self.PlayText,self,Text,0)
|
|
79577
|
-
else
|
|
79578
|
-
self:_DCSgRPCtts(tostring(Text))
|
|
79579
|
-
end
|
|
79580
|
-
return self
|
|
79581
|
-
end
|
|
79582
|
-
MSRS_BACKEND_DCSGRPC.Functions.PlayTextExt=function(self,Text,Delay,Frequencies,Modulations,Gender,Culture,Voice,Volume,Label)
|
|
79583
|
-
if Delay and Delay>0 then
|
|
79584
|
-
self:ScheduleOnce(Delay,self.PlayTextExt,self,Text,0,Frequencies,Modulations,Gender,Culture,Voice,Volume,Label)
|
|
79856
|
+
function MSRS.getSpeechTime(length,speed,isGoogle)
|
|
79857
|
+
local maxRateRatio=3
|
|
79858
|
+
speed=speed or 1.0
|
|
79859
|
+
isGoogle=isGoogle or false
|
|
79860
|
+
local speedFactor=1.0
|
|
79861
|
+
if isGoogle then
|
|
79862
|
+
speedFactor=speed
|
|
79585
79863
|
else
|
|
79586
|
-
|
|
79587
|
-
|
|
79588
|
-
return self
|
|
79589
|
-
end
|
|
79590
|
-
MSRS_BACKEND_DCSGRPC.Functions.PlayTextFile=function(self,TextFile,Delay)
|
|
79591
|
-
BASE:E("ERROR: MSRS:PlayTextFile() is not supported by the DCS-gRPC backend.")
|
|
79592
|
-
return self
|
|
79593
|
-
end
|
|
79594
|
-
MSRS_BACKEND_DCSGRPC.Functions._DCSgRPCtts=function(self,Text,Plaintext,Frequencies,Voice,Label)
|
|
79595
|
-
BASE:T("MSRS_BACKEND_DCSGRPC:_DCSgRPCtts()")
|
|
79596
|
-
BASE:T({Text,Plaintext,Frequencies,Voice,Label})
|
|
79597
|
-
local options=self.ProviderOptions or MSRS.ProviderOptions or{}
|
|
79598
|
-
local ssml=Text or''
|
|
79599
|
-
local XmitFrequencies=Frequencies or self.Frequency
|
|
79600
|
-
if type(XmitFrequencies)~="table"then
|
|
79601
|
-
XmitFrequencies={XmitFrequencies}
|
|
79602
|
-
end
|
|
79603
|
-
options.plaintext=Plaintext
|
|
79604
|
-
options.srsClientName=Label or self.Label
|
|
79605
|
-
options.position={}
|
|
79606
|
-
if self.coordinate then
|
|
79607
|
-
options.position.lat,options.position.lon,options.position.alt=self:_GetLatLongAlt(self.coordinate)
|
|
79608
|
-
end
|
|
79609
|
-
options.position.lat=options.position.lat or 0.0
|
|
79610
|
-
options.position.lon=options.position.lon or 0.0
|
|
79611
|
-
options.position.alt=options.position.alt or 0.0
|
|
79612
|
-
if UTILS.GetCoalitionName(self.coalition)=='Blue'then
|
|
79613
|
-
options.coalition='blue'
|
|
79614
|
-
elseif UTILS.GetCoalitionName(self.coalition)=='Red'then
|
|
79615
|
-
options.coalition='red'
|
|
79616
|
-
end
|
|
79617
|
-
local provider=self.provider or self.GRPCOptions.DefaultProvider or MSRS.GRPCOptions.DefaultProvider
|
|
79618
|
-
options.provider={}
|
|
79619
|
-
options.provider[provider]={}
|
|
79620
|
-
if self.APIKey then
|
|
79621
|
-
options.provider[provider].key=self.APIKey
|
|
79622
|
-
end
|
|
79623
|
-
if self.defaultVoice then
|
|
79624
|
-
options.provider[provider].defaultVoice=self.defaultVoice
|
|
79625
|
-
end
|
|
79626
|
-
if self.voice then
|
|
79627
|
-
options.provider[provider].voice=Voice or self.voice or self.defaultVoice
|
|
79628
|
-
elseif ssml then
|
|
79629
|
-
local preTag,genderProp,langProp,postTag='','','',''
|
|
79630
|
-
if self.gender then
|
|
79631
|
-
genderProp=' gender=\"'..self.gender..'\"'
|
|
79632
|
-
end
|
|
79633
|
-
if self.culture then
|
|
79634
|
-
langProp=' language=\"'..self.culture..'\"'
|
|
79864
|
+
if speed~=0 then
|
|
79865
|
+
speedFactor=math.abs(speed)*(maxRateRatio-1)/10+1
|
|
79635
79866
|
end
|
|
79636
|
-
if
|
|
79637
|
-
|
|
79638
|
-
postTag='</voice>'
|
|
79639
|
-
ssml=preTag..Text..postTag
|
|
79867
|
+
if speed<0 then
|
|
79868
|
+
speedFactor=1/speedFactor
|
|
79640
79869
|
end
|
|
79641
79870
|
end
|
|
79642
|
-
|
|
79643
|
-
local
|
|
79644
|
-
|
|
79645
|
-
|
|
79646
|
-
BASE:T(freq)
|
|
79647
|
-
BASE:T({options})
|
|
79648
|
-
GRPC.tts(ssml,freq,options)
|
|
79871
|
+
local wpm=math.ceil(100*speedFactor)
|
|
79872
|
+
local cps=math.floor((wpm*5)/60)
|
|
79873
|
+
if type(length)=="string"then
|
|
79874
|
+
length=string.len(length)
|
|
79649
79875
|
end
|
|
79876
|
+
return length/cps
|
|
79650
79877
|
end
|
|
79651
79878
|
MSRSQUEUE={
|
|
79652
79879
|
ClassName="MSRSQUEUE",
|
|
@@ -79707,7 +79934,7 @@ return nil
|
|
|
79707
79934
|
end
|
|
79708
79935
|
local transmission={}
|
|
79709
79936
|
transmission.text=text
|
|
79710
|
-
transmission.duration=duration or
|
|
79937
|
+
transmission.duration=duration or MSRS.getSpeechTime(text)
|
|
79711
79938
|
transmission.msrs=msrs
|
|
79712
79939
|
transmission.Tplay=tstart or timer.getAbsTime()
|
|
79713
79940
|
transmission.subtitle=subtitle
|