@jtff/miztemplate-lib 3.9.0 → 3.9.2
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 +39 -39
- package/lua/lib/Moose_.lua +956 -815
- package/lua/lib/Splash_Damage_main.lua +4 -2
- package/package.json +1 -1
package/lua/lib/Moose_.lua
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
env.info('*** MOOSE GITHUB Commit Hash ID: 2025-
|
|
1
|
+
env.info('*** MOOSE GITHUB Commit Hash ID: 2025-10-23T12:10:05+02:00-0f270a6a35ebcfe2430659092d934beeb495d489 ***')
|
|
2
2
|
if not MOOSE_DEVELOPMENT_FOLDER then
|
|
3
3
|
MOOSE_DEVELOPMENT_FOLDER='Scripts'
|
|
4
4
|
end
|
|
@@ -469,6 +469,7 @@ CH47={},
|
|
|
469
469
|
OH58={},
|
|
470
470
|
UH1H={},
|
|
471
471
|
AH64D={},
|
|
472
|
+
UH60L={},
|
|
472
473
|
}
|
|
473
474
|
}
|
|
474
475
|
ENUMS.Storage.weapons.nurs.SNEB_TYPE253_F1B="weapons.nurs.SNEB_TYPE253_F1B"
|
|
@@ -1172,6 +1173,24 @@ ENUMS.Storage.weapons.UH1H.M134_MiniGun_Right_Door={4,15,46,175}
|
|
|
1172
1173
|
ENUMS.Storage.weapons.UH1H.M60_MG_Right_Door={4,15,46,177}
|
|
1173
1174
|
ENUMS.Storage.weapons.UH1H.M134_MiniGun_Left_Door={4,15,46,174}
|
|
1174
1175
|
ENUMS.Storage.weapons.UH1H.M60_MG_Left_Door={4,15,46,176}
|
|
1176
|
+
ENUMS.Storage.weapons.UH60L.M151_HYDRA={4,7,33,147}
|
|
1177
|
+
ENUMS.Storage.weapons.UH60L.M156_HYDRA={4,7,33,148}
|
|
1178
|
+
ENUMS.Storage.weapons.UH60L.M229_HYDRA={4,7,33,148}
|
|
1179
|
+
ENUMS.Storage.weapons.UH60L.M257_HYDRA={4,7,33,151}
|
|
1180
|
+
ENUMS.Storage.weapons.UH60L.M259_HYDRA={4,7,33,151}
|
|
1181
|
+
ENUMS.Storage.weapons.UH60L.M274_HYDRA={4,7,33,150}
|
|
1182
|
+
ENUMS.Storage.weapons.UH60L.M134_DOOR_GUN={4,15,46,3031}
|
|
1183
|
+
ENUMS.Storage.weapons.UH60L.M3M={4,15,46,2496}
|
|
1184
|
+
ENUMS.Storage.weapons.UH60L.M3M_DOOR_GUN={4,15,46,3032}
|
|
1185
|
+
ENUMS.Storage.weapons.UH60L.M60_DOOR_GUN={4,15,46,3033}
|
|
1186
|
+
ENUMS.Storage.weapons.UH60L.FUEL_TANK_200={1,3,43,3023}
|
|
1187
|
+
ENUMS.Storage.weapons.UH60L.FUEL_TANK_230={1,3,43,3024}
|
|
1188
|
+
ENUMS.Storage.weapons.UH60L.FUEL_TANK_450={1,3,43,3025}
|
|
1189
|
+
ENUMS.Storage.weapons.UH60L.FUEL_TANK_DUAL_AUX={1,3,43,3026}
|
|
1190
|
+
ENUMS.Storage.weapons.UH60L.CARGO_SEAT_REAR_ROW={1,3,43,3030}
|
|
1191
|
+
ENUMS.Storage.weapons.UH60L.CARGO_SEAT_THREE_ROWS={1,3,43,3029}
|
|
1192
|
+
ENUMS.Storage.weapons.UH60L.EMPTY_GUNNER_SEAT_1={1,3,43,3027}
|
|
1193
|
+
ENUMS.Storage.weapons.UH60L.EMPTY_GUNNER_SEAT_2={1,3,43,3028}
|
|
1175
1194
|
ENUMS.Storage.weapons.OH58.FIM92={4,4,7,449}
|
|
1176
1195
|
ENUMS.Storage.weapons.OH58.MG_M3P100={4,15,46,2611}
|
|
1177
1196
|
ENUMS.Storage.weapons.OH58.MG_M3P200={4,15,46,2610}
|
|
@@ -2659,6 +2678,14 @@ if type_name=="UH-60L"and(unit:getDrawArgumentValue(38)>0 or unit:getDrawArgumen
|
|
|
2659
2678
|
BASE:T(unit_name.." front door(s) are open")
|
|
2660
2679
|
return true
|
|
2661
2680
|
end
|
|
2681
|
+
if type_name=="UH-60L_DAP"and(unit:getDrawArgumentValue(401)==1 or unit:getDrawArgumentValue(402)==1)then
|
|
2682
|
+
BASE:T(unit_name.." cargo door is open")
|
|
2683
|
+
return true
|
|
2684
|
+
end
|
|
2685
|
+
if type_name=="UH-60L_DAP"and(unit:getDrawArgumentValue(38)>0 or unit:getDrawArgumentValue(400)==1)then
|
|
2686
|
+
BASE:T(unit_name.." front door(s) are open")
|
|
2687
|
+
return true
|
|
2688
|
+
end
|
|
2662
2689
|
if type_name=="AH-64D_BLK_II"then
|
|
2663
2690
|
BASE:T(unit_name.." front door(s) are open")
|
|
2664
2691
|
return true
|
|
@@ -3860,7 +3887,55 @@ end
|
|
|
3860
3887
|
UTILS.lcg.seed=(UTILS.lcg.a*UTILS.lcg.seed+UTILS.lcg.c)%UTILS.lcg.m
|
|
3861
3888
|
return UTILS.lcg.seed/UTILS.lcg.m
|
|
3862
3889
|
end
|
|
3863
|
-
function UTILS.
|
|
3890
|
+
function UTILS.GenerateGridPoints(startVec2,n,spacingX,spacingY)
|
|
3891
|
+
local points={}
|
|
3892
|
+
local gridSize=math.ceil(math.sqrt(n))
|
|
3893
|
+
local count=0
|
|
3894
|
+
local n=n or 1
|
|
3895
|
+
local spacingX=spacingX or 100
|
|
3896
|
+
local spacingY=spacingY or 100
|
|
3897
|
+
local startX=startVec2.x or 100
|
|
3898
|
+
local startY=startVec2.y or 100
|
|
3899
|
+
for row=0,gridSize-1 do
|
|
3900
|
+
for col=0,gridSize-1 do
|
|
3901
|
+
if count>=n then
|
|
3902
|
+
break
|
|
3903
|
+
end
|
|
3904
|
+
local point={
|
|
3905
|
+
x=startX+(col*spacingX),
|
|
3906
|
+
y=startY+(row*spacingY)
|
|
3907
|
+
}
|
|
3908
|
+
table.insert(points,point)
|
|
3909
|
+
count=count+1
|
|
3910
|
+
end
|
|
3911
|
+
if count>=n then
|
|
3912
|
+
break
|
|
3913
|
+
end
|
|
3914
|
+
end
|
|
3915
|
+
return points
|
|
3916
|
+
end
|
|
3917
|
+
function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition,Country,CallSign,Frequency,Modulation,ADF,SpawnRadius,VehicleTemplate,Liquids,Equipment,Airframes,F10Text,DynamicSpawns,HotStart,NumberPads,SpacingX,SpacingY)
|
|
3918
|
+
local function PopulateStorage(Name,liquids,equip,airframes)
|
|
3919
|
+
local newWH=STORAGE:New(Name)
|
|
3920
|
+
if liquids and liquids>0 then
|
|
3921
|
+
newWH:SetLiquid(STORAGE.Liquid.DIESEL,liquids)
|
|
3922
|
+
newWH:SetLiquid(STORAGE.Liquid.GASOLINE,liquids)
|
|
3923
|
+
newWH:SetLiquid(STORAGE.Liquid.JETFUEL,liquids)
|
|
3924
|
+
newWH:SetLiquid(STORAGE.Liquid.MW50,liquids)
|
|
3925
|
+
end
|
|
3926
|
+
if equip and equip>0 then
|
|
3927
|
+
for cat,nitem in pairs(ENUMS.Storage.weapons)do
|
|
3928
|
+
for name,item in pairs(nitem)do
|
|
3929
|
+
newWH:SetItem(item,equip)
|
|
3930
|
+
end
|
|
3931
|
+
end
|
|
3932
|
+
end
|
|
3933
|
+
if airframes and airframes>0 then
|
|
3934
|
+
for typename in pairs(CSAR.AircraftType)do
|
|
3935
|
+
newWH:SetItem(typename,airframes)
|
|
3936
|
+
end
|
|
3937
|
+
end
|
|
3938
|
+
end
|
|
3864
3939
|
local farplocation=Coordinate
|
|
3865
3940
|
local farptype=FARPType or ENUMS.FARPType.FARP
|
|
3866
3941
|
local Coalition=Coalition or coalition.side.BLUE
|
|
@@ -3878,11 +3953,29 @@ local STypeName=statictypes.TypeName
|
|
|
3878
3953
|
local SShapeName=statictypes.ShapeName
|
|
3879
3954
|
local Country=Country or(Coalition==coalition.side.BLUE and country.id.USA or country.id.RUSSIA)
|
|
3880
3955
|
local ReturnObjects={}
|
|
3956
|
+
local NumberPads=NumberPads or 1
|
|
3957
|
+
local SpacingX=SpacingX or 100
|
|
3958
|
+
local SpacingY=SpacingY or 100
|
|
3959
|
+
local FarpVec2=Coordinate:GetVec2()
|
|
3960
|
+
if NumberPads>1 then
|
|
3961
|
+
local Grid=UTILS.GenerateGridPoints(FarpVec2,NumberPads,SpacingX,SpacingY)
|
|
3962
|
+
for id,gridpoint in ipairs(Grid)do
|
|
3963
|
+
local location=COORDINATE:NewFromVec2(gridpoint)
|
|
3964
|
+
local newfarp=SPAWNSTATIC:NewFromType(STypeName,"Heliports",Country)
|
|
3965
|
+
newfarp:InitShape(SShapeName)
|
|
3966
|
+
newfarp:InitFARP(callsign,freq,mod,DynamicSpawns,HotStart)
|
|
3967
|
+
local spawnedfarp=newfarp:SpawnFromCoordinate(location,0,Name.."-"..id)
|
|
3968
|
+
table.insert(ReturnObjects,spawnedfarp)
|
|
3969
|
+
PopulateStorage(Name.."-"..id,liquids,equip,airframes)
|
|
3970
|
+
end
|
|
3971
|
+
else
|
|
3881
3972
|
local newfarp=SPAWNSTATIC:NewFromType(STypeName,"Heliports",Country)
|
|
3882
3973
|
newfarp:InitShape(SShapeName)
|
|
3883
3974
|
newfarp:InitFARP(callsign,freq,mod,DynamicSpawns,HotStart)
|
|
3884
3975
|
local spawnedfarp=newfarp:SpawnFromCoordinate(farplocation,0,Name)
|
|
3885
3976
|
table.insert(ReturnObjects,spawnedfarp)
|
|
3977
|
+
PopulateStorage(Name,liquids,equip,airframes)
|
|
3978
|
+
end
|
|
3886
3979
|
local FARPStaticObjectsNato={
|
|
3887
3980
|
["FUEL"]={TypeName="FARP Fuel Depot",ShapeName="GSM Rus",Category="Fortifications"},
|
|
3888
3981
|
["AMMO"]={TypeName="FARP Ammo Dump Coating",ShapeName="SetkaKP",Category="Fortifications"},
|
|
@@ -3911,25 +4004,6 @@ vehicles:InitDelayOff()
|
|
|
3911
4004
|
local spawnedvehicle=vehicles:SpawnFromCoordinate(vcoordinate)
|
|
3912
4005
|
table.insert(ReturnObjects,spawnedvehicle)
|
|
3913
4006
|
end
|
|
3914
|
-
local newWH=STORAGE:New(Name)
|
|
3915
|
-
if liquids and liquids>0 then
|
|
3916
|
-
newWH:SetLiquid(STORAGE.Liquid.DIESEL,liquids)
|
|
3917
|
-
newWH:SetLiquid(STORAGE.Liquid.GASOLINE,liquids)
|
|
3918
|
-
newWH:SetLiquid(STORAGE.Liquid.JETFUEL,liquids)
|
|
3919
|
-
newWH:SetLiquid(STORAGE.Liquid.MW50,liquids)
|
|
3920
|
-
end
|
|
3921
|
-
if equip and equip>0 then
|
|
3922
|
-
for cat,nitem in pairs(ENUMS.Storage.weapons)do
|
|
3923
|
-
for name,item in pairs(nitem)do
|
|
3924
|
-
newWH:SetItem(item,equip)
|
|
3925
|
-
end
|
|
3926
|
-
end
|
|
3927
|
-
end
|
|
3928
|
-
if airframes and airframes>0 then
|
|
3929
|
-
for typename in pairs(CSAR.AircraftType)do
|
|
3930
|
-
newWH:SetItem(typename,airframes)
|
|
3931
|
-
end
|
|
3932
|
-
end
|
|
3933
4007
|
local ADFName
|
|
3934
4008
|
if ADF and type(ADF)=="number"then
|
|
3935
4009
|
local ADFFreq=ADF*1000
|
|
@@ -7726,10 +7800,12 @@ if Event.id==EVENTS.LandingAfterEjection then
|
|
|
7726
7800
|
else
|
|
7727
7801
|
if Event.place:isExist()and Object.getCategory(Event.place)~=Object.Category.SCENERY then
|
|
7728
7802
|
Event.Place=AIRBASE:Find(Event.place)
|
|
7803
|
+
if Event.Place then
|
|
7729
7804
|
Event.PlaceName=Event.Place:GetName()
|
|
7730
7805
|
end
|
|
7731
7806
|
end
|
|
7732
7807
|
end
|
|
7808
|
+
end
|
|
7733
7809
|
if Event.idx then
|
|
7734
7810
|
Event.MarkID=Event.idx
|
|
7735
7811
|
Event.MarkVec3=Event.pos
|
|
@@ -9553,10 +9629,9 @@ radius=ZoneRadius,
|
|
|
9553
9629
|
}
|
|
9554
9630
|
}
|
|
9555
9631
|
local function EvaluateZone(ZoneObject)
|
|
9556
|
-
if ZoneObject then
|
|
9632
|
+
if ZoneObject and self:IsVec3InZone(ZoneObject:getPoint())then
|
|
9557
9633
|
local ObjectCategory=Object.getCategory(ZoneObject)
|
|
9558
9634
|
if(ObjectCategory==Object.Category.UNIT and ZoneObject:isExist()and ZoneObject:isActive())or(ObjectCategory==Object.Category.STATIC and ZoneObject:isExist())then
|
|
9559
|
-
local CoalitionDCSUnit=ZoneObject:getCoalition()
|
|
9560
9635
|
local Include=false
|
|
9561
9636
|
if not UnitCategories then
|
|
9562
9637
|
Include=true
|
|
@@ -9918,6 +9993,16 @@ self.LastVec2=ZoneUNIT:GetVec2()
|
|
|
9918
9993
|
_EVENTDISPATCHER:CreateEventNewZone(self)
|
|
9919
9994
|
return self
|
|
9920
9995
|
end
|
|
9996
|
+
function ZONE_UNIT:UpdateFromUnit(Unit)
|
|
9997
|
+
if Unit and Unit:IsAlive()then
|
|
9998
|
+
local vec2=Unit:GetVec2()
|
|
9999
|
+
self.LastVec2=vec2
|
|
10000
|
+
elseif self.ZoneUNIT and self.ZoneUNIT:IsAlive()then
|
|
10001
|
+
local ZoneVec2=self.ZoneUNIT:GetVec2()
|
|
10002
|
+
self.LastVec2=ZoneVec2
|
|
10003
|
+
end
|
|
10004
|
+
return self
|
|
10005
|
+
end
|
|
9921
10006
|
function ZONE_UNIT:GetVec2()
|
|
9922
10007
|
local ZoneVec2=self.ZoneUNIT:GetVec2()
|
|
9923
10008
|
if ZoneVec2 then
|
|
@@ -9979,6 +10064,17 @@ ZoneVec2=self._.ZoneVec2Cache
|
|
|
9979
10064
|
end
|
|
9980
10065
|
return ZoneVec2
|
|
9981
10066
|
end
|
|
10067
|
+
function ZONE_GROUP:UpdateFromGroup(Group)
|
|
10068
|
+
if Group and Group:IsAlive()then
|
|
10069
|
+
local vec2=Group:GetVec2()
|
|
10070
|
+
self.Vec2=vec2
|
|
10071
|
+
elseif self._.ZoneGROUP and self._.ZoneGROUP:IsAlive()then
|
|
10072
|
+
local ZoneVec2=self._.ZoneGROUP:GetVec2()
|
|
10073
|
+
self.Vec2=ZoneVec2
|
|
10074
|
+
self._.ZoneVec2Cache=ZoneVec2
|
|
10075
|
+
end
|
|
10076
|
+
return self
|
|
10077
|
+
end
|
|
9982
10078
|
function ZONE_GROUP:GetRandomVec2()
|
|
9983
10079
|
local Point={}
|
|
9984
10080
|
local Vec2=self._.ZoneGROUP:GetVec2()
|
|
@@ -10607,10 +10703,9 @@ radius=ZoneRadius,
|
|
|
10607
10703
|
}
|
|
10608
10704
|
}
|
|
10609
10705
|
local function EvaluateZone(ZoneObject)
|
|
10610
|
-
if ZoneObject then
|
|
10706
|
+
if ZoneObject and self:IsVec3InZone(ZoneObject:getPoint())then
|
|
10611
10707
|
local ObjectCategory=Object.getCategory(ZoneObject)
|
|
10612
10708
|
if(ObjectCategory==Object.Category.UNIT and ZoneObject:isExist()and ZoneObject:isActive())or(ObjectCategory==Object.Category.STATIC and ZoneObject:isExist())then
|
|
10613
|
-
local CoalitionDCSUnit=ZoneObject:getCoalition()
|
|
10614
10709
|
local Include=false
|
|
10615
10710
|
if not UnitCategories then
|
|
10616
10711
|
Include=true
|
|
@@ -10629,7 +10724,7 @@ self.ScanData.Coalitions[CoalitionDCSUnit]=true
|
|
|
10629
10724
|
self.ScanData.Units[ZoneObject]=ZoneObject
|
|
10630
10725
|
end
|
|
10631
10726
|
end
|
|
10632
|
-
if ObjectCategory==Object.Category.SCENERY
|
|
10727
|
+
if ObjectCategory==Object.Category.SCENERY then
|
|
10633
10728
|
local SceneryType=ZoneObject:getTypeName()
|
|
10634
10729
|
local SceneryName=ZoneObject:getName()
|
|
10635
10730
|
self.ScanData.Scenery[SceneryType]=self.ScanData.Scenery[SceneryType]or{}
|
|
@@ -11392,11 +11487,17 @@ local ZoneName=objectData.name or"Unknown rect Polygon Drawing"
|
|
|
11392
11487
|
local vec2={x=objectData.mapX,y=objectData.mapY}
|
|
11393
11488
|
local w=objectData.width
|
|
11394
11489
|
local h=objectData.height
|
|
11395
|
-
local
|
|
11396
|
-
|
|
11397
|
-
|
|
11398
|
-
|
|
11399
|
-
|
|
11490
|
+
local rotation=UTILS.ToRadian(objectData.angle or 0)
|
|
11491
|
+
local sinRot=math.sin(rotation)
|
|
11492
|
+
local cosRot=math.cos(rotation)
|
|
11493
|
+
local dx=h/2
|
|
11494
|
+
local dy=w/2
|
|
11495
|
+
local points={
|
|
11496
|
+
{x=-dx*cosRot-(-dy*sinRot)+vec2.x,y=-dx*sinRot+(-dy*cosRot)+vec2.y},
|
|
11497
|
+
{x=dx*cosRot-(-dy*sinRot)+vec2.x,y=dx*sinRot+(-dy*cosRot)+vec2.y},
|
|
11498
|
+
{x=dx*cosRot-(dy*sinRot)+vec2.x,y=dx*sinRot+(dy*cosRot)+vec2.y},
|
|
11499
|
+
{x=-dx*cosRot-(dy*sinRot)+vec2.x,y=-dx*sinRot+(dy*cosRot)+vec2.y},
|
|
11500
|
+
}
|
|
11400
11501
|
self:I(string.format("Register ZONE: %s (Polygon (rect) drawing with %d vertices)",ZoneName,#points))
|
|
11401
11502
|
local Zone=ZONE_POLYGON:NewFromPointsArray(ZoneName,points)
|
|
11402
11503
|
Zone:SetColor({1,0,0},0.15)
|
|
@@ -16160,6 +16261,18 @@ self:Remove(RemoveGroupName)
|
|
|
16160
16261
|
end
|
|
16161
16262
|
return self
|
|
16162
16263
|
end
|
|
16264
|
+
function SET_OPSGROUP:CountAlive()
|
|
16265
|
+
local CountG=0
|
|
16266
|
+
local CountU=0
|
|
16267
|
+
local Set=self:GetSet()
|
|
16268
|
+
for GroupID,GroupData in pairs(Set)do
|
|
16269
|
+
if GroupData and GroupData:IsAlive()then
|
|
16270
|
+
CountG=CountG+1
|
|
16271
|
+
CountU=CountU+GroupData:GetGroup():CountAliveUnits()
|
|
16272
|
+
end
|
|
16273
|
+
end
|
|
16274
|
+
return CountG,CountU
|
|
16275
|
+
end
|
|
16163
16276
|
function SET_OPSGROUP:FindGroup(GroupName)
|
|
16164
16277
|
local GroupFound=self.Set[GroupName]
|
|
16165
16278
|
return GroupFound
|
|
@@ -21705,7 +21818,7 @@ self:ScheduleOnce(0.3,self.SpawnFunctionHook,mystatic,unpack(self.SpawnFunctionA
|
|
|
21705
21818
|
end
|
|
21706
21819
|
if self.StaticCopyFrom~=nil then
|
|
21707
21820
|
mystatic.StaticCopyFrom=self.StaticCopyFrom
|
|
21708
|
-
|
|
21821
|
+
end
|
|
21709
21822
|
local TemplateGroup={}
|
|
21710
21823
|
TemplateGroup.units={}
|
|
21711
21824
|
TemplateGroup.units[1]=Template
|
|
@@ -21713,8 +21826,6 @@ TemplateGroup.x=Template.x
|
|
|
21713
21826
|
TemplateGroup.y=Template.y
|
|
21714
21827
|
TemplateGroup.name=Template.name
|
|
21715
21828
|
_DATABASE:_RegisterStaticTemplate(TemplateGroup,self.CoalitionID,self.CategoryID,CountryID)
|
|
21716
|
-
end
|
|
21717
|
-
end
|
|
21718
21829
|
return mystatic
|
|
21719
21830
|
end
|
|
21720
21831
|
TIMER={
|
|
@@ -22624,6 +22735,7 @@ function POSITIONABLE:GetCoord()
|
|
|
22624
22735
|
local DCSPositionable=self:GetDCSObject()
|
|
22625
22736
|
if DCSPositionable then
|
|
22626
22737
|
local PositionableVec3=self:GetVec3()
|
|
22738
|
+
if PositionableVec3 then
|
|
22627
22739
|
if self.coordinate then
|
|
22628
22740
|
self.coordinate:UpdateFromVec3(PositionableVec3)
|
|
22629
22741
|
else
|
|
@@ -22631,6 +22743,7 @@ self.coordinate=COORDINATE:NewFromVec3(PositionableVec3)
|
|
|
22631
22743
|
end
|
|
22632
22744
|
return self.coordinate
|
|
22633
22745
|
end
|
|
22746
|
+
end
|
|
22634
22747
|
BASE:E({"Cannot GetCoordinate",Positionable=self,Alive=self:IsAlive()})
|
|
22635
22748
|
return nil
|
|
22636
22749
|
end
|
|
@@ -25673,6 +25786,46 @@ return self
|
|
|
25673
25786
|
end
|
|
25674
25787
|
return nil
|
|
25675
25788
|
end
|
|
25789
|
+
function CONTROLLABLE:OptionAAAMinFiringHeightMeters(meters)
|
|
25790
|
+
self:F2({self.ControllableName})
|
|
25791
|
+
local meters=meters or 20
|
|
25792
|
+
local DCSControllable=self:GetDCSObject()
|
|
25793
|
+
if DCSControllable then
|
|
25794
|
+
local Controller=self:_GetController()
|
|
25795
|
+
if Controller then
|
|
25796
|
+
if self:IsGround()then
|
|
25797
|
+
self:SetOption(27,meters)
|
|
25798
|
+
end
|
|
25799
|
+
end
|
|
25800
|
+
return self
|
|
25801
|
+
end
|
|
25802
|
+
return nil
|
|
25803
|
+
end
|
|
25804
|
+
function CONTROLLABLE:OptionAAAMaxFiringHeightMeters(meters)
|
|
25805
|
+
self:F2({self.ControllableName})
|
|
25806
|
+
local meters=meters or 1000
|
|
25807
|
+
local DCSControllable=self:GetDCSObject()
|
|
25808
|
+
if DCSControllable then
|
|
25809
|
+
local Controller=self:_GetController()
|
|
25810
|
+
if Controller then
|
|
25811
|
+
if self:IsGround()then
|
|
25812
|
+
self:SetOption(29,meters)
|
|
25813
|
+
end
|
|
25814
|
+
end
|
|
25815
|
+
return self
|
|
25816
|
+
end
|
|
25817
|
+
return nil
|
|
25818
|
+
end
|
|
25819
|
+
function CONTROLLABLE:OptionAAAMinFiringHeightFeet(feet)
|
|
25820
|
+
self:F2({self.ControllableName})
|
|
25821
|
+
local feet=feet or 60
|
|
25822
|
+
return self:OptionAAAMinFiringHeightMeters(UTILS.FeetToMeters(feet))
|
|
25823
|
+
end
|
|
25824
|
+
function CONTROLLABLE:OptionAAAMaxFiringHeightfeet(feet)
|
|
25825
|
+
self:F2({self.ControllableName})
|
|
25826
|
+
local feet=feet or 3000
|
|
25827
|
+
return self:OptionAAAMaxFiringHeightMeters(UTILS.FeetToMeters(feet))
|
|
25828
|
+
end
|
|
25676
25829
|
function CONTROLLABLE:OptionEngageRange(EngageRange)
|
|
25677
25830
|
self:F2({self.ControllableName})
|
|
25678
25831
|
EngageRange=EngageRange or 100
|
|
@@ -30291,19 +30444,25 @@ AIRBASE.Afghanistan={
|
|
|
30291
30444
|
["Urgoon_Heliport"]="Urgoon Heliport",
|
|
30292
30445
|
}
|
|
30293
30446
|
AIRBASE.Iraq={
|
|
30294
|
-
["Baghdad_International_Airport"]="Baghdad International Airport",
|
|
30295
|
-
["Sulaimaniyah_International_Airport"]="Sulaimaniyah International Airport",
|
|
30296
|
-
["Al_Sahra_Airport"]="Al-Sahra Airport",
|
|
30297
|
-
["Erbil_International_Airport"]="Erbil International Airport",
|
|
30298
|
-
["Al_Taji_Airport"]="Al-Taji Airport",
|
|
30299
30447
|
["Al_Asad_Airbase"]="Al-Asad Airbase",
|
|
30448
|
+
["Al_Kut_Airport"]="Al-Kut Airport",
|
|
30449
|
+
["Al_Sahra_Airport"]="Al-Sahra Airport",
|
|
30300
30450
|
["Al_Salam_Airbase"]="Al-Salam Airbase",
|
|
30451
|
+
["Al_Taji_Airport"]="Al-Taji Airport",
|
|
30452
|
+
["Al_Taquddum_Airport"]="Al-Taquddum Airport",
|
|
30453
|
+
["Baghdad_International_Airport"]="Baghdad International Airport",
|
|
30301
30454
|
["Balad_Airbase"]="Balad Airbase",
|
|
30302
|
-
["Kirkuk_International_Airport"]="Kirkuk International Airport",
|
|
30303
30455
|
["Bashur_Airport"]="Bashur Airport",
|
|
30304
|
-
["
|
|
30305
|
-
["
|
|
30456
|
+
["Erbil_International_Airport"]="Erbil International Airport",
|
|
30457
|
+
["H2_Airbase"]="H-2 Airbase",
|
|
30458
|
+
["H3_Main_Airbase"]="H-3 Main Airbase",
|
|
30459
|
+
["H3_Northwest_Airbase"]="H-3 Northwest Airbase",
|
|
30460
|
+
["H3_Southwest_Airbase"]="H-3 Southwest Airbase",
|
|
30306
30461
|
["K1_Base"]="K1 Base",
|
|
30462
|
+
["Kirkuk_International_Airport"]="Kirkuk International Airport",
|
|
30463
|
+
["Mosul_International_Airport"]="Mosul International Airport",
|
|
30464
|
+
["Qayyarah_Airfield_West"]="Qayyarah Airfield West",
|
|
30465
|
+
["Sulaimaniyah_International_Airport"]="Sulaimaniyah International Airport",
|
|
30307
30466
|
}
|
|
30308
30467
|
AIRBASE.GermanyCW={
|
|
30309
30468
|
["Airracing_Frankfurt"]="Airracing Frankfurt",
|
|
@@ -30576,6 +30735,13 @@ end
|
|
|
30576
30735
|
self:T2(string.format("Registered airbase %s",tostring(self.AirbaseName)))
|
|
30577
30736
|
return self
|
|
30578
30737
|
end
|
|
30738
|
+
function AIRBASE:GetVec2()
|
|
30739
|
+
local runways=self:GetRunways()
|
|
30740
|
+
if runways and#runways>0 then
|
|
30741
|
+
return runways[1].center:GetVec2()
|
|
30742
|
+
end
|
|
30743
|
+
return self:GetCoordinate():GetVec2()
|
|
30744
|
+
end
|
|
30579
30745
|
function AIRBASE:_GetCategory()
|
|
30580
30746
|
local name=self.AirbaseName
|
|
30581
30747
|
local static=StaticObject.getByName(name)
|
|
@@ -32985,7 +33151,7 @@ self:SetLiquid(lqno,lqam)
|
|
|
32985
33151
|
end
|
|
32986
33152
|
end
|
|
32987
33153
|
else
|
|
32988
|
-
self:E("File for Liquids could not be found: "..tostring(Path).."\\"..tostring(Filename"_Liquids.csv")
|
|
33154
|
+
self:E("File for Liquids could not be found: "..tostring(Path).."\\"..tostring(Filename).."_Liquids.csv")
|
|
32989
33155
|
end
|
|
32990
33156
|
end
|
|
32991
33157
|
if self:IsLimitedAircraft()then
|
|
@@ -33003,7 +33169,7 @@ self:SetAmount(acname,acnumber)
|
|
|
33003
33169
|
end
|
|
33004
33170
|
end
|
|
33005
33171
|
else
|
|
33006
|
-
self:E("File for Aircraft could not be found: "..tostring(Path).."\\"..tostring(Filename"_Aircraft.csv")
|
|
33172
|
+
self:E("File for Aircraft could not be found: "..tostring(Path).."\\"..tostring(Filename).."_Aircraft.csv")
|
|
33007
33173
|
end
|
|
33008
33174
|
end
|
|
33009
33175
|
if self:IsLimitedWeapons()then
|
|
@@ -33032,7 +33198,7 @@ end
|
|
|
33032
33198
|
end
|
|
33033
33199
|
end
|
|
33034
33200
|
else
|
|
33035
|
-
self:E("File for Weapons could not be found: "..tostring(Path).."\\"..tostring(Filename"_Weapons.csv")
|
|
33201
|
+
self:E("File for Weapons could not be found: "..tostring(Path).."\\"..tostring(Filename).."_Weapons.csv")
|
|
33036
33202
|
end
|
|
33037
33203
|
end
|
|
33038
33204
|
return self
|
|
@@ -33103,6 +33269,8 @@ REMOVED="REMOVED",
|
|
|
33103
33269
|
}
|
|
33104
33270
|
DYNAMICCARGO.AircraftTypes={
|
|
33105
33271
|
["CH-47Fbl1"]="CH-47Fbl1",
|
|
33272
|
+
["Mi-8MTV2"]="CH-47Fbl1",
|
|
33273
|
+
["Mi-8MT"]="CH-47Fbl1",
|
|
33106
33274
|
}
|
|
33107
33275
|
DYNAMICCARGO.AircraftDimensions={
|
|
33108
33276
|
["CH-47Fbl1"]={
|
|
@@ -33111,8 +33279,20 @@ DYNAMICCARGO.AircraftDimensions={
|
|
|
33111
33279
|
["length"]=11,
|
|
33112
33280
|
["ropelength"]=30,
|
|
33113
33281
|
},
|
|
33282
|
+
["Mi-8MTV2"]={
|
|
33283
|
+
["width"]=6,
|
|
33284
|
+
["height"]=6,
|
|
33285
|
+
["length"]=15,
|
|
33286
|
+
["ropelength"]=30,
|
|
33287
|
+
},
|
|
33288
|
+
["Mi-8MT"]={
|
|
33289
|
+
["width"]=6,
|
|
33290
|
+
["height"]=6,
|
|
33291
|
+
["length"]=15,
|
|
33292
|
+
["ropelength"]=30,
|
|
33293
|
+
},
|
|
33114
33294
|
}
|
|
33115
|
-
DYNAMICCARGO.version="0.0.
|
|
33295
|
+
DYNAMICCARGO.version="0.0.9"
|
|
33116
33296
|
function DYNAMICCARGO:Register(CargoName)
|
|
33117
33297
|
local self=BASE:Inherit(self,POSITIONABLE:New(CargoName))
|
|
33118
33298
|
self.StaticName=CargoName
|
|
@@ -34725,7 +34905,9 @@ end
|
|
|
34725
34905
|
end)
|
|
34726
34906
|
self.AutoSavePath=SavePath
|
|
34727
34907
|
self.AutoSave=AutoSave or true
|
|
34908
|
+
if self.AutoSave==true then
|
|
34728
34909
|
self:OpenCSV(GameName)
|
|
34910
|
+
end
|
|
34729
34911
|
return self
|
|
34730
34912
|
end
|
|
34731
34913
|
function SCORING:SetDisplayMessagePrefix(DisplayMessagePrefix)
|
|
@@ -35749,7 +35931,7 @@ TargetUnitCoalition=TargetUnitCoalition or""
|
|
|
35749
35931
|
TargetUnitCategory=TargetUnitCategory or""
|
|
35750
35932
|
TargetUnitType=TargetUnitType or""
|
|
35751
35933
|
TargetUnitName=TargetUnitName or""
|
|
35752
|
-
if lfs and io and os and self.AutoSave then
|
|
35934
|
+
if lfs and io and os and self.AutoSave==true and self.CSVFile~=nil then
|
|
35753
35935
|
self.CSVFile:write(
|
|
35754
35936
|
'"'..self.GameName..'"'..','..
|
|
35755
35937
|
'"'..self.RunTime..'"'..','..
|
|
@@ -40445,22 +40627,22 @@ RAT.markerid=0
|
|
|
40445
40627
|
RAT.MenuF10=nil
|
|
40446
40628
|
RAT.id="RAT | "
|
|
40447
40629
|
RAT.version={
|
|
40448
|
-
version="
|
|
40630
|
+
version="3.0.0",
|
|
40449
40631
|
print=true,
|
|
40450
40632
|
}
|
|
40451
40633
|
function RAT:New(groupname,alias)
|
|
40452
|
-
BASE:F({groupname=groupname,alias=alias})
|
|
40453
40634
|
self=BASE:Inherit(self,SPAWN:NewWithAlias(groupname,alias))
|
|
40635
|
+
self.lid=string.format("RAT %s | ",alias or groupname)
|
|
40454
40636
|
if RAT.version.print then
|
|
40455
|
-
env.info(
|
|
40637
|
+
env.info(self.lid.."Version "..RAT.version.version)
|
|
40456
40638
|
RAT.version.print=false
|
|
40457
40639
|
end
|
|
40458
|
-
self:F(
|
|
40640
|
+
self:F(self.lid..string.format("Creating new RAT object from template: %s.",groupname))
|
|
40459
40641
|
alias=alias or groupname
|
|
40460
40642
|
self.alias=alias
|
|
40461
40643
|
local DCSgroup=Group.getByName(groupname)
|
|
40462
40644
|
if DCSgroup==nil then
|
|
40463
|
-
self:E(
|
|
40645
|
+
self:E(self.lid..string.format("ERROR: Group with name %s does not exist in the mission editor!",groupname))
|
|
40464
40646
|
return nil
|
|
40465
40647
|
end
|
|
40466
40648
|
self.templategroup=GROUP:FindByName(groupname)
|
|
@@ -40470,6 +40652,36 @@ self:_InitAircraft(DCSgroup)
|
|
|
40470
40652
|
self:_GetAirportsOfMap()
|
|
40471
40653
|
return self
|
|
40472
40654
|
end
|
|
40655
|
+
function RAT:Stop(delay)
|
|
40656
|
+
self:T3(self.lid..string.format("Stopping RAT! Delay %s sec!",tostring(delay)))
|
|
40657
|
+
if delay and delay>0 then
|
|
40658
|
+
self:T2(self.lid..string.format("Stopping RAT in %d sec!",delay))
|
|
40659
|
+
self:ScheduleOnce(delay,RAT.Stop,self)
|
|
40660
|
+
else
|
|
40661
|
+
self:T(self.lid.."Stopping RAT: Clearing schedulers and unhandling events!")
|
|
40662
|
+
if self.sid_Activate then
|
|
40663
|
+
self.Scheduler:ScheduleStop(self.sid_Activate)
|
|
40664
|
+
end
|
|
40665
|
+
if self.sid_Spawn then
|
|
40666
|
+
self.Scheduler:ScheduleStop(self.sid_Spawn)
|
|
40667
|
+
end
|
|
40668
|
+
if self.sid_Status then
|
|
40669
|
+
self.Scheduler:ScheduleStop(self.sid_Status)
|
|
40670
|
+
end
|
|
40671
|
+
if self.Scheduler then
|
|
40672
|
+
self.Scheduler:Clear()
|
|
40673
|
+
end
|
|
40674
|
+
self.norespawn=true
|
|
40675
|
+
self:UnHandleEvent(EVENTS.Birth)
|
|
40676
|
+
self:UnHandleEvent(EVENTS.EngineStartup)
|
|
40677
|
+
self:UnHandleEvent(EVENTS.Takeoff)
|
|
40678
|
+
self:UnHandleEvent(EVENTS.Land)
|
|
40679
|
+
self:UnHandleEvent(EVENTS.EngineShutdown)
|
|
40680
|
+
self:UnHandleEvent(EVENTS.Dead)
|
|
40681
|
+
self:UnHandleEvent(EVENTS.Crash)
|
|
40682
|
+
self:UnHandleEvent(EVENTS.Hit)
|
|
40683
|
+
end
|
|
40684
|
+
end
|
|
40473
40685
|
function RAT:Spawn(naircraft)
|
|
40474
40686
|
if self.spawninitialized==true then
|
|
40475
40687
|
self:E("ERROR: Spawn function should only be called once per RAT object! Exiting and returning nil.")
|
|
@@ -40479,7 +40691,7 @@ self.spawninitialized=true
|
|
|
40479
40691
|
end
|
|
40480
40692
|
self.ngroups=naircraft or 1
|
|
40481
40693
|
if self.ATCswitch and not RAT.ATC.init then
|
|
40482
|
-
|
|
40694
|
+
RAT._ATCInit(self.airports_map)
|
|
40483
40695
|
end
|
|
40484
40696
|
if self.f10menu and not RAT.MenuF10 then
|
|
40485
40697
|
RAT.MenuF10=MENU_MISSION:New("RAT")
|
|
@@ -40585,7 +40797,7 @@ text=text..string.format("- %s\n",livery)
|
|
|
40585
40797
|
end
|
|
40586
40798
|
end
|
|
40587
40799
|
text=text..string.format("******************************************************\n")
|
|
40588
|
-
self:T(
|
|
40800
|
+
self:T(self.lid..text)
|
|
40589
40801
|
if self.f10menu then
|
|
40590
40802
|
self.Menu[self.SubMenuName]=MENU_MISSION:New(self.SubMenuName,RAT.MenuF10)
|
|
40591
40803
|
self.Menu[self.SubMenuName]["groups"]=MENU_MISSION:New("Groups",self.Menu[self.SubMenuName])
|
|
@@ -40599,7 +40811,7 @@ if self.takeoff==RAT.wp.runway and not self.random_departure then
|
|
|
40599
40811
|
dt=math.max(dt,180)
|
|
40600
40812
|
end
|
|
40601
40813
|
local Tstop=Tstart+dt*(self.ngroups-1)
|
|
40602
|
-
|
|
40814
|
+
self.sid_Status=self:ScheduleRepeat(Tstart+1,self.statusinterval,nil,nil,RAT.Status,self)
|
|
40603
40815
|
self:HandleEvent(EVENTS.Birth,self._OnBirth)
|
|
40604
40816
|
self:HandleEvent(EVENTS.EngineStartup,self._OnEngineStartup)
|
|
40605
40817
|
self:HandleEvent(EVENTS.Takeoff,self._OnTakeoff)
|
|
@@ -40611,9 +40823,9 @@ self:HandleEvent(EVENTS.Hit,self._OnHit)
|
|
|
40611
40823
|
if self.ngroups==0 then
|
|
40612
40824
|
return nil
|
|
40613
40825
|
end
|
|
40614
|
-
|
|
40826
|
+
self.sid_Spawn=self:ScheduleRepeat(Tstart,dt,0.0,Tstop,RAT._SpawnWithRoute,self)
|
|
40615
40827
|
if self.uncontrolled and self.activate_uncontrolled then
|
|
40616
|
-
|
|
40828
|
+
self.sid_Activate=self:ScheduleRepeat(self.activate_delay,self.activate_delta,self.activate_frand,nil,RAT._ActivateUncontrolled,self)
|
|
40617
40829
|
end
|
|
40618
40830
|
return true
|
|
40619
40831
|
end
|
|
@@ -40629,12 +40841,12 @@ end
|
|
|
40629
40841
|
end
|
|
40630
40842
|
if self.Ndeparture_Zones>0 and self.takeoff~=RAT.wp.air then
|
|
40631
40843
|
self.takeoff=RAT.wp.air
|
|
40632
|
-
self:E(
|
|
40844
|
+
self:E(self.lid..string.format("WARNING: At least one zone defined as departure and takeoff is NOT set to air. Enabling air start for RAT group %s!",self.alias))
|
|
40633
40845
|
end
|
|
40634
40846
|
if self.Ndeparture_Airports==0 and self.Ndeparture_Zone==0 then
|
|
40635
40847
|
self.random_departure=true
|
|
40636
40848
|
local text=string.format("No airports or zones found given in SetDeparture(). Enabling random departure airports for RAT group %s!",self.alias)
|
|
40637
|
-
self:E(
|
|
40849
|
+
self:E(self.lid.."ERROR: "..text)
|
|
40638
40850
|
MESSAGE:New(text,30):ToAll()
|
|
40639
40851
|
end
|
|
40640
40852
|
end
|
|
@@ -40649,17 +40861,17 @@ end
|
|
|
40649
40861
|
if self.Ndestination_Zones>0 and self.landing~=RAT.wp.air and not self.returnzone then
|
|
40650
40862
|
self.landing=RAT.wp.air
|
|
40651
40863
|
self.destinationzone=true
|
|
40652
|
-
self:E(
|
|
40864
|
+
self:E(self.lid.."WARNING: At least one zone defined as destination and landing is NOT set to air. Enabling destination zone!")
|
|
40653
40865
|
end
|
|
40654
40866
|
if self.Ndestination_Airports==0 and self.Ndestination_Zones==0 then
|
|
40655
40867
|
self.random_destination=true
|
|
40656
40868
|
local text="No airports or zones found given in SetDestination(). Enabling random destination airports!"
|
|
40657
|
-
self:E(
|
|
40869
|
+
self:E(self.lid.."ERROR: "..text)
|
|
40658
40870
|
MESSAGE:New(text,30):ToAll()
|
|
40659
40871
|
end
|
|
40660
40872
|
end
|
|
40661
40873
|
if self.destinationzone and self.returnzone then
|
|
40662
|
-
self:E(
|
|
40874
|
+
self:E(self.lid.."ERROR: Destination zone _and_ return to zone not possible! Disabling return to zone.")
|
|
40663
40875
|
self.returnzone=false
|
|
40664
40876
|
end
|
|
40665
40877
|
if self.returnzone and self.takeoff==RAT.wp.air then
|
|
@@ -40808,7 +41020,7 @@ names=departurenames
|
|
|
40808
41020
|
elseif type(departurenames)=="string"then
|
|
40809
41021
|
names={departurenames}
|
|
40810
41022
|
else
|
|
40811
|
-
self:E(
|
|
41023
|
+
self:E(self.lid.."ERROR: Input parameter must be a string or a table in SetDeparture()!")
|
|
40812
41024
|
end
|
|
40813
41025
|
for _,name in pairs(names)do
|
|
40814
41026
|
if self:_AirportExists(name)then
|
|
@@ -40816,7 +41028,7 @@ table.insert(self.departure_ports,name)
|
|
|
40816
41028
|
elseif self:_ZoneExists(name)then
|
|
40817
41029
|
table.insert(self.departure_ports,name)
|
|
40818
41030
|
else
|
|
40819
|
-
self:E(
|
|
41031
|
+
self:E(self.lid.."ERROR: No departure airport or zone found with name "..name)
|
|
40820
41032
|
end
|
|
40821
41033
|
end
|
|
40822
41034
|
return self
|
|
@@ -40830,7 +41042,7 @@ names=destinationnames
|
|
|
40830
41042
|
elseif type(destinationnames)=="string"then
|
|
40831
41043
|
names={destinationnames}
|
|
40832
41044
|
else
|
|
40833
|
-
self:E(
|
|
41045
|
+
self:E(self.lid.."ERROR: Input parameter must be a string or a table in SetDestination()!")
|
|
40834
41046
|
end
|
|
40835
41047
|
for _,name in pairs(names)do
|
|
40836
41048
|
if self:_AirportExists(name)then
|
|
@@ -40838,7 +41050,7 @@ table.insert(self.destination_ports,name)
|
|
|
40838
41050
|
elseif self:_ZoneExists(name)then
|
|
40839
41051
|
table.insert(self.destination_ports,name)
|
|
40840
41052
|
else
|
|
40841
|
-
self:E(
|
|
41053
|
+
self:E(self.lid.."ERROR: No destination airport or zone found with name "..name)
|
|
40842
41054
|
end
|
|
40843
41055
|
end
|
|
40844
41056
|
return self
|
|
@@ -40943,12 +41155,14 @@ interval=interval or 5
|
|
|
40943
41155
|
self.spawninterval=math.max(0.5,interval)
|
|
40944
41156
|
return self
|
|
40945
41157
|
end
|
|
41158
|
+
function RAT:SetSpawnLimit(Nmax)
|
|
41159
|
+
self.NspawnMax=Nmax
|
|
41160
|
+
return self
|
|
41161
|
+
end
|
|
40946
41162
|
function RAT:RespawnAfterLanding(delay)
|
|
40947
41163
|
self:F2(delay)
|
|
40948
|
-
delay=delay or 180
|
|
40949
41164
|
self.respawn_at_landing=true
|
|
40950
|
-
|
|
40951
|
-
self.respawn_delay=delay
|
|
41165
|
+
self:SetRespawnDelay(delay)
|
|
40952
41166
|
return self
|
|
40953
41167
|
end
|
|
40954
41168
|
function RAT:SetRespawnDelay(delay)
|
|
@@ -41012,10 +41226,6 @@ self.checkontop=switch
|
|
|
41012
41226
|
self.ontopradius=radius or 2
|
|
41013
41227
|
return self
|
|
41014
41228
|
end
|
|
41015
|
-
function RAT:ParkingSpotDB(switch)
|
|
41016
|
-
self:E("RAT ParkingSpotDB function is obsolete and will be removed soon!")
|
|
41017
|
-
return self
|
|
41018
|
-
end
|
|
41019
41229
|
function RAT:RadioON()
|
|
41020
41230
|
self:F2()
|
|
41021
41231
|
self.radio=true
|
|
@@ -41265,7 +41475,7 @@ elseif DCScategory==Group.Category.HELICOPTER then
|
|
|
41265
41475
|
self.category=RAT.cat.heli
|
|
41266
41476
|
else
|
|
41267
41477
|
self.category="other"
|
|
41268
|
-
self:E(
|
|
41478
|
+
self:E(self.lid.."ERROR: Group of RAT is neither airplane nor helicopter!")
|
|
41269
41479
|
end
|
|
41270
41480
|
self.aircraft.type=DCStype
|
|
41271
41481
|
self.aircraft.fuel=DCSunit:getFuel()
|
|
@@ -41304,10 +41514,16 @@ text=text..string.format("Max range = %6.1f km\n",self.aircraft.Rmax/1000)
|
|
|
41304
41514
|
text=text..string.format("Eff range = %6.1f km (with 95 percent initial fuel amount)\n",self.aircraft.Reff/1000)
|
|
41305
41515
|
text=text..string.format("Ceiling = %6.1f km = FL%3.0f\n",self.aircraft.ceiling/1000,self.aircraft.ceiling/RAT.unit.FL2m)
|
|
41306
41516
|
text=text..string.format("******************************************************\n")
|
|
41307
|
-
self:T(
|
|
41517
|
+
self:T(self.lid..text)
|
|
41308
41518
|
end
|
|
41309
41519
|
function RAT:_SpawnWithRoute(_departure,_destination,_takeoff,_landing,_livery,_waypoint,_lastpos,_nrespawn,parkingdata)
|
|
41310
|
-
self:F({rat=
|
|
41520
|
+
self:F({rat=self.lid,departure=_departure,destination=_destination,takeoff=_takeoff,landing=_landing,livery=_livery,waypoint=_waypoint,lastpos=_lastpos,nrespawn=_nrespawn})
|
|
41521
|
+
if self.NspawnMax and self.SpawnIndex>=self.NspawnMax then
|
|
41522
|
+
self:T(self.lid..string.format("Max limit of spawns reached %d >= %d! Will not spawn any more groups",self.NspawnMax,self.SpawnIndex))
|
|
41523
|
+
return
|
|
41524
|
+
else
|
|
41525
|
+
self:T2(self.lid..string.format("Spawning with spawn index=%d",self.SpawnIndex))
|
|
41526
|
+
end
|
|
41311
41527
|
local takeoff=self.takeoff
|
|
41312
41528
|
local landing=self.landing
|
|
41313
41529
|
if _takeoff then
|
|
@@ -41324,7 +41540,7 @@ local nrespawn=0
|
|
|
41324
41540
|
if _nrespawn then
|
|
41325
41541
|
nrespawn=_nrespawn
|
|
41326
41542
|
end
|
|
41327
|
-
local departure,destination,waypoints,
|
|
41543
|
+
local departure,destination,waypoints,wpdesc,wpstatus=self:_SetRoute(takeoff,landing,_departure,_destination,_waypoint)
|
|
41328
41544
|
if not(departure and destination and waypoints)then
|
|
41329
41545
|
return nil
|
|
41330
41546
|
end
|
|
@@ -41334,101 +41550,210 @@ livery=_livery
|
|
|
41334
41550
|
elseif self.livery then
|
|
41335
41551
|
livery=self.livery[math.random(#self.livery)]
|
|
41336
41552
|
local text=string.format("Chosen livery for group %s: %s",self:_AnticipatedGroupName(),livery)
|
|
41337
|
-
self:T(
|
|
41553
|
+
self:T(self.lid..text)
|
|
41338
41554
|
else
|
|
41339
41555
|
livery=nil
|
|
41340
41556
|
end
|
|
41341
|
-
local
|
|
41557
|
+
local uncontrolled=self.uncontrolled
|
|
41558
|
+
local isFlightcontrol=self:_IsFlightControlAirbase(departure)
|
|
41559
|
+
if takeoff~=RAT.wp.air and departure and isFlightcontrol then
|
|
41560
|
+
takeoff=RAT.wp.cold
|
|
41561
|
+
uncontrolled=true
|
|
41562
|
+
end
|
|
41563
|
+
local successful=self:_ModifySpawnTemplate(waypoints,livery,_lastpos,departure,takeoff,parkingdata,uncontrolled)
|
|
41342
41564
|
if not successful then
|
|
41343
41565
|
return nil
|
|
41344
41566
|
end
|
|
41345
41567
|
local group=self:SpawnWithIndex(self.SpawnIndex)
|
|
41568
|
+
local groupname=group:GetName()
|
|
41569
|
+
local flightgroup=FLIGHTGROUP:New(group)
|
|
41570
|
+
if self.ATCswitch then
|
|
41571
|
+
flightgroup.holdtime=nil
|
|
41572
|
+
end
|
|
41573
|
+
flightgroup.stuckDespawn=false
|
|
41346
41574
|
self.alive=self.alive+1
|
|
41347
|
-
self:T(
|
|
41575
|
+
self:T(self.lid..string.format("Alive groups counter now = %d.",self.alive))
|
|
41348
41576
|
if self.ATCswitch and landing==RAT.wp.landing then
|
|
41577
|
+
local airbasename=destination:GetName()
|
|
41349
41578
|
if self.returnzone then
|
|
41350
|
-
|
|
41351
|
-
|
|
41352
|
-
self:
|
|
41579
|
+
airbasename=departure:GetName()
|
|
41580
|
+
end
|
|
41581
|
+
if not self:_IsFlightControlAirbase(airbasename)then
|
|
41582
|
+
self:_ATCAddFlight(groupname,airbasename)
|
|
41353
41583
|
end
|
|
41354
41584
|
end
|
|
41355
41585
|
if self.placemarkers then
|
|
41356
|
-
self:_PlaceMarkers(waypoints,self.SpawnIndex)
|
|
41586
|
+
self:_PlaceMarkers(waypoints,wpdesc,self.SpawnIndex)
|
|
41587
|
+
end
|
|
41588
|
+
if isFlightcontrol and not self.activate_uncontrolled then
|
|
41589
|
+
local N=math.random(120)
|
|
41590
|
+
self:T(self.lid..string.format("Flight will be ready for takeoff in %d seconds",N))
|
|
41591
|
+
flightgroup:SetReadyForTakeoff(true,N)
|
|
41357
41592
|
end
|
|
41358
41593
|
if self.invisible then
|
|
41359
|
-
|
|
41594
|
+
flightgroup:SetDefaultInvisible(true)
|
|
41595
|
+
flightgroup:SwitchInvisible(true)
|
|
41360
41596
|
end
|
|
41361
41597
|
if self.immortal then
|
|
41362
|
-
|
|
41598
|
+
flightgroup:SetDefaultImmortal(true)
|
|
41599
|
+
flightgroup:SwitchImmortal(true)
|
|
41363
41600
|
end
|
|
41364
41601
|
if self.eplrs then
|
|
41365
|
-
|
|
41366
|
-
|
|
41367
|
-
|
|
41368
|
-
self:
|
|
41369
|
-
self
|
|
41370
|
-
|
|
41371
|
-
|
|
41372
|
-
|
|
41373
|
-
|
|
41374
|
-
|
|
41375
|
-
|
|
41376
|
-
|
|
41377
|
-
|
|
41378
|
-
|
|
41379
|
-
|
|
41380
|
-
|
|
41381
|
-
|
|
41382
|
-
|
|
41383
|
-
|
|
41384
|
-
|
|
41385
|
-
|
|
41386
|
-
|
|
41387
|
-
|
|
41388
|
-
|
|
41389
|
-
|
|
41390
|
-
|
|
41391
|
-
self.ratcraft[self.SpawnIndex]["P0"]=group:GetCoordinate()
|
|
41392
|
-
self.ratcraft[self.SpawnIndex]["Pnow"]=group:GetCoordinate()
|
|
41393
|
-
self.ratcraft[self.SpawnIndex]["Distance"]=0
|
|
41394
|
-
self.ratcraft[self.SpawnIndex].takeoff=takeoff
|
|
41395
|
-
self.ratcraft[self.SpawnIndex].landing=landing
|
|
41396
|
-
self.ratcraft[self.SpawnIndex].wpholding=WPholding
|
|
41397
|
-
self.ratcraft[self.SpawnIndex].wpfinal=WPfinal
|
|
41398
|
-
self.ratcraft[self.SpawnIndex].active=not self.uncontrolled
|
|
41399
|
-
self.ratcraft[self.SpawnIndex]["status"]=RAT.status.Spawned
|
|
41400
|
-
self.ratcraft[self.SpawnIndex].livery=livery
|
|
41401
|
-
self.ratcraft[self.SpawnIndex].despawnme=false
|
|
41402
|
-
self.ratcraft[self.SpawnIndex].nrespawn=nrespawn
|
|
41602
|
+
flightgroup:SetDefaultEPLRS(true)
|
|
41603
|
+
flightgroup:SwitchEPLRS(true)
|
|
41604
|
+
end
|
|
41605
|
+
self:_SetROE(flightgroup,self.roe)
|
|
41606
|
+
self:_SetROT(flightgroup,self.rot)
|
|
41607
|
+
local ratcraft={}
|
|
41608
|
+
ratcraft.index=self.SpawnIndex
|
|
41609
|
+
ratcraft.group=group
|
|
41610
|
+
ratcraft.flightgroup=flightgroup
|
|
41611
|
+
ratcraft.destination=destination
|
|
41612
|
+
ratcraft.departure=departure
|
|
41613
|
+
ratcraft.waypoints=waypoints
|
|
41614
|
+
ratcraft.airborne=group:InAir()
|
|
41615
|
+
ratcraft.nunits=group:GetInitialSize()
|
|
41616
|
+
ratcraft.Pnow=group:GetCoordinate()
|
|
41617
|
+
ratcraft.Distance=0
|
|
41618
|
+
ratcraft.takeoff=takeoff
|
|
41619
|
+
ratcraft.landing=landing
|
|
41620
|
+
ratcraft.wpdesc=wpdesc
|
|
41621
|
+
ratcraft.wpstatus=wpstatus
|
|
41622
|
+
ratcraft.active=not uncontrolled
|
|
41623
|
+
ratcraft.status=RAT.status.Spawned
|
|
41624
|
+
ratcraft.livery=livery
|
|
41625
|
+
ratcraft.despawnme=false
|
|
41626
|
+
ratcraft.nrespawn=nrespawn
|
|
41627
|
+
self.ratcraft[self.SpawnIndex]=ratcraft
|
|
41403
41628
|
if self.f10menu then
|
|
41404
41629
|
local name=self.aircraft.type.." ID "..tostring(self.SpawnIndex)
|
|
41405
41630
|
self.Menu[self.SubMenuName].groups[self.SpawnIndex]=MENU_MISSION:New(name,self.Menu[self.SubMenuName].groups)
|
|
41406
41631
|
self.Menu[self.SubMenuName].groups[self.SpawnIndex]["roe"]=MENU_MISSION:New("Set ROE",self.Menu[self.SubMenuName].groups[self.SpawnIndex])
|
|
41407
|
-
MENU_MISSION_COMMAND:New("Weapons hold",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["roe"],self._SetROE,self,
|
|
41408
|
-
MENU_MISSION_COMMAND:New("Weapons free",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["roe"],self._SetROE,self,
|
|
41409
|
-
MENU_MISSION_COMMAND:New("Return fire",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["roe"],self._SetROE,self,
|
|
41632
|
+
MENU_MISSION_COMMAND:New("Weapons hold",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["roe"],self._SetROE,self,flightgroup,RAT.ROE.weaponhold)
|
|
41633
|
+
MENU_MISSION_COMMAND:New("Weapons free",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["roe"],self._SetROE,self,flightgroup,RAT.ROE.weaponfree)
|
|
41634
|
+
MENU_MISSION_COMMAND:New("Return fire",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["roe"],self._SetROE,self,flightgroup,RAT.ROE.returnfire)
|
|
41410
41635
|
self.Menu[self.SubMenuName].groups[self.SpawnIndex]["rot"]=MENU_MISSION:New("Set ROT",self.Menu[self.SubMenuName].groups[self.SpawnIndex])
|
|
41411
|
-
MENU_MISSION_COMMAND:New("No reaction",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["rot"],self._SetROT,self,
|
|
41412
|
-
MENU_MISSION_COMMAND:New("Passive defense",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["rot"],self._SetROT,self,
|
|
41413
|
-
MENU_MISSION_COMMAND:New("Evade on fire",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["rot"],self._SetROT,self,
|
|
41636
|
+
MENU_MISSION_COMMAND:New("No reaction",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["rot"],self._SetROT,self,flightgroup,RAT.ROT.noreaction)
|
|
41637
|
+
MENU_MISSION_COMMAND:New("Passive defense",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["rot"],self._SetROT,self,flightgroup,RAT.ROT.passive)
|
|
41638
|
+
MENU_MISSION_COMMAND:New("Evade on fire",self.Menu[self.SubMenuName].groups[self.SpawnIndex]["rot"],self._SetROT,self,flightgroup,RAT.ROT.evade)
|
|
41414
41639
|
MENU_MISSION_COMMAND:New("Despawn group",self.Menu[self.SubMenuName].groups[self.SpawnIndex],self._Despawn,self,group)
|
|
41415
41640
|
MENU_MISSION_COMMAND:New("Place markers",self.Menu[self.SubMenuName].groups[self.SpawnIndex],self._PlaceMarkers,self,waypoints,self.SpawnIndex)
|
|
41416
41641
|
MENU_MISSION_COMMAND:New("Status report",self.Menu[self.SubMenuName].groups[self.SpawnIndex],self.Status,self,true,self.SpawnIndex)
|
|
41417
41642
|
end
|
|
41643
|
+
function flightgroup.OnAfterPassingWaypoint(Flightgroup,From,Event,To,Waypoint)
|
|
41644
|
+
local waypoint=Waypoint
|
|
41645
|
+
local flightgroup=Flightgroup
|
|
41646
|
+
local wpid=waypoint.uid
|
|
41647
|
+
local ratcraft=self:_GetRatcraftFromGroup(flightgroup.group)
|
|
41648
|
+
local wpdescription=tostring(ratcraft.wpdesc[wpid])
|
|
41649
|
+
local wpstatus=ratcraft.wpstatus[wpid]
|
|
41650
|
+
self:T(self.lid..string.format("RAT passed waypoint %s [uid=%d]: %s [status=%s]",waypoint.name,wpid,wpdescription,wpstatus))
|
|
41651
|
+
self:_SetStatus(group,wpstatus)
|
|
41652
|
+
if waypoint.uid==3 then
|
|
41653
|
+
end
|
|
41654
|
+
end
|
|
41655
|
+
function flightgroup.OnAfterPassedFinalWaypoint(flightgroup,From,Event,To)
|
|
41656
|
+
self:T(self.lid..string.format("RAT passed FINAL waypoint"))
|
|
41657
|
+
local ratcraft=self:_GetRatcraftFromGroup(flightgroup.group)
|
|
41658
|
+
local text=string.format("Flight %s arrived at final destination %s.",group:GetName(),destination:GetName())
|
|
41659
|
+
MESSAGE:New(text,10):ToAllIf(self.reportstatus)
|
|
41660
|
+
self:T(self.lid..text)
|
|
41661
|
+
if landing==RAT.wp.air then
|
|
41662
|
+
local text=string.format("Activating despawn switch for flight %s! Group will be detroyed soon.",group:GetName())
|
|
41663
|
+
MESSAGE:New(text,10):ToAllIf(self.Debug)
|
|
41664
|
+
self:T(self.lid..text)
|
|
41665
|
+
ratcraft.despawnme=true
|
|
41666
|
+
end
|
|
41667
|
+
end
|
|
41668
|
+
function flightgroup.OnAfterRTB(flightgroup,From,Event,To,airbase,SpeedTo,SpeedHold,SpeedLand)
|
|
41669
|
+
self:T(self.lid..string.format("RAT group is RTB"))
|
|
41670
|
+
end
|
|
41671
|
+
function flightgroup.OnAfterHolding(Flightgroup,From,Event,To)
|
|
41672
|
+
local flightgroup=Flightgroup
|
|
41673
|
+
local ratcraft=self:_GetRatcraftFromGroup(flightgroup.group)
|
|
41674
|
+
local destinationname=ratcraft.destination:GetName()
|
|
41675
|
+
local text=string.format("Flight %s to %s ATC: Holding and awaiting landing clearance.",groupname,destinationname)
|
|
41676
|
+
self:T(self.lid..text)
|
|
41677
|
+
MESSAGE:New(text,10):ToAllIf(self.reportstatus)
|
|
41678
|
+
local fc=_DATABASE:GetFlightControl(destinationname)
|
|
41679
|
+
if self.ATCswitch and not fc then
|
|
41680
|
+
self:T(self.lid..string.format("RAT group is HOLDING ==> ATCRegisterFlight"))
|
|
41681
|
+
if self.f10menu then
|
|
41682
|
+
MENU_MISSION_COMMAND:New("Clear for landing",self.Menu[self.SubMenuName].groups[self.SpawnIndex],flightgroup.ClearToLand,flightgroup)
|
|
41683
|
+
end
|
|
41684
|
+
RAT._ATCRegisterFlight(groupname,timer.getTime())
|
|
41685
|
+
end
|
|
41686
|
+
end
|
|
41687
|
+
function flightgroup.OnAfterLanded(Flightgroup,From,Event,To,Airport)
|
|
41688
|
+
self:T(self.lid..string.format("RAT group landed at airbase"))
|
|
41689
|
+
end
|
|
41690
|
+
function flightgroup.OnAfterArrived(Flightgroup,From,Event,To)
|
|
41691
|
+
self:T(self.lid..string.format("RAT group arrived"))
|
|
41692
|
+
end
|
|
41693
|
+
function flightgroup.OnAfterStuck(Flightgroup,From,Event,To,Stucktime)
|
|
41694
|
+
local flightgroup=Flightgroup
|
|
41695
|
+
self:T(self.lid..string.format("Group %s got stuck for %d seconds",flightgroup:GetName(),Stucktime))
|
|
41696
|
+
if Stucktime>10*60 then
|
|
41697
|
+
self:_Respawn(flightgroup.group)
|
|
41698
|
+
end
|
|
41699
|
+
end
|
|
41418
41700
|
return self.SpawnIndex
|
|
41419
41701
|
end
|
|
41702
|
+
function RAT:_IsFlightControlAirbase(airbase)
|
|
41703
|
+
if type(airbase)=="table"then
|
|
41704
|
+
airbase=airbase:GetName()
|
|
41705
|
+
end
|
|
41706
|
+
if airbase then
|
|
41707
|
+
local fc=_DATABASE:GetFlightControl(airbase)
|
|
41708
|
+
if fc then
|
|
41709
|
+
self:T(self.lid..string.format("Airbase %s has a FLIGHTCONTROL running",airbase))
|
|
41710
|
+
return true
|
|
41711
|
+
else
|
|
41712
|
+
return false
|
|
41713
|
+
end
|
|
41714
|
+
end
|
|
41715
|
+
return nil
|
|
41716
|
+
end
|
|
41420
41717
|
function RAT:ClearForLanding(name)
|
|
41421
41718
|
trigger.action.setUserFlag(name,1)
|
|
41422
41719
|
local flagvalue=trigger.misc.getUserFlag(name)
|
|
41423
|
-
self:T(
|
|
41424
|
-
end
|
|
41425
|
-
function RAT:_Respawn(
|
|
41426
|
-
|
|
41427
|
-
|
|
41428
|
-
|
|
41429
|
-
|
|
41430
|
-
|
|
41431
|
-
|
|
41720
|
+
self:T(self.lid.."ATC: User flag value (landing) for "..name.." set to "..flagvalue)
|
|
41721
|
+
end
|
|
41722
|
+
function RAT:_Respawn(group,lastpos,delay)
|
|
41723
|
+
if delay and delay>0 then
|
|
41724
|
+
self:ScheduleOnce(delay,RAT._Respawn,self,group,lastpos,0)
|
|
41725
|
+
else
|
|
41726
|
+
if group then
|
|
41727
|
+
self:T(self.lid..string.format("Respawning ratcraft from group %s",group:GetName()))
|
|
41728
|
+
else
|
|
41729
|
+
self:E(self.lid..string.format("ERROR: group is nil in _Respawn!"))
|
|
41730
|
+
return nil
|
|
41731
|
+
end
|
|
41732
|
+
local ratcraft=self:_GetRatcraftFromGroup(group)
|
|
41733
|
+
lastpos=lastpos or group:GetCoordinate()
|
|
41734
|
+
local departure=ratcraft.departure
|
|
41735
|
+
local destination=ratcraft.destination
|
|
41736
|
+
local takeoff=ratcraft.takeoff
|
|
41737
|
+
local landing=ratcraft.landing
|
|
41738
|
+
local livery=ratcraft.livery
|
|
41739
|
+
local lastwp=ratcraft.waypoints[#ratcraft.waypoints]
|
|
41740
|
+
local flightgroup=ratcraft.flightgroup
|
|
41741
|
+
local parkingdata=nil
|
|
41742
|
+
if self.continuejourney or self.commute then
|
|
41743
|
+
for _,_element in pairs(flightgroup.elements)do
|
|
41744
|
+
local element=_element
|
|
41745
|
+
if element.parking then
|
|
41746
|
+
if parkingdata==nil then
|
|
41747
|
+
parkingdata={}
|
|
41748
|
+
end
|
|
41749
|
+
self:T(self.lid..string.format("Element %s was parking at spot id=%d",element.name,element.parking.TerminalID))
|
|
41750
|
+
table.insert(parkingdata,UTILS.DeepCopy(element.parking))
|
|
41751
|
+
else
|
|
41752
|
+
self:E(self.lid..string.format("WARNING: Element %s did NOT have a not parking spot!",tostring(element.name)))
|
|
41753
|
+
end
|
|
41754
|
+
end
|
|
41755
|
+
end
|
|
41756
|
+
self:_Despawn(ratcraft.group)
|
|
41432
41757
|
local _departure=nil
|
|
41433
41758
|
local _destination=nil
|
|
41434
41759
|
local _takeoff=nil
|
|
@@ -41439,7 +41764,7 @@ local _lastpos=nil
|
|
|
41439
41764
|
if self.continuejourney then
|
|
41440
41765
|
_departure=destination:GetName()
|
|
41441
41766
|
_livery=livery
|
|
41442
|
-
if landing==RAT.wp.landing and
|
|
41767
|
+
if landing==RAT.wp.landing and not(self.respawn_at_landing or self.respawn_after_takeoff)then
|
|
41443
41768
|
if destination:GetCategory()==4 then
|
|
41444
41769
|
_lastpos=lastpos
|
|
41445
41770
|
end
|
|
@@ -41502,28 +41827,31 @@ if _takeoff==RAT.wp.air and(self.continuejourney or self.commute)then
|
|
|
41502
41827
|
_lastwp=lastwp
|
|
41503
41828
|
end
|
|
41504
41829
|
self:T2({departure=_departure,destination=_destination,takeoff=_takeoff,landing=_landing,livery=_livery,lastwp=_lastwp})
|
|
41505
|
-
local respawndelay
|
|
41506
|
-
|
|
41507
|
-
respawndelay
|
|
41508
|
-
|
|
41509
|
-
|
|
41510
|
-
|
|
41511
|
-
|
|
41512
|
-
|
|
41513
|
-
|
|
41514
|
-
|
|
41515
|
-
|
|
41516
|
-
|
|
41517
|
-
|
|
41518
|
-
|
|
41519
|
-
|
|
41520
|
-
|
|
41521
|
-
|
|
41522
|
-
self
|
|
41523
|
-
|
|
41524
|
-
|
|
41525
|
-
|
|
41526
|
-
|
|
41830
|
+
local respawndelay=self.respawn_delay or 1
|
|
41831
|
+
self:T(self.lid..string.format("%s delayed respawn in %.1f seconds.",self.alias,respawndelay))
|
|
41832
|
+
self:ScheduleOnce(respawndelay,RAT._SpawnWithRoute,self,_departure,_destination,_takeoff,_landing,_livery,nil,_lastpos,nil,parkingdata)
|
|
41833
|
+
end
|
|
41834
|
+
end
|
|
41835
|
+
function RAT:_Despawn(group,delay)
|
|
41836
|
+
if delay and delay>0 then
|
|
41837
|
+
self:ScheduleOnce(delay,RAT._Despawn,self,group,0)
|
|
41838
|
+
else
|
|
41839
|
+
if group then
|
|
41840
|
+
local index=self:GetSpawnIndexFromGroup(group)
|
|
41841
|
+
if index then
|
|
41842
|
+
self:T(self.lid..string.format("Despawning group %s (index=%d)",group:GetName(),index))
|
|
41843
|
+
local ratcraft=self.ratcraft[index]
|
|
41844
|
+
ratcraft.flightgroup:Despawn()
|
|
41845
|
+
ratcraft.flightgroup:__Stop(0.1)
|
|
41846
|
+
self.ratcraft[index].group=nil
|
|
41847
|
+
self.ratcraft[index]["status"]="Dead"
|
|
41848
|
+
self.ratcraft[index]=nil
|
|
41849
|
+
if self.f10menu and self.SubMenuName~=nil then
|
|
41850
|
+
self.Menu[self.SubMenuName]["groups"][index]:Remove()
|
|
41851
|
+
end
|
|
41852
|
+
end
|
|
41853
|
+
end
|
|
41854
|
+
end
|
|
41527
41855
|
end
|
|
41528
41856
|
function RAT:_SetRoute(takeoff,landing,_departure,_destination,_waypoint)
|
|
41529
41857
|
local VxCruiseMax
|
|
@@ -41553,7 +41881,7 @@ elseif self:_ZoneExists(_departure)then
|
|
|
41553
41881
|
departure=ZONE:FindByName(_departure)
|
|
41554
41882
|
else
|
|
41555
41883
|
local text=string.format("ERROR! Specified departure airport %s does not exist for %s.",_departure,self.alias)
|
|
41556
|
-
self:E(
|
|
41884
|
+
self:E(self.lid..text)
|
|
41557
41885
|
end
|
|
41558
41886
|
else
|
|
41559
41887
|
departure=self:_PickDeparture(takeoff)
|
|
@@ -41563,7 +41891,7 @@ end
|
|
|
41563
41891
|
end
|
|
41564
41892
|
if not departure then
|
|
41565
41893
|
local text=string.format("ERROR! No valid departure airport could be found for %s.",self.alias)
|
|
41566
|
-
self:E(
|
|
41894
|
+
self:E(self.lid..text)
|
|
41567
41895
|
return nil
|
|
41568
41896
|
end
|
|
41569
41897
|
local Pdeparture
|
|
@@ -41611,7 +41939,7 @@ mindist=Dtot
|
|
|
41611
41939
|
end
|
|
41612
41940
|
mindist=math.max(self.mindist,mindist)
|
|
41613
41941
|
local text=string.format("Adjusting min distance to %d km (for given min FL%03d)",mindist/1000,self.FLminuser/RAT.unit.FL2m)
|
|
41614
|
-
self:T(
|
|
41942
|
+
self:T(self.lid..text)
|
|
41615
41943
|
end
|
|
41616
41944
|
local destination=nil
|
|
41617
41945
|
if _destination then
|
|
@@ -41624,7 +41952,7 @@ elseif self:_ZoneExists(_destination)then
|
|
|
41624
41952
|
destination=ZONE:FindByName(_destination)
|
|
41625
41953
|
else
|
|
41626
41954
|
local text=string.format("ERROR: Specified destination airport/zone %s does not exist for %s!",_destination,self.alias)
|
|
41627
|
-
self:E(
|
|
41955
|
+
self:E(self.lid.."ERROR: "..text)
|
|
41628
41956
|
end
|
|
41629
41957
|
else
|
|
41630
41958
|
local random=self.random_destination
|
|
@@ -41642,13 +41970,13 @@ end
|
|
|
41642
41970
|
if not destination then
|
|
41643
41971
|
local text=string.format("No valid destination airport could be found for %s!",self.alias)
|
|
41644
41972
|
MESSAGE:New(text,60):ToAll()
|
|
41645
|
-
self:E(
|
|
41973
|
+
self:E(self.lid.."ERROR: "..text)
|
|
41646
41974
|
return nil
|
|
41647
41975
|
end
|
|
41648
41976
|
if destination:GetName()==departure:GetName()then
|
|
41649
41977
|
local text=string.format("%s: Destination and departure are identical. Airport/zone %s.",self.alias,destination:GetName())
|
|
41650
41978
|
MESSAGE:New(text,30):ToAll()
|
|
41651
|
-
self:E(
|
|
41979
|
+
self:E(self.lid.."ERROR: "..text)
|
|
41652
41980
|
end
|
|
41653
41981
|
local Preturn
|
|
41654
41982
|
local destination_returnzone
|
|
@@ -41829,93 +42157,90 @@ text=text..string.format("h_climb_max = %6.1f m\n",h_climb_max)
|
|
|
41829
42157
|
text=text..string.format("h_descent_max = %6.1f m\n",h_descent_max)
|
|
41830
42158
|
end
|
|
41831
42159
|
text=text..string.format("******************************************************\n")
|
|
41832
|
-
self:T2(
|
|
42160
|
+
self:T2(self.lid..text)
|
|
41833
42161
|
if d_cruise<0 then
|
|
41834
42162
|
d_cruise=100
|
|
41835
42163
|
end
|
|
41836
42164
|
local wp={}
|
|
41837
42165
|
local c={}
|
|
42166
|
+
local waypointdescriptions={}
|
|
42167
|
+
local waypointstatus={}
|
|
41838
42168
|
local wpholding=nil
|
|
41839
42169
|
local wpfinal=nil
|
|
41840
42170
|
c[#c+1]=Pdeparture
|
|
41841
42171
|
wp[#wp+1]=self:_Waypoint(#wp+1,"Departure",takeoff,c[#wp+1],VxClimb,H_departure,departure)
|
|
41842
|
-
|
|
41843
|
-
|
|
42172
|
+
waypointdescriptions[#wp]="Departure"
|
|
42173
|
+
waypointstatus[#wp]=RAT.status.Departure
|
|
41844
42174
|
if takeoff==RAT.wp.air then
|
|
41845
42175
|
if d_climb<5000 or d_cruise<5000 then
|
|
41846
42176
|
d_cruise=d_cruise+d_climb
|
|
41847
42177
|
else
|
|
41848
42178
|
c[#c+1]=c[#c]:Translate(d_climb,heading)
|
|
41849
42179
|
wp[#wp+1]=self:_Waypoint(#wp+1,"Begin of Cruise",RAT.wp.cruise,c[#wp+1],VxCruise,FLcruise)
|
|
41850
|
-
|
|
41851
|
-
|
|
42180
|
+
waypointdescriptions[#wp]="Begin of Cruise"
|
|
42181
|
+
waypointstatus[#wp]=RAT.status.Cruise
|
|
41852
42182
|
end
|
|
41853
42183
|
else
|
|
41854
42184
|
c[#c+1]=c[#c]:Translate(d_climb/2,heading)
|
|
41855
42185
|
c[#c+1]=c[#c]:Translate(d_climb/2,heading)
|
|
41856
42186
|
wp[#wp+1]=self:_Waypoint(#wp+1,"Climb",RAT.wp.climb,c[#wp+1],VxClimb,H_departure+(FLcruise-H_departure)/2)
|
|
41857
|
-
|
|
41858
|
-
|
|
42187
|
+
waypointdescriptions[#wp]="Climb"
|
|
42188
|
+
waypointstatus[#wp]=RAT.status.Climb
|
|
41859
42189
|
wp[#wp+1]=self:_Waypoint(#wp+1,"Begin of Cruise",RAT.wp.cruise,c[#wp+1],VxCruise,FLcruise)
|
|
41860
|
-
|
|
41861
|
-
|
|
42190
|
+
waypointdescriptions[#wp]="Begin of Cruise"
|
|
42191
|
+
waypointstatus[#wp]=RAT.status.Cruise
|
|
41862
42192
|
end
|
|
41863
42193
|
if self.returnzone then
|
|
41864
42194
|
c[#c+1]=Preturn
|
|
41865
42195
|
wp[#wp+1]=self:_Waypoint(#wp+1,"Return Zone",RAT.wp.cruise,c[#wp+1],VxCruise,FLcruise)
|
|
41866
|
-
|
|
41867
|
-
|
|
42196
|
+
waypointdescriptions[#wp]="Return Zone"
|
|
42197
|
+
waypointstatus[#wp]=RAT.status.Uturn
|
|
41868
42198
|
end
|
|
41869
42199
|
if landing==RAT.wp.air then
|
|
41870
42200
|
c[#c+1]=Pdestination
|
|
41871
42201
|
wp[#wp+1]=self:_Waypoint(#wp+1,"Final Destination",RAT.wp.finalwp,c[#wp+1],VxCruise,FLcruise)
|
|
41872
|
-
|
|
41873
|
-
|
|
42202
|
+
waypointdescriptions[#wp]="Final Destination"
|
|
42203
|
+
waypointstatus[#wp]=RAT.status.Destination
|
|
41874
42204
|
elseif self.returnzone then
|
|
41875
42205
|
c[#c+1]=c[#c]:Translate(d_cruise/2,heading-180)
|
|
41876
42206
|
wp[#wp+1]=self:_Waypoint(#wp+1,"End of Cruise",RAT.wp.cruise,c[#wp+1],VxCruise,FLcruise)
|
|
41877
|
-
|
|
41878
|
-
|
|
42207
|
+
waypointdescriptions[#wp]="End of Cruise"
|
|
42208
|
+
waypointstatus[#wp]=RAT.status.Descent
|
|
41879
42209
|
else
|
|
41880
42210
|
c[#c+1]=c[#c]:Translate(d_cruise,heading)
|
|
41881
42211
|
wp[#wp+1]=self:_Waypoint(#wp+1,"End of Cruise",RAT.wp.cruise,c[#wp+1],VxCruise,FLcruise)
|
|
41882
|
-
|
|
41883
|
-
|
|
42212
|
+
waypointdescriptions[#wp]="End of Cruise"
|
|
42213
|
+
waypointstatus[#wp]=RAT.status.Descent
|
|
41884
42214
|
end
|
|
41885
42215
|
if landing==RAT.wp.landing then
|
|
41886
42216
|
if self.returnzone then
|
|
41887
42217
|
c[#c+1]=c[#c]:Translate(d_descent/2,heading-180)
|
|
41888
42218
|
wp[#wp+1]=self:_Waypoint(#wp+1,"Descent",RAT.wp.descent,c[#wp+1],VxDescent,FLcruise-(FLcruise-(h_holding+H_holding))/2)
|
|
41889
|
-
|
|
41890
|
-
|
|
42219
|
+
waypointdescriptions[#wp]="Descent"
|
|
42220
|
+
waypointstatus[#wp]=RAT.status.DescentHolding
|
|
41891
42221
|
else
|
|
41892
42222
|
c[#c+1]=c[#c]:Translate(d_descent/2,heading)
|
|
41893
42223
|
wp[#wp+1]=self:_Waypoint(#wp+1,"Descent",RAT.wp.descent,c[#wp+1],VxDescent,FLcruise-(FLcruise-(h_holding+H_holding))/2)
|
|
41894
|
-
|
|
41895
|
-
|
|
42224
|
+
waypointdescriptions[#wp]="Descent"
|
|
42225
|
+
waypointstatus[#wp]=RAT.status.DescentHolding
|
|
41896
42226
|
end
|
|
41897
42227
|
end
|
|
41898
42228
|
if landing==RAT.wp.landing then
|
|
41899
|
-
c[#c+1]=Pholding
|
|
41900
|
-
wp[#wp+1]=self:_Waypoint(#wp+1,"Holding Point",RAT.wp.holding,c[#wp+1],VxHolding,H_holding+h_holding)
|
|
41901
|
-
self.waypointdescriptions[#wp]="Holding Point"
|
|
41902
|
-
self.waypointstatus[#wp]=RAT.status.Holding
|
|
41903
|
-
wpholding=#wp
|
|
41904
42229
|
c[#c+1]=Pdestination
|
|
41905
42230
|
wp[#wp+1]=self:_Waypoint(#wp+1,"Final Destination",landing,c[#wp+1],VxFinal,H_destination,destination)
|
|
41906
|
-
|
|
41907
|
-
|
|
42231
|
+
waypointdescriptions[#wp]="Final Destination"
|
|
42232
|
+
waypointstatus[#wp]=RAT.status.Destination
|
|
41908
42233
|
end
|
|
41909
42234
|
wpfinal=#wp
|
|
41910
42235
|
local waypoints={}
|
|
41911
42236
|
for _,p in ipairs(wp)do
|
|
41912
42237
|
table.insert(waypoints,p)
|
|
41913
42238
|
end
|
|
41914
|
-
self:_Routeinfo(waypoints,"Waypoint info in set_route:")
|
|
42239
|
+
self:_Routeinfo(waypoints,"Waypoint info in set_route:",waypointdescriptions)
|
|
41915
42240
|
if self.returnzone then
|
|
41916
|
-
return departure,destination_returnzone,waypoints,
|
|
42241
|
+
return departure,destination_returnzone,waypoints,waypointdescriptions,waypointstatus
|
|
41917
42242
|
else
|
|
41918
|
-
return departure,destination,waypoints,
|
|
42243
|
+
return departure,destination,waypoints,waypointdescriptions,waypointstatus
|
|
41919
42244
|
end
|
|
41920
42245
|
end
|
|
41921
42246
|
function RAT:_PickDeparture(takeoff)
|
|
@@ -41958,17 +42283,17 @@ elseif self:_ZoneExists(name)then
|
|
|
41958
42283
|
if takeoff==RAT.wp.air then
|
|
41959
42284
|
dep=ZONE:FindByName(name)
|
|
41960
42285
|
else
|
|
41961
|
-
self:E(
|
|
42286
|
+
self:E(self.lid..string.format("ERROR! Takeoff is not in air. Cannot use %s as departure.",name))
|
|
41962
42287
|
end
|
|
41963
42288
|
else
|
|
41964
|
-
self:E(
|
|
42289
|
+
self:E(self.lid..string.format("ERROR: No airport or zone found with name %s.",name))
|
|
41965
42290
|
end
|
|
41966
42291
|
if dep then
|
|
41967
42292
|
table.insert(departures,dep)
|
|
41968
42293
|
end
|
|
41969
42294
|
end
|
|
41970
42295
|
end
|
|
41971
|
-
self:T(
|
|
42296
|
+
self:T(self.lid..string.format("Number of possible departures for %s= %d",self.alias,#departures))
|
|
41972
42297
|
local departure=departures[math.random(#departures)]
|
|
41973
42298
|
local text
|
|
41974
42299
|
if departure and departure:GetName()then
|
|
@@ -41977,9 +42302,9 @@ text=string.format("%s: Chosen departure zone: %s",self.alias,departure:GetName(
|
|
|
41977
42302
|
else
|
|
41978
42303
|
text=string.format("%s: Chosen departure airport: %s (ID %d)",self.alias,departure:GetName(),departure:GetID())
|
|
41979
42304
|
end
|
|
41980
|
-
self:T(
|
|
42305
|
+
self:T(self.lid..text)
|
|
41981
42306
|
else
|
|
41982
|
-
self:E(
|
|
42307
|
+
self:E(self.lid..string.format("ERROR! No departure airport or zone found for %s.",self.alias))
|
|
41983
42308
|
departure=nil
|
|
41984
42309
|
end
|
|
41985
42310
|
return departure
|
|
@@ -42030,10 +42355,10 @@ elseif self:_ZoneExists(name)then
|
|
|
42030
42355
|
if landing==RAT.wp.air then
|
|
42031
42356
|
dest=ZONE:FindByName(name)
|
|
42032
42357
|
else
|
|
42033
|
-
self:E(
|
|
42358
|
+
self:E(self.lid..string.format("ERROR! Landing is not in air. Cannot use zone %s as destination!",name))
|
|
42034
42359
|
end
|
|
42035
42360
|
else
|
|
42036
|
-
self:E(
|
|
42361
|
+
self:E(self.lid..string.format("ERROR! No airport or zone found with name %s",name))
|
|
42037
42362
|
end
|
|
42038
42363
|
if dest then
|
|
42039
42364
|
local distance=q:Get2DDistance(dest:GetCoordinate())
|
|
@@ -42041,13 +42366,13 @@ if distance>=minrange and distance<=maxrange then
|
|
|
42041
42366
|
table.insert(destinations,dest)
|
|
42042
42367
|
else
|
|
42043
42368
|
local text=string.format("Destination %s is ouside range. Distance = %5.1f km, min = %5.1f km, max = %5.1f km.",name,distance,minrange,maxrange)
|
|
42044
|
-
self:T(
|
|
42369
|
+
self:T(self.lid..text)
|
|
42045
42370
|
end
|
|
42046
42371
|
end
|
|
42047
42372
|
end
|
|
42048
42373
|
end
|
|
42049
42374
|
end
|
|
42050
|
-
self:T(
|
|
42375
|
+
self:T(self.lid..string.format("Number of possible destinations = %s.",#destinations))
|
|
42051
42376
|
if#destinations>0 then
|
|
42052
42377
|
local function compare(a,b)
|
|
42053
42378
|
local qa=q:Get2DDistance(a:GetCoordinate())
|
|
@@ -42067,9 +42392,9 @@ text=string.format("%s: Chosen destination zone: %s.",self.alias,destination:Get
|
|
|
42067
42392
|
else
|
|
42068
42393
|
text=string.format("%s Chosen destination airport: %s (ID %d).",self.alias,destination:GetName(),destination:GetID())
|
|
42069
42394
|
end
|
|
42070
|
-
self:T(
|
|
42395
|
+
self:T(self.lid..text)
|
|
42071
42396
|
else
|
|
42072
|
-
self:E(
|
|
42397
|
+
self:E(self.lid.."ERROR! No destination airport or zone found.")
|
|
42073
42398
|
destination=nil
|
|
42074
42399
|
end
|
|
42075
42400
|
return destination
|
|
@@ -42121,9 +42446,9 @@ local _myab=AIRBASE:FindByName(_name)
|
|
|
42121
42446
|
if _myab then
|
|
42122
42447
|
table.insert(self.airports_map,_myab)
|
|
42123
42448
|
local text="MOOSE: Airport ID = ".._myab:GetID().." and Name = ".._myab:GetName()..", Category = ".._myab:GetCategory()..", TypeName = ".._myab:GetTypeName()
|
|
42124
|
-
self:T(
|
|
42449
|
+
self:T(self.lid..text)
|
|
42125
42450
|
else
|
|
42126
|
-
self:E(
|
|
42451
|
+
self:E(self.lid..string.format("WARNING: Airbase %s does not exsist as MOOSE object!",tostring(_name)))
|
|
42127
42452
|
end
|
|
42128
42453
|
end
|
|
42129
42454
|
end
|
|
@@ -42145,31 +42470,26 @@ end
|
|
|
42145
42470
|
if#self.airports==0 then
|
|
42146
42471
|
local text=string.format("No possible departure/destination airports found for RAT %s.",tostring(self.alias))
|
|
42147
42472
|
MESSAGE:New(text,10):ToAll()
|
|
42148
|
-
self:E(
|
|
42473
|
+
self:E(self.lid..text)
|
|
42149
42474
|
end
|
|
42150
42475
|
end
|
|
42151
42476
|
function RAT:Status(message,forID)
|
|
42152
|
-
|
|
42153
|
-
message=false
|
|
42154
|
-
end
|
|
42155
|
-
if forID==nil then
|
|
42156
|
-
forID=false
|
|
42157
|
-
end
|
|
42477
|
+
self:T(self.lid.."Checking status")
|
|
42158
42478
|
local Tnow=timer.getTime()
|
|
42159
42479
|
local nalive=0
|
|
42160
|
-
for spawnindex,
|
|
42480
|
+
for spawnindex,_ratcraft in pairs(self.ratcraft)do
|
|
42481
|
+
local ratcraft=_ratcraft
|
|
42482
|
+
self:T(self.lid..string.format("Ratcraft Index=%s",tostring(spawnindex)))
|
|
42161
42483
|
local group=ratcraft.group
|
|
42162
|
-
if group and group:IsAlive()
|
|
42484
|
+
if group and group:IsAlive()then
|
|
42163
42485
|
nalive=nalive+1
|
|
42486
|
+
self:T(self.lid..string.format("Ratcraft Index=%s is ALIVE",tostring(spawnindex)))
|
|
42164
42487
|
local prefix=self:_GetPrefixFromGroup(group)
|
|
42165
42488
|
local life=self:_GetLife(group)
|
|
42166
42489
|
local fuel=group:GetFuel()*100.0
|
|
42167
42490
|
local airborne=group:InAir()
|
|
42168
|
-
local coords=group:GetCoordinate()
|
|
42169
|
-
local alt=1000
|
|
42170
|
-
if coords then
|
|
42171
|
-
alt=coords.y or 1000
|
|
42172
|
-
end
|
|
42491
|
+
local coords=group:GetCoordinate()
|
|
42492
|
+
local alt=coords~=nil and coords.y or 1000
|
|
42173
42493
|
local departure=ratcraft.departure:GetName()
|
|
42174
42494
|
local destination=ratcraft.destination:GetName()
|
|
42175
42495
|
local type=self.aircraft.type
|
|
@@ -42177,52 +42497,16 @@ local status=ratcraft.status
|
|
|
42177
42497
|
local active=ratcraft.active
|
|
42178
42498
|
local Nunits=ratcraft.nunits
|
|
42179
42499
|
local N0units=group:GetInitialSize()
|
|
42180
|
-
local
|
|
42181
|
-
|
|
42182
|
-
local
|
|
42183
|
-
|
|
42184
|
-
if airborne then
|
|
42185
|
-
ratcraft["Tground"]=nil
|
|
42186
|
-
ratcraft["Pground"]=nil
|
|
42187
|
-
ratcraft["Uground"]=nil
|
|
42188
|
-
ratcraft["Tlastcheck"]=nil
|
|
42189
|
-
else
|
|
42190
|
-
if ratcraft["Tground"]then
|
|
42191
|
-
Tg=Tnow-ratcraft["Tground"]
|
|
42192
|
-
Dg=coords:Get2DDistance(ratcraft["Pground"])
|
|
42193
|
-
dTlast=Tnow-ratcraft["Tlastcheck"]
|
|
42194
|
-
if dTlast>self.Tinactive then
|
|
42195
|
-
for _,_unit in pairs(group:GetUnits())do
|
|
42196
|
-
if _unit and _unit:IsAlive()then
|
|
42197
|
-
local unitname=_unit:GetName()
|
|
42198
|
-
local unitcoord=_unit:GetCoordinate()
|
|
42199
|
-
local Ug=unitcoord:Get2DDistance(ratcraft.Uground[unitname])
|
|
42200
|
-
self:T2(RAT.id..string.format("Unit %s travelled distance on ground %.1f m since %d seconds.",unitname,Ug,dTlast))
|
|
42201
|
-
if Ug<50 and active and status~=RAT.status.EventBirth then
|
|
42202
|
-
stationary=true
|
|
42500
|
+
local Dtravel=0
|
|
42501
|
+
if coords and ratcraft.Pnow then
|
|
42502
|
+
local Dtravel=coords:Get2DDistance(ratcraft.Pnow)
|
|
42503
|
+
ratcraft.Pnow=coords
|
|
42203
42504
|
end
|
|
42204
|
-
ratcraft
|
|
42505
|
+
ratcraft.Distance=ratcraft.Distance+Dtravel
|
|
42506
|
+
local Ddestination=-1
|
|
42507
|
+
if ratcraft.Pnow then
|
|
42508
|
+
Ddestination=ratcraft.Pnow:Get2DDistance(ratcraft.destination:GetCoordinate())
|
|
42205
42509
|
end
|
|
42206
|
-
end
|
|
42207
|
-
ratcraft["Tlastcheck"]=Tnow
|
|
42208
|
-
ratcraft["Pground"]=coords
|
|
42209
|
-
end
|
|
42210
|
-
else
|
|
42211
|
-
ratcraft["Tground"]=Tnow
|
|
42212
|
-
ratcraft["Tlastcheck"]=Tnow
|
|
42213
|
-
ratcraft["Pground"]=coords
|
|
42214
|
-
ratcraft["Uground"]={}
|
|
42215
|
-
for _,_unit in pairs(group:GetUnits())do
|
|
42216
|
-
local unitname=_unit:GetName()
|
|
42217
|
-
ratcraft.Uground[unitname]=_unit:GetCoordinate()
|
|
42218
|
-
end
|
|
42219
|
-
end
|
|
42220
|
-
end
|
|
42221
|
-
local Pn=coords
|
|
42222
|
-
local Dtravel=Pn:Get2DDistance(ratcraft["Pnow"])
|
|
42223
|
-
ratcraft["Pnow"]=Pn
|
|
42224
|
-
ratcraft["Distance"]=ratcraft["Distance"]+Dtravel
|
|
42225
|
-
local Ddestination=Pn:Get2DDistance(ratcraft.destination:GetCoordinate())
|
|
42226
42510
|
if(forID and spawnindex==forID)or(not forID)then
|
|
42227
42511
|
local text=string.format("ID %i of flight %s",spawnindex,prefix)
|
|
42228
42512
|
if N0units>1 then
|
|
@@ -42243,53 +42527,46 @@ text=text.." [airborne]\n"
|
|
|
42243
42527
|
else
|
|
42244
42528
|
text=text.." [on ground]\n"
|
|
42245
42529
|
end
|
|
42246
|
-
text=text..string.format("Fuel
|
|
42247
|
-
text=text..string.format("Life
|
|
42248
|
-
text=text..string.format("FL%03d
|
|
42249
|
-
text=text..string.format("Distance travelled
|
|
42250
|
-
text=text..string.format("Distance to
|
|
42251
|
-
|
|
42252
|
-
text=text..string.format("\nTime on ground = %6.0f seconds\n",Tg)
|
|
42253
|
-
text=text..string.format("Position change = %8.1f m since %3.0f seconds.",Dg,dTlast)
|
|
42254
|
-
end
|
|
42255
|
-
self:T(RAT.id..text)
|
|
42530
|
+
text=text..string.format("Fuel = %3.0f %%\n",fuel)
|
|
42531
|
+
text=text..string.format("Life = %3.0f %%\n",life)
|
|
42532
|
+
text=text..string.format("FL%03d = %i m ASL\n",alt/RAT.unit.FL2m,alt)
|
|
42533
|
+
text=text..string.format("Distance travelled = %6.1f km\n",ratcraft["Distance"]/1000)
|
|
42534
|
+
text=text..string.format("Distance to dest = %6.1f km",Ddestination/1000)
|
|
42535
|
+
self:T(self.lid..text)
|
|
42256
42536
|
if message then
|
|
42257
42537
|
MESSAGE:New(text,20):ToAll()
|
|
42258
42538
|
end
|
|
42259
42539
|
end
|
|
42260
|
-
if not airborne then
|
|
42261
|
-
if stationary then
|
|
42262
|
-
local text=string.format("Group %s is despawned after being %d seconds inaktive on ground.",self.alias,dTlast)
|
|
42263
|
-
self:T(RAT.id..text)
|
|
42264
|
-
self:_Despawn(group)
|
|
42265
|
-
end
|
|
42266
|
-
if life<10 and Dtravel<100 then
|
|
42267
|
-
local text=string.format("Damaged group %s is despawned. Life = %3.0f",self.alias,life)
|
|
42268
|
-
self:T(RAT.id..text)
|
|
42269
|
-
self:_Despawn(group)
|
|
42270
|
-
end
|
|
42271
|
-
end
|
|
42272
42540
|
if ratcraft.despawnme then
|
|
42273
|
-
|
|
42274
|
-
self:T(RAT.id..text)
|
|
42275
|
-
if(not self.norespawn)and(not self.respawn_after_takeoff)then
|
|
42276
|
-
local idx=self:GetSpawnIndexFromGroup(group)
|
|
42277
|
-
local coord=group:GetCoordinate()
|
|
42278
|
-
self:_Respawn(idx,coord,0)
|
|
42279
|
-
end
|
|
42541
|
+
if self.norespawn or self.respawn_after_takeoff then
|
|
42280
42542
|
if self.despawnair then
|
|
42281
|
-
self:
|
|
42543
|
+
self:T(self.lid..string.format("[STATUS despawnme] Flight %s will be despawned NOW and NO new group is created!",self.alias))
|
|
42544
|
+
self:_Despawn(group)
|
|
42545
|
+
end
|
|
42546
|
+
else
|
|
42547
|
+
self:T(self.lid..string.format("[STATUS despawnme] Flight %s will be despawned NOW and a new group is respawned!",self.alias))
|
|
42548
|
+
self:_Respawn(group)
|
|
42282
42549
|
end
|
|
42283
42550
|
end
|
|
42284
42551
|
else
|
|
42285
|
-
local text=string.format("Group does not exist in loop ratcraft status
|
|
42286
|
-
self:T2(
|
|
42552
|
+
local text=string.format("Group does not exist in loop ratcraft status for spawn index=%d",spawnindex)
|
|
42553
|
+
self:T2(self.lid..text)
|
|
42554
|
+
self:T2(ratcraft)
|
|
42287
42555
|
end
|
|
42288
42556
|
end
|
|
42289
42557
|
local text=string.format("Alive groups of %s: %d, nalive=%d/%d",self.alias,self.alive,nalive,self.ngroups)
|
|
42290
|
-
self:T(
|
|
42558
|
+
self:T(self.lid..text)
|
|
42291
42559
|
MESSAGE:New(text,20):ToAllIf(message and not forID)
|
|
42292
42560
|
end
|
|
42561
|
+
function RAT:_RemoveRatcraft(ratcraft)
|
|
42562
|
+
self.ratcraft[ratcraft.index]=nil
|
|
42563
|
+
return self
|
|
42564
|
+
end
|
|
42565
|
+
function RAT:_GetRatcraftFromGroup(group)
|
|
42566
|
+
local index=self:GetSpawnIndexFromGroup(group)
|
|
42567
|
+
local ratcraft=self.ratcraft[index]
|
|
42568
|
+
return ratcraft
|
|
42569
|
+
end
|
|
42293
42570
|
function RAT:_GetLife(group)
|
|
42294
42571
|
local life=0.0
|
|
42295
42572
|
if group and group:IsAlive()then
|
|
@@ -42297,48 +42574,56 @@ local unit=group:GetUnit(1)
|
|
|
42297
42574
|
if unit then
|
|
42298
42575
|
life=unit:GetLife()/unit:GetLife0()*100
|
|
42299
42576
|
else
|
|
42300
|
-
self:T2(
|
|
42577
|
+
self:T2(self.lid.."ERROR! Unit does not exist in RAT_Getlife(). Returning zero.")
|
|
42301
42578
|
end
|
|
42302
42579
|
else
|
|
42303
|
-
self:T2(
|
|
42580
|
+
self:T2(self.lid.."ERROR! Group does not exist in RAT_Getlife(). Returning zero.")
|
|
42304
42581
|
end
|
|
42305
42582
|
return life
|
|
42306
42583
|
end
|
|
42307
42584
|
function RAT:_SetStatus(group,status)
|
|
42308
42585
|
if group and group:IsAlive()then
|
|
42309
|
-
local
|
|
42310
|
-
if
|
|
42311
|
-
|
|
42586
|
+
local ratcraft=self:_GetRatcraftFromGroup(group)
|
|
42587
|
+
if ratcraft then
|
|
42588
|
+
ratcraft.status=status
|
|
42312
42589
|
local no1=status==RAT.status.Departure
|
|
42313
42590
|
local no2=status==RAT.status.EventBirthAir
|
|
42314
42591
|
local no3=status==RAT.status.Holding
|
|
42315
|
-
local text=string.format("Flight %s: %s
|
|
42316
|
-
self:T(
|
|
42592
|
+
local text=string.format("Flight %s: %s",group:GetName(),status)
|
|
42593
|
+
self:T(self.lid..text)
|
|
42317
42594
|
if not(no1 or no2 or no3)then
|
|
42318
42595
|
MESSAGE:New(text,10):ToAllIf(self.reportstatus)
|
|
42319
42596
|
end
|
|
42320
42597
|
end
|
|
42321
42598
|
end
|
|
42322
42599
|
end
|
|
42323
|
-
function RAT:
|
|
42324
|
-
if group
|
|
42600
|
+
function RAT:_GetRatcraftFromGroup(group)
|
|
42601
|
+
if group then
|
|
42325
42602
|
local index=self:GetSpawnIndexFromGroup(group)
|
|
42326
42603
|
if self.ratcraft[index]then
|
|
42327
|
-
return self.ratcraft[index]
|
|
42604
|
+
return self.ratcraft[index]
|
|
42605
|
+
end
|
|
42606
|
+
end
|
|
42607
|
+
return nil
|
|
42608
|
+
end
|
|
42609
|
+
function RAT:GetStatus(group)
|
|
42610
|
+
if group and group:IsAlive()then
|
|
42611
|
+
local ratcraft=self:_GetRatcraftFromGroup(group)
|
|
42612
|
+
if ratcraft then
|
|
42613
|
+
return ratcraft.status
|
|
42328
42614
|
end
|
|
42329
42615
|
end
|
|
42330
42616
|
return"nonexistant"
|
|
42331
42617
|
end
|
|
42332
42618
|
function RAT:_OnBirth(EventData)
|
|
42333
42619
|
self:F3(EventData)
|
|
42334
|
-
self:T3(
|
|
42620
|
+
self:T3(self.lid.."Captured event birth!")
|
|
42335
42621
|
local SpawnGroup=EventData.IniGroup
|
|
42336
42622
|
if SpawnGroup then
|
|
42337
42623
|
local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
|
|
42338
|
-
if EventPrefix then
|
|
42339
|
-
if EventPrefix==self.alias then
|
|
42624
|
+
if EventPrefix and EventPrefix==self.alias then
|
|
42340
42625
|
local text="Event: Group "..SpawnGroup:GetName().." was born."
|
|
42341
|
-
self:T(
|
|
42626
|
+
self:T(self.lid..text)
|
|
42342
42627
|
local status="unknown in birth"
|
|
42343
42628
|
if SpawnGroup:InAir()then
|
|
42344
42629
|
status=RAT.status.EventBirthAir
|
|
@@ -42349,12 +42634,13 @@ status=RAT.status.EventBirth
|
|
|
42349
42634
|
end
|
|
42350
42635
|
self:_SetStatus(SpawnGroup,status)
|
|
42351
42636
|
local i=self:GetSpawnIndexFromGroup(SpawnGroup)
|
|
42352
|
-
local
|
|
42353
|
-
local
|
|
42354
|
-
local
|
|
42355
|
-
local
|
|
42356
|
-
local
|
|
42357
|
-
local
|
|
42637
|
+
local ratcraft=self.ratcraft[i]
|
|
42638
|
+
local _departure=ratcraft.departure:GetName()
|
|
42639
|
+
local _destination=ratcraft.destination:GetName()
|
|
42640
|
+
local _nrespawn=ratcraft.nrespawn
|
|
42641
|
+
local _takeoff=ratcraft.takeoff
|
|
42642
|
+
local _landing=ratcraft.landing
|
|
42643
|
+
local _livery=ratcraft.livery
|
|
42358
42644
|
local _airbase=AIRBASE:FindByName(_departure)
|
|
42359
42645
|
local onrunway=false
|
|
42360
42646
|
if _airbase then
|
|
@@ -42365,7 +42651,7 @@ end
|
|
|
42365
42651
|
if onrunway then
|
|
42366
42652
|
local text=string.format("ERROR: RAT group of %s was spawned on runway. Group #%d will be despawned immediately!",self.alias,i)
|
|
42367
42653
|
MESSAGE:New(text,30):ToAllIf(self.Debug)
|
|
42368
|
-
self:E(
|
|
42654
|
+
self:E(self.lid..text)
|
|
42369
42655
|
if self.Debug then
|
|
42370
42656
|
SpawnGroup:FlareRed()
|
|
42371
42657
|
end
|
|
@@ -42374,13 +42660,13 @@ if(self.Ndeparture_Airports>=2 or self.random_departure)and _nrespawn<self.onrun
|
|
|
42374
42660
|
_nrespawn=_nrespawn+1
|
|
42375
42661
|
text=string.format("Try spawning new aircraft of group %s at another location. Attempt %d of max %d.",self.alias,_nrespawn,self.onrunwaymaxretry)
|
|
42376
42662
|
MESSAGE:New(text,10):ToAllIf(self.Debug)
|
|
42377
|
-
self:T(
|
|
42663
|
+
self:T(self.lid..text)
|
|
42378
42664
|
self:_SpawnWithRoute(nil,nil,nil,nil,nil,nil,nil,_nrespawn)
|
|
42379
42665
|
else
|
|
42380
42666
|
if self.respawn_inair and not self.uncontrolled then
|
|
42381
42667
|
text=string.format("Spawning new aircraft of group %s in air since no parking slot is available at %s.",self.alias,_departure)
|
|
42382
42668
|
MESSAGE:New(text,10):ToAll()
|
|
42383
|
-
self:T(
|
|
42669
|
+
self:T(self.lid..text)
|
|
42384
42670
|
self:_SpawnWithRoute(_departure,_destination,RAT.wp.air,_landing,_livery)
|
|
42385
42671
|
end
|
|
42386
42672
|
end
|
|
@@ -42392,28 +42678,26 @@ end
|
|
|
42392
42678
|
if ontop then
|
|
42393
42679
|
local text=string.format("ERROR: Group of %s was spawned on top of another unit. Group #%d will be despawned immediately!",self.alias,i)
|
|
42394
42680
|
MESSAGE:New(text,30):ToAllIf(self.Debug)
|
|
42395
|
-
self:T(
|
|
42681
|
+
self:T(self.lid..text)
|
|
42396
42682
|
if self.Debug then
|
|
42397
42683
|
SpawnGroup:FlareYellow()
|
|
42398
42684
|
end
|
|
42399
42685
|
self:_Despawn(SpawnGroup)
|
|
42400
42686
|
end
|
|
42401
42687
|
end
|
|
42402
|
-
end
|
|
42403
42688
|
else
|
|
42404
|
-
self:T2(
|
|
42689
|
+
self:T2(self.lid.."ERROR: Group does not exist in RAT:_OnBirth().")
|
|
42405
42690
|
end
|
|
42406
42691
|
end
|
|
42407
42692
|
function RAT:_OnEngineStartup(EventData)
|
|
42408
42693
|
self:F3(EventData)
|
|
42409
|
-
self:T3(
|
|
42694
|
+
self:T3(self.lid.."Captured event EngineStartup!")
|
|
42410
42695
|
local SpawnGroup=EventData.IniGroup
|
|
42411
42696
|
if SpawnGroup then
|
|
42412
42697
|
local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
|
|
42413
|
-
if EventPrefix then
|
|
42414
|
-
if EventPrefix==self.alias then
|
|
42698
|
+
if EventPrefix and EventPrefix==self.alias then
|
|
42415
42699
|
local text="Event: Group "..SpawnGroup:GetName().." started engines."
|
|
42416
|
-
self:T(
|
|
42700
|
+
self:T(self.lid..text)
|
|
42417
42701
|
local status
|
|
42418
42702
|
if SpawnGroup:InAir()then
|
|
42419
42703
|
status=RAT.status.EventEngineStartAir
|
|
@@ -42422,61 +42706,54 @@ status=RAT.status.EventEngineStart
|
|
|
42422
42706
|
end
|
|
42423
42707
|
self:_SetStatus(SpawnGroup,status)
|
|
42424
42708
|
end
|
|
42425
|
-
end
|
|
42426
42709
|
else
|
|
42427
|
-
self:T2(
|
|
42710
|
+
self:T2(self.lid.."ERROR: Group does not exist in RAT:_EngineStartup().")
|
|
42428
42711
|
end
|
|
42429
42712
|
end
|
|
42430
42713
|
function RAT:_OnTakeoff(EventData)
|
|
42431
42714
|
local SpawnGroup=EventData.IniGroup
|
|
42432
42715
|
if SpawnGroup then
|
|
42433
42716
|
local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
|
|
42434
|
-
if EventPrefix then
|
|
42435
|
-
if EventPrefix==self.alias then
|
|
42717
|
+
if EventPrefix and EventPrefix==self.alias then
|
|
42436
42718
|
local text="Event: Group "..SpawnGroup:GetName().." is airborne."
|
|
42437
|
-
self:T(
|
|
42719
|
+
self:T(self.lid..text)
|
|
42438
42720
|
local status=RAT.status.EventTakeoff
|
|
42439
42721
|
self:_SetStatus(SpawnGroup,status)
|
|
42440
42722
|
if self.respawn_after_takeoff then
|
|
42441
42723
|
text="Event: Group "..SpawnGroup:GetName().." will be respawned after takeoff."
|
|
42442
|
-
self:T(
|
|
42724
|
+
self:T(self.lid..text)
|
|
42443
42725
|
self:_SpawnWithRoute(nil,nil,nil,nil,nil,nil,nil,nil)
|
|
42444
42726
|
end
|
|
42445
42727
|
end
|
|
42446
|
-
end
|
|
42447
42728
|
else
|
|
42448
|
-
self:T2(
|
|
42729
|
+
self:T2(self.lid.."ERROR: Group does not exist in RAT:_OnTakeoff().")
|
|
42449
42730
|
end
|
|
42450
42731
|
end
|
|
42451
42732
|
function RAT:_OnLand(EventData)
|
|
42452
42733
|
local SpawnGroup=EventData.IniGroup
|
|
42453
42734
|
if SpawnGroup then
|
|
42454
42735
|
local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
|
|
42455
|
-
if EventPrefix then
|
|
42456
|
-
|
|
42457
|
-
|
|
42458
|
-
self:T(RAT.id..text)
|
|
42736
|
+
if EventPrefix and EventPrefix==self.alias then
|
|
42737
|
+
local text="Event: Group "..SpawnGroup:GetName().." landed"
|
|
42738
|
+
self:T(self.lid..text)
|
|
42459
42739
|
local status=RAT.status.EventLand
|
|
42460
42740
|
self:_SetStatus(SpawnGroup,status)
|
|
42461
42741
|
if self.ATCswitch then
|
|
42462
|
-
RAT
|
|
42742
|
+
RAT._ATCFlightLanded(SpawnGroup:GetName())
|
|
42463
42743
|
end
|
|
42464
42744
|
if self.respawn_at_landing and not self.norespawn then
|
|
42465
|
-
text="Event: Group "..SpawnGroup:GetName().." will be respawned
|
|
42466
|
-
self:T(
|
|
42467
|
-
|
|
42468
|
-
local coord=SpawnGroup:GetCoordinate()
|
|
42469
|
-
self:_Respawn(idx,coord)
|
|
42470
|
-
end
|
|
42745
|
+
text="Event: Group "..SpawnGroup:GetName().." will be respawned"
|
|
42746
|
+
self:T(self.lid..text)
|
|
42747
|
+
self:_Respawn(SpawnGroup)
|
|
42471
42748
|
end
|
|
42472
42749
|
end
|
|
42473
42750
|
else
|
|
42474
|
-
self:T2(
|
|
42751
|
+
self:T2(self.lid.."ERROR: Group does not exist in RAT:_OnLand()")
|
|
42475
42752
|
end
|
|
42476
42753
|
end
|
|
42477
42754
|
function RAT:_OnEngineShutdown(EventData)
|
|
42478
42755
|
self:F3(EventData)
|
|
42479
|
-
self:T3(
|
|
42756
|
+
self:T3(self.lid.."Captured event EngineShutdown!")
|
|
42480
42757
|
local SpawnGroup=EventData.IniGroup
|
|
42481
42758
|
if SpawnGroup then
|
|
42482
42759
|
local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
|
|
@@ -42484,35 +42761,34 @@ if EventPrefix and EventPrefix==self.alias then
|
|
|
42484
42761
|
if not SpawnGroup:InAir()then
|
|
42485
42762
|
local currentstate=self:GetStatus(SpawnGroup)
|
|
42486
42763
|
local text=string.format("Event: Unit %s of group %s shut down its engines. Current state %s.",EventData.IniUnitName,SpawnGroup:GetName(),currentstate)
|
|
42487
|
-
self:T(
|
|
42764
|
+
self:T(self.lid..text)
|
|
42488
42765
|
if currentstate~=RAT.status.EventEngineShutdown and currentstate~="Dead"then
|
|
42489
42766
|
local status=RAT.status.EventEngineShutdown
|
|
42490
42767
|
self:_SetStatus(SpawnGroup,status)
|
|
42491
42768
|
if not self.respawn_at_landing and not self.norespawn then
|
|
42492
42769
|
text=string.format("Event: Group %s will be respawned. Current state %s => new state %s.",SpawnGroup:GetName(),currentstate,status)
|
|
42493
|
-
self:T(
|
|
42494
|
-
|
|
42495
|
-
|
|
42496
|
-
|
|
42497
|
-
|
|
42498
|
-
text="Event: Group "..SpawnGroup:GetName().." will be destroyed now."
|
|
42499
|
-
self:T(RAT.id..text)
|
|
42770
|
+
self:T(self.lid..text)
|
|
42771
|
+
self:_Respawn(SpawnGroup,nil,3)
|
|
42772
|
+
else
|
|
42773
|
+
text="Event: Group "..SpawnGroup:GetName().." will be destroyed now"
|
|
42774
|
+
self:T(self.lid..text)
|
|
42500
42775
|
self:_Despawn(SpawnGroup)
|
|
42501
42776
|
end
|
|
42502
42777
|
end
|
|
42503
42778
|
end
|
|
42779
|
+
end
|
|
42504
42780
|
else
|
|
42505
|
-
self:T2(
|
|
42781
|
+
self:T2(self.lid.."ERROR: Group does not exist in RAT:_OnEngineShutdown().")
|
|
42506
42782
|
end
|
|
42507
42783
|
end
|
|
42508
42784
|
function RAT:_OnHit(EventData)
|
|
42509
42785
|
self:F3(EventData)
|
|
42510
|
-
self:T(
|
|
42786
|
+
self:T(self.lid..string.format("Captured event Hit by %s! Initiator %s. Target %s",self.alias,tostring(EventData.IniUnitName),tostring(EventData.TgtUnitName)))
|
|
42511
42787
|
local SpawnGroup=EventData.TgtGroup
|
|
42512
42788
|
if SpawnGroup then
|
|
42513
42789
|
local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
|
|
42514
42790
|
if EventPrefix and EventPrefix==self.alias then
|
|
42515
|
-
self:T(
|
|
42791
|
+
self:T(self.lid..string.format("Event: Group %s was hit. Unit %s.",SpawnGroup:GetName(),tostring(EventData.TgtUnitName)))
|
|
42516
42792
|
local text=string.format("%s, unit %s was hit!",self.alias,EventData.TgtUnitName)
|
|
42517
42793
|
MESSAGE:New(text,10):ToAllIf(self.reportstatus or self.Debug)
|
|
42518
42794
|
end
|
|
@@ -42520,7 +42796,7 @@ end
|
|
|
42520
42796
|
end
|
|
42521
42797
|
function RAT:_OnDeadOrCrash(EventData)
|
|
42522
42798
|
self:F3(EventData)
|
|
42523
|
-
self:T3(
|
|
42799
|
+
self:T3(self.lid.."Captured event DeadOrCrash!")
|
|
42524
42800
|
local SpawnGroup=EventData.IniGroup
|
|
42525
42801
|
if SpawnGroup then
|
|
42526
42802
|
local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
|
|
@@ -42528,7 +42804,7 @@ if EventPrefix then
|
|
|
42528
42804
|
if EventPrefix==self.alias then
|
|
42529
42805
|
self.alive=self.alive-1
|
|
42530
42806
|
local text=string.format("Event: Group %s crashed or died. Alive counter = %d.",SpawnGroup:GetName(),self.alive)
|
|
42531
|
-
self:T(
|
|
42807
|
+
self:T(self.lid..text)
|
|
42532
42808
|
if EventData.id==world.event.S_EVENT_CRASH then
|
|
42533
42809
|
self:_OnCrash(EventData)
|
|
42534
42810
|
elseif EventData.id==world.event.S_EVENT_DEAD then
|
|
@@ -42540,98 +42816,50 @@ end
|
|
|
42540
42816
|
end
|
|
42541
42817
|
function RAT:_OnDead(EventData)
|
|
42542
42818
|
self:F3(EventData)
|
|
42543
|
-
self:T3(
|
|
42819
|
+
self:T3(self.lid.."Captured event Dead!")
|
|
42544
42820
|
local SpawnGroup=EventData.IniGroup
|
|
42545
42821
|
if SpawnGroup then
|
|
42546
42822
|
local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
|
|
42547
42823
|
if EventPrefix then
|
|
42548
42824
|
if EventPrefix==self.alias then
|
|
42549
42825
|
local text=string.format("Event: Group %s died. Unit %s.",SpawnGroup:GetName(),EventData.IniUnitName)
|
|
42550
|
-
self:T(
|
|
42826
|
+
self:T(self.lid..text)
|
|
42551
42827
|
local status=RAT.status.EventDead
|
|
42552
42828
|
self:_SetStatus(SpawnGroup,status)
|
|
42553
42829
|
end
|
|
42554
42830
|
end
|
|
42555
42831
|
else
|
|
42556
|
-
self:T2(
|
|
42832
|
+
self:T2(self.lid.."ERROR: Group does not exist in RAT:_OnDead().")
|
|
42557
42833
|
end
|
|
42558
42834
|
end
|
|
42559
42835
|
function RAT:_OnCrash(EventData)
|
|
42560
42836
|
self:F3(EventData)
|
|
42561
|
-
self:T3(
|
|
42837
|
+
self:T3(self.lid.."Captured event Crash!")
|
|
42562
42838
|
local SpawnGroup=EventData.IniGroup
|
|
42563
42839
|
if SpawnGroup then
|
|
42564
42840
|
local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
|
|
42565
42841
|
if EventPrefix and EventPrefix==self.alias then
|
|
42566
|
-
local
|
|
42567
|
-
|
|
42568
|
-
|
|
42842
|
+
local ratcraft=self:_GetRatcraftFromGroup(SpawnGroup)
|
|
42843
|
+
if ratcraft then
|
|
42844
|
+
ratcraft.nunits=ratcraft.nunits-1
|
|
42569
42845
|
local _n0=SpawnGroup:GetInitialSize()
|
|
42570
|
-
local text=string.format("Event: Group %s crashed. Unit %s. Units still alive %d of %d.",SpawnGroup:GetName(),EventData.IniUnitName,
|
|
42571
|
-
self:T(
|
|
42846
|
+
local text=string.format("Event: Group %s crashed. Unit %s. Units still alive %d of %d.",SpawnGroup:GetName(),EventData.IniUnitName,ratcraft.nunits,_n0)
|
|
42847
|
+
self:T(self.lid..text)
|
|
42572
42848
|
local status=RAT.status.EventCrash
|
|
42573
42849
|
self:_SetStatus(SpawnGroup,status)
|
|
42574
|
-
if
|
|
42575
|
-
|
|
42576
|
-
self:
|
|
42577
|
-
local idx=self:GetSpawnIndexFromGroup(SpawnGroup)
|
|
42578
|
-
local coord=SpawnGroup:GetCoordinate()
|
|
42579
|
-
self:_Respawn(idx,coord)
|
|
42580
|
-
end
|
|
42850
|
+
if ratcraft.nunits==0 and self.respawn_after_crash and not self.norespawn then
|
|
42851
|
+
self:T(self.lid..string.format("No units left of group %s. Group will be respawned now.",SpawnGroup:GetName()))
|
|
42852
|
+
self:_Respawn(SpawnGroup)
|
|
42581
42853
|
end
|
|
42582
42854
|
else
|
|
42583
|
-
|
|
42584
|
-
self:E(RAT.id.."ERROR: Group does not exist in RAT:_OnCrash().")
|
|
42585
|
-
end
|
|
42586
|
-
end
|
|
42587
|
-
end
|
|
42588
|
-
function RAT:_Despawn(group,delay)
|
|
42589
|
-
if group~=nil then
|
|
42590
|
-
local index=self:GetSpawnIndexFromGroup(group)
|
|
42591
|
-
if index~=nil then
|
|
42592
|
-
self.ratcraft[index].group=nil
|
|
42593
|
-
self.ratcraft[index]["status"]="Dead"
|
|
42594
|
-
local despawndelay=0
|
|
42595
|
-
if delay then
|
|
42596
|
-
despawndelay=delay
|
|
42597
|
-
elseif self.respawn_delay then
|
|
42598
|
-
despawndelay=self.respawn_delay
|
|
42599
|
-
end
|
|
42600
|
-
self:T(RAT.id..string.format("%s delayed despawn in %.1f seconds.",self.alias,despawndelay))
|
|
42601
|
-
SCHEDULER:New(nil,self._Destroy,{self,group},despawndelay)
|
|
42602
|
-
if self.f10menu and self.SubMenuName~=nil then
|
|
42603
|
-
self.Menu[self.SubMenuName]["groups"][index]:Remove()
|
|
42604
|
-
end
|
|
42605
|
-
end
|
|
42606
|
-
end
|
|
42607
|
-
end
|
|
42608
|
-
function RAT:_Destroy(group)
|
|
42609
|
-
self:F2(group)
|
|
42610
|
-
local DCSGroup=group:GetDCSObject()
|
|
42611
|
-
if DCSGroup and DCSGroup:isExist()then
|
|
42612
|
-
local triggerdead=true
|
|
42613
|
-
for _,DCSUnit in pairs(DCSGroup:getUnits())do
|
|
42614
|
-
if DCSUnit then
|
|
42615
|
-
if triggerdead then
|
|
42616
|
-
self:_CreateEventDead(timer.getTime(),DCSUnit)
|
|
42617
|
-
triggerdead=false
|
|
42618
|
-
end
|
|
42619
|
-
_DATABASE:DeleteUnit(DCSUnit:getName())
|
|
42855
|
+
self:E(self.lid..string.format("ERROR: Could not find ratcraft object for crashed group %s!",SpawnGroup:GetName()))
|
|
42620
42856
|
end
|
|
42621
42857
|
end
|
|
42622
|
-
|
|
42623
|
-
|
|
42858
|
+
else
|
|
42859
|
+
if self.Debug then
|
|
42860
|
+
self:E(self.lid.."ERROR: Group does not exist in RAT:_OnCrash()!")
|
|
42624
42861
|
end
|
|
42625
|
-
return nil
|
|
42626
42862
|
end
|
|
42627
|
-
function RAT:_CreateEventDead(EventTime,Initiator)
|
|
42628
|
-
self:F({EventTime,Initiator})
|
|
42629
|
-
local Event={
|
|
42630
|
-
id=world.event.S_EVENT_DEAD,
|
|
42631
|
-
time=EventTime,
|
|
42632
|
-
initiator=Initiator,
|
|
42633
|
-
}
|
|
42634
|
-
world.onEvent(Event)
|
|
42635
42863
|
end
|
|
42636
42864
|
function RAT:_Waypoint(index,description,Type,Coord,Speed,Altitude,Airport)
|
|
42637
42865
|
local _Altitude=Altitude or Coord.y
|
|
@@ -42684,7 +42912,7 @@ _Type="Turning Point"
|
|
|
42684
42912
|
_Action="Turning Point"
|
|
42685
42913
|
_alttype="BARO"
|
|
42686
42914
|
else
|
|
42687
|
-
self:E(
|
|
42915
|
+
self:E(self.lid.."ERROR: Unknown waypoint type in RAT:Waypoint() function!")
|
|
42688
42916
|
_Type="Turning Point"
|
|
42689
42917
|
_Action="Turning Point"
|
|
42690
42918
|
_alttype="RADIO"
|
|
@@ -42709,7 +42937,7 @@ else
|
|
|
42709
42937
|
text=text..string.format("No airport/zone specified\n")
|
|
42710
42938
|
end
|
|
42711
42939
|
text=text.."******************************************************\n"
|
|
42712
|
-
self:T2(
|
|
42940
|
+
self:T2(self.lid..text)
|
|
42713
42941
|
local RoutePoint={}
|
|
42714
42942
|
RoutePoint.x=Coord.x
|
|
42715
42943
|
RoutePoint.y=Coord.z
|
|
@@ -42734,30 +42962,12 @@ RoutePoint.helipadId=AirbaseID
|
|
|
42734
42962
|
elseif AirbaseCategory==Airbase.Category.AIRDROME then
|
|
42735
42963
|
RoutePoint.airdromeId=AirbaseID
|
|
42736
42964
|
else
|
|
42737
|
-
self:T(
|
|
42738
|
-
end
|
|
42965
|
+
self:T(self.lid.."Unknown Airport category in _Waypoint()!")
|
|
42739
42966
|
end
|
|
42740
|
-
RoutePoint.properties={
|
|
42741
|
-
["vnav"]=1,
|
|
42742
|
-
["scale"]=0,
|
|
42743
|
-
["angle"]=0,
|
|
42744
|
-
["vangle"]=0,
|
|
42745
|
-
["steer"]=2,
|
|
42746
|
-
}
|
|
42747
|
-
local TaskCombo={}
|
|
42748
|
-
local TaskHolding=self:_TaskHolding({x=Coord.x,y=Coord.z},Altitude,Speed,self:_Randomize(90,0.9))
|
|
42749
|
-
local TaskWaypoint=self:_TaskFunction("RAT._WaypointFunction",self,index)
|
|
42750
|
-
RoutePoint.task={}
|
|
42751
|
-
RoutePoint.task.id="ComboTask"
|
|
42752
|
-
RoutePoint.task.params={}
|
|
42753
|
-
TaskCombo[#TaskCombo+1]=TaskWaypoint
|
|
42754
|
-
if Type==RAT.wp.holding then
|
|
42755
|
-
TaskCombo[#TaskCombo+1]=TaskHolding
|
|
42756
42967
|
end
|
|
42757
|
-
RoutePoint.task.params.tasks=TaskCombo
|
|
42758
42968
|
return RoutePoint
|
|
42759
42969
|
end
|
|
42760
|
-
function RAT:_Routeinfo(waypoints,comment)
|
|
42970
|
+
function RAT:_Routeinfo(waypoints,comment,waypointdescriptions)
|
|
42761
42971
|
local text=string.format("\n******************************************************\n")
|
|
42762
42972
|
text=text..string.format("Template = %s\n",self.SpawnTemplatePrefix)
|
|
42763
42973
|
if comment then
|
|
@@ -42766,7 +42976,7 @@ end
|
|
|
42766
42976
|
text=text..string.format("Number of waypoints = %i\n",#waypoints)
|
|
42767
42977
|
for i=1,#waypoints do
|
|
42768
42978
|
local p=waypoints[i]
|
|
42769
|
-
text=text..string.format("WP #%i: x = %6.1f km, y = %6.1f km, alt = %6.1f m %s\n",i-1,p.x/1000,p.y/1000,p.alt,
|
|
42979
|
+
text=text..string.format("WP #%i: x = %6.1f km, y = %6.1f km, alt = %6.1f m %s\n",i-1,p.x/1000,p.y/1000,p.alt,waypointdescriptions[i])
|
|
42770
42980
|
end
|
|
42771
42981
|
local total=0.0
|
|
42772
42982
|
for i=1,#waypoints-1 do
|
|
@@ -42779,115 +42989,27 @@ local y2=point2.y
|
|
|
42779
42989
|
local d=math.sqrt((x1-x2)^2+(y1-y2)^2)
|
|
42780
42990
|
local heading=self:_Course(point1,point2)
|
|
42781
42991
|
total=total+d
|
|
42782
|
-
text=text..string.format("Distance from WP %i-->%i = %6.1f km. Heading = %03d : %s - %s\n",i-1,i,d/1000,heading,
|
|
42992
|
+
text=text..string.format("Distance from WP %i-->%i = %6.1f km. Heading = %03d : %s - %s\n",i-1,i,d/1000,heading,waypointdescriptions[i],waypointdescriptions[i+1])
|
|
42783
42993
|
end
|
|
42784
42994
|
text=text..string.format("Total distance = %6.1f km\n",total/1000)
|
|
42785
42995
|
text=text..string.format("******************************************************\n")
|
|
42786
|
-
self:T2(
|
|
42996
|
+
self:T2(self.lid..text)
|
|
42787
42997
|
return total
|
|
42788
42998
|
end
|
|
42789
|
-
function RAT:_TaskHolding(P1,Altitude,Speed,Duration)
|
|
42790
|
-
local dx=3000
|
|
42791
|
-
local dy=0
|
|
42792
|
-
if self.category==RAT.cat.heli then
|
|
42793
|
-
dx=200
|
|
42794
|
-
dy=0
|
|
42795
|
-
end
|
|
42796
|
-
local P2={}
|
|
42797
|
-
P2.x=P1.x+dx
|
|
42798
|
-
P2.y=P1.y+dy
|
|
42799
|
-
local Task={
|
|
42800
|
-
id='Orbit',
|
|
42801
|
-
params={
|
|
42802
|
-
pattern=AI.Task.OrbitPattern.RACE_TRACK,
|
|
42803
|
-
point=P1,
|
|
42804
|
-
point2=P2,
|
|
42805
|
-
speed=Speed,
|
|
42806
|
-
altitude=Altitude
|
|
42807
|
-
}
|
|
42808
|
-
}
|
|
42809
|
-
local DCSTask={}
|
|
42810
|
-
DCSTask.id="ControlledTask"
|
|
42811
|
-
DCSTask.params={}
|
|
42812
|
-
DCSTask.params.task=Task
|
|
42813
|
-
if self.ATCswitch then
|
|
42814
|
-
local userflagname=string.format("%s#%03d",self.alias,self.SpawnIndex+1)
|
|
42815
|
-
local maxholdingduration=60*120
|
|
42816
|
-
DCSTask.params.stopCondition={userFlag=userflagname,userFlagValue=1,duration=maxholdingduration}
|
|
42817
|
-
else
|
|
42818
|
-
DCSTask.params.stopCondition={duration=Duration}
|
|
42819
|
-
end
|
|
42820
|
-
return DCSTask
|
|
42821
|
-
end
|
|
42822
|
-
function RAT._WaypointFunction(group,rat,wp)
|
|
42823
|
-
local Tnow=timer.getTime()
|
|
42824
|
-
local sdx=rat:GetSpawnIndexFromGroup(group)
|
|
42825
|
-
local departure=rat.ratcraft[sdx].departure:GetName()
|
|
42826
|
-
local destination=rat.ratcraft[sdx].destination:GetName()
|
|
42827
|
-
local landing=rat.ratcraft[sdx].landing
|
|
42828
|
-
local WPholding=rat.ratcraft[sdx].wpholding
|
|
42829
|
-
local WPfinal=rat.ratcraft[sdx].wpfinal
|
|
42830
|
-
local text
|
|
42831
|
-
text=string.format("Flight %s passing waypoint #%d %s.",group:GetName(),wp,rat.waypointdescriptions[wp])
|
|
42832
|
-
BASE.T(rat,RAT.id..text)
|
|
42833
|
-
local status=rat.waypointstatus[wp]
|
|
42834
|
-
rat:_SetStatus(group,status)
|
|
42835
|
-
if wp==WPholding then
|
|
42836
|
-
text=string.format("Flight %s to %s ATC: Holding and awaiting landing clearance.",group:GetName(),destination)
|
|
42837
|
-
MESSAGE:New(text,10):ToAllIf(rat.reportstatus)
|
|
42838
|
-
if rat.ATCswitch then
|
|
42839
|
-
if rat.f10menu then
|
|
42840
|
-
MENU_MISSION_COMMAND:New("Clear for landing",rat.Menu[rat.SubMenuName].groups[sdx],rat.ClearForLanding,rat,group:GetName())
|
|
42841
|
-
end
|
|
42842
|
-
rat._ATCRegisterFlight(rat,group:GetName(),Tnow)
|
|
42843
|
-
end
|
|
42844
|
-
end
|
|
42845
|
-
if wp==WPfinal then
|
|
42846
|
-
text=string.format("Flight %s arrived at final destination %s.",group:GetName(),destination)
|
|
42847
|
-
MESSAGE:New(text,10):ToAllIf(rat.reportstatus)
|
|
42848
|
-
BASE.T(rat,RAT.id..text)
|
|
42849
|
-
if landing==RAT.wp.air then
|
|
42850
|
-
text=string.format("Activating despawn switch for flight %s! Group will be detroyed soon.",group:GetName())
|
|
42851
|
-
MESSAGE:New(text,10):ToAllIf(rat.Debug)
|
|
42852
|
-
BASE.T(rat,RAT.id..text)
|
|
42853
|
-
rat.ratcraft[sdx].despawnme=true
|
|
42854
|
-
end
|
|
42855
|
-
end
|
|
42856
|
-
end
|
|
42857
|
-
function RAT:_TaskFunction(FunctionString,...)
|
|
42858
|
-
self:F2({FunctionString,arg})
|
|
42859
|
-
local DCSTask
|
|
42860
|
-
local ArgumentKey
|
|
42861
|
-
local templatename=self.templategroup:GetName()
|
|
42862
|
-
local groupname=self:_AnticipatedGroupName()
|
|
42863
|
-
local DCSScript={}
|
|
42864
|
-
DCSScript[#DCSScript+1]="local MissionControllable = GROUP:FindByName(\""..groupname.."\") "
|
|
42865
|
-
DCSScript[#DCSScript+1]="local RATtemplateControllable = GROUP:FindByName(\""..templatename.."\") "
|
|
42866
|
-
if arg and arg.n>0 then
|
|
42867
|
-
ArgumentKey='_'..tostring(arg):match("table: (.*)")
|
|
42868
|
-
self.templategroup:SetState(self.templategroup,ArgumentKey,arg)
|
|
42869
|
-
DCSScript[#DCSScript+1]="local Arguments = RATtemplateControllable:GetState(RATtemplateControllable, '"..ArgumentKey.."' ) "
|
|
42870
|
-
DCSScript[#DCSScript+1]=FunctionString.."( MissionControllable, unpack( Arguments ) )"
|
|
42871
|
-
else
|
|
42872
|
-
DCSScript[#DCSScript+1]=FunctionString.."( MissionControllable )"
|
|
42873
|
-
end
|
|
42874
|
-
DCSTask=self.templategroup:TaskWrappedAction(self.templategroup:CommandDoScript(table.concat(DCSScript)))
|
|
42875
|
-
return DCSTask
|
|
42876
|
-
end
|
|
42877
42999
|
function RAT:_AnticipatedGroupName(index)
|
|
42878
43000
|
local index=index or self.SpawnIndex+1
|
|
42879
43001
|
return string.format("%s#%03d",self.alias,index)
|
|
42880
43002
|
end
|
|
42881
43003
|
function RAT:_ActivateUncontrolled()
|
|
42882
|
-
self:F()
|
|
42883
43004
|
local idx={}
|
|
42884
43005
|
local rat={}
|
|
42885
43006
|
local nactive=0
|
|
42886
|
-
for spawnindex,
|
|
43007
|
+
for spawnindex,_ratcraft in pairs(self.ratcraft)do
|
|
43008
|
+
local ratcraft=_ratcraft
|
|
42887
43009
|
local group=ratcraft.group
|
|
42888
43010
|
if group and group:IsAlive()then
|
|
42889
|
-
local text=string.format("Uncontrolled: Group = %s (spawnindex = %d), active = %s
|
|
42890
|
-
self:T2(
|
|
43011
|
+
local text=string.format("Uncontrolled: Group = %s (spawnindex = %d), active = %s",ratcraft.group:GetName(),spawnindex,tostring(ratcraft.active))
|
|
43012
|
+
self:T2(self.lid..text)
|
|
42891
43013
|
if ratcraft.active then
|
|
42892
43014
|
nactive=nactive+1
|
|
42893
43015
|
else
|
|
@@ -42895,24 +43017,28 @@ table.insert(idx,spawnindex)
|
|
|
42895
43017
|
end
|
|
42896
43018
|
end
|
|
42897
43019
|
end
|
|
42898
|
-
local text=string.format("Uncontrolled: Ninactive = %d, Nactive = %d (of max %d)
|
|
42899
|
-
self:T(
|
|
43020
|
+
local text=string.format("Uncontrolled: Ninactive = %d, Nactive = %d (of max %d)",#idx,nactive,self.activate_max)
|
|
43021
|
+
self:T(self.lid..text)
|
|
42900
43022
|
if#idx>0 and nactive<self.activate_max then
|
|
42901
43023
|
local index=idx[math.random(#idx)]
|
|
42902
|
-
local
|
|
42903
|
-
|
|
43024
|
+
local ratcraft=self.ratcraft[index]
|
|
43025
|
+
local group=ratcraft.group
|
|
43026
|
+
local departureAirbase=self:_GetDepartureAirbase(ratcraft)
|
|
43027
|
+
local departureFlightControl=nil
|
|
43028
|
+
if departureAirbase then
|
|
43029
|
+
departureFlightControl=_DATABASE:GetFlightControl(departureAirbase:GetName())
|
|
42904
43030
|
end
|
|
43031
|
+
if departureFlightControl then
|
|
43032
|
+
self:T(self.lid..string.format("RAT group %s is ready for takeoff",group:GetName()))
|
|
43033
|
+
ratcraft.flightgroup:SetReadyForTakeoff(true)
|
|
43034
|
+
else
|
|
43035
|
+
self:T(self.lid..string.format("RAT group %s is switching to controlled now",group:GetName()))
|
|
43036
|
+
ratcraft.flightgroup:StartUncontrolled()
|
|
42905
43037
|
end
|
|
42906
|
-
|
|
42907
|
-
self:F(group)
|
|
42908
|
-
local StartCommand={id='Start',params={}}
|
|
42909
|
-
local text=string.format("Uncontrolled: Activating group %s.",group:GetName())
|
|
42910
|
-
self:T(RAT.id..text)
|
|
42911
|
-
group:SetCommand(StartCommand)
|
|
42912
|
-
local index=self:GetSpawnIndexFromGroup(group)
|
|
42913
|
-
self.ratcraft[index].active=true
|
|
43038
|
+
ratcraft.active=true
|
|
42914
43039
|
self:_SetStatus(group,RAT.status.EventBirth)
|
|
42915
43040
|
end
|
|
43041
|
+
end
|
|
42916
43042
|
function RAT:_CommandInvisible(group,switch)
|
|
42917
43043
|
local SetInvisible={id='SetInvisible',params={value=switch}}
|
|
42918
43044
|
group:SetCommand(SetInvisible)
|
|
@@ -42949,7 +43075,7 @@ if DCSuniti and DCSuniti:isExist()and DCSunitj and DCSunitj:isExist()then
|
|
|
42949
43075
|
local _dist=uniti:GetCoordinate():Get3DDistance(unitj:GetCoordinate())
|
|
42950
43076
|
if _dist<distmin then
|
|
42951
43077
|
if(not uniti:InAir())and(not unitj:InAir())then
|
|
42952
|
-
self:T(
|
|
43078
|
+
self:T(self.lid..string.format("Unit %s is on top of unit %s. Distance %.2f m.",namei,namej,_dist))
|
|
42953
43079
|
return true
|
|
42954
43080
|
end
|
|
42955
43081
|
end
|
|
@@ -42981,6 +43107,21 @@ end
|
|
|
42981
43107
|
end
|
|
42982
43108
|
return false
|
|
42983
43109
|
end
|
|
43110
|
+
function RAT:_GetDestinationAirbase(ratcraft)
|
|
43111
|
+
if ratcraft and ratcraft.destination then
|
|
43112
|
+
local airbase=AIRBASE:FindByName(ratcraft.destination)
|
|
43113
|
+
return airbase
|
|
43114
|
+
end
|
|
43115
|
+
return nil
|
|
43116
|
+
end
|
|
43117
|
+
function RAT:_GetDepartureAirbase(ratcraft)
|
|
43118
|
+
if ratcraft and ratcraft.departure then
|
|
43119
|
+
local name=ratcraft.departure:GetName()
|
|
43120
|
+
local airbase=AIRBASE:FindByName(name)
|
|
43121
|
+
return airbase
|
|
43122
|
+
end
|
|
43123
|
+
return nil
|
|
43124
|
+
end
|
|
42984
43125
|
function RAT:_AirportExists(name)
|
|
42985
43126
|
for _,airport in pairs(self.airports_map)do
|
|
42986
43127
|
if airport:GetName()==name then
|
|
@@ -42996,25 +43137,31 @@ return true
|
|
|
42996
43137
|
end
|
|
42997
43138
|
return false
|
|
42998
43139
|
end
|
|
42999
|
-
function RAT:_SetROE(
|
|
43000
|
-
self
|
|
43001
|
-
|
|
43002
|
-
|
|
43003
|
-
|
|
43004
|
-
|
|
43140
|
+
function RAT:_SetROE(flightgroup,roe)
|
|
43141
|
+
roe=roe or self.roe
|
|
43142
|
+
self:T(self.lid.."Setting ROE to "..roe.." for group "..flightgroup:GetName())
|
|
43143
|
+
local _roe=ENUMS.ROE.WeaponHold
|
|
43144
|
+
if roe==RAT.ROE.returnfire then
|
|
43145
|
+
_roe=ENUMS.ROE.ReturnFire
|
|
43146
|
+
elseif roe==RAT.ROE.weaponfree then
|
|
43147
|
+
_roe=ENUMS.ROE.OpenFireWeaponFree
|
|
43005
43148
|
else
|
|
43006
|
-
group:OptionROEHoldFire()
|
|
43007
43149
|
end
|
|
43150
|
+
flightgroup:SetDefaultROE(_roe)
|
|
43151
|
+
flightgroup:SwitchROE(_roe)
|
|
43008
43152
|
end
|
|
43009
|
-
function RAT:_SetROT(
|
|
43010
|
-
self
|
|
43011
|
-
|
|
43012
|
-
|
|
43013
|
-
|
|
43014
|
-
|
|
43153
|
+
function RAT:_SetROT(flightgroup,rot)
|
|
43154
|
+
rot=rot or self.rot
|
|
43155
|
+
self:T(self.lid.."Setting ROT to "..rot.." for group "..flightgroup:GetName())
|
|
43156
|
+
local _rot=ENUMS.ROT.NoReaction
|
|
43157
|
+
if rot==RAT.ROT.passive then
|
|
43158
|
+
_rot=ENUMS.ROT.PassiveDefense
|
|
43159
|
+
elseif rot==RAT.ROT.evade then
|
|
43160
|
+
_rot=ENUMS.ROT.EvadeFire
|
|
43015
43161
|
else
|
|
43016
|
-
group:OptionROTNoReaction()
|
|
43017
43162
|
end
|
|
43163
|
+
flightgroup:SetDefaultROT(_rot)
|
|
43164
|
+
flightgroup:SwitchROT(_rot)
|
|
43018
43165
|
end
|
|
43019
43166
|
function RAT:_SetCoalitionTable()
|
|
43020
43167
|
if self.friendly==RAT.coal.neutral then
|
|
@@ -43024,7 +43171,7 @@ self.ctable={self.coalition,coalition.side.NEUTRAL}
|
|
|
43024
43171
|
elseif self.friendly==RAT.coal.sameonly then
|
|
43025
43172
|
self.ctable={self.coalition}
|
|
43026
43173
|
else
|
|
43027
|
-
self:E(
|
|
43174
|
+
self:E(self.lid.."ERROR: Unknown friendly coalition in _SetCoalitionTable(). Defaulting to NEUTRAL.")
|
|
43028
43175
|
self.ctable={self.coalition,coalition.side.NEUTRAL}
|
|
43029
43176
|
end
|
|
43030
43177
|
end
|
|
@@ -43074,16 +43221,16 @@ end
|
|
|
43074
43221
|
local r=math.random(min,max)
|
|
43075
43222
|
if self.Debug then
|
|
43076
43223
|
local text=string.format("Random: value = %6.2f, fac = %4.2f, min = %6.2f, max = %6.2f, r = %6.2f",value,fac,min,max,r)
|
|
43077
|
-
self:T3(
|
|
43224
|
+
self:T3(self.lid..text)
|
|
43078
43225
|
end
|
|
43079
43226
|
return r
|
|
43080
43227
|
end
|
|
43081
|
-
function RAT:_PlaceMarkers(waypoints,index)
|
|
43228
|
+
function RAT:_PlaceMarkers(waypoints,waypointdescriptions,index)
|
|
43082
43229
|
for i=1,#waypoints do
|
|
43083
|
-
self:_SetMarker(
|
|
43230
|
+
self:_SetMarker(waypointdescriptions[i],waypoints[i],index)
|
|
43084
43231
|
if self.Debug then
|
|
43085
|
-
local text=string.format("Marker at waypoint #%d: %s for flight #%d",i,
|
|
43086
|
-
self:T2(
|
|
43232
|
+
local text=string.format("Marker at waypoint #%d: %s for flight #%d",i,waypointdescriptions[i],index)
|
|
43233
|
+
self:T2(self.lid..text)
|
|
43087
43234
|
end
|
|
43088
43235
|
end
|
|
43089
43236
|
end
|
|
@@ -43092,7 +43239,7 @@ RAT.markerid=RAT.markerid+1
|
|
|
43092
43239
|
self.markerids[#self.markerids+1]=RAT.markerid
|
|
43093
43240
|
if self.Debug then
|
|
43094
43241
|
local text2=string.format("%s: placing marker with ID %d and text %s",self.alias,RAT.markerid,text)
|
|
43095
|
-
self:T2(
|
|
43242
|
+
self:T2(self.lid..text2)
|
|
43096
43243
|
end
|
|
43097
43244
|
local vec={x=wp.x,y=wp.alt,z=wp.y}
|
|
43098
43245
|
local flight=self:GetGroupFromIndex(index):GetName()
|
|
@@ -43107,7 +43254,7 @@ for k,v in ipairs(self.markerids)do
|
|
|
43107
43254
|
self.markerids[k]=nil
|
|
43108
43255
|
end
|
|
43109
43256
|
end
|
|
43110
|
-
function RAT:_ModifySpawnTemplate(waypoints,livery,spawnplace,departure,takeoff,parkingdata)
|
|
43257
|
+
function RAT:_ModifySpawnTemplate(waypoints,livery,spawnplace,departure,takeoff,parkingdata,uncontrolled)
|
|
43111
43258
|
self:F2({waypoints=waypoints,livery=livery,spawnplace=spawnplace,departure=departure,takeoff=takeoff,parking=parkingdata})
|
|
43112
43259
|
local PointVec3=COORDINATE:New(waypoints[1].x,waypoints[1].alt,waypoints[1].y)
|
|
43113
43260
|
if spawnplace then
|
|
@@ -43141,8 +43288,7 @@ if self:_GetSpawnIndex(self.SpawnIndex+1)then
|
|
|
43141
43288
|
local SpawnTemplate=self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
|
43142
43289
|
if SpawnTemplate then
|
|
43143
43290
|
self:T(SpawnTemplate)
|
|
43144
|
-
if self.uncontrolled then
|
|
43145
|
-
self.SpawnUnControlled=true
|
|
43291
|
+
if self.uncontrolled or uncontrolled then
|
|
43146
43292
|
SpawnTemplate.uncontrolled=true
|
|
43147
43293
|
end
|
|
43148
43294
|
local nunits=#SpawnTemplate.units
|
|
@@ -43161,25 +43307,27 @@ local scanstatics=true
|
|
|
43161
43307
|
local scanscenery=self.parkingscanscenery
|
|
43162
43308
|
local verysafe=self.parkingverysafe
|
|
43163
43309
|
if spawnonship or spawnonfarp or spawnonrunway then
|
|
43164
|
-
self:T(
|
|
43310
|
+
self:T(self.lid..string.format("Group %s is spawned on farp/ship/runway %s.",self.alias,departure:GetName()))
|
|
43165
43311
|
nfree=departure:GetFreeParkingSpotsNumber(termtype,true)
|
|
43166
43312
|
spots=departure:GetFreeParkingSpotsTable(termtype,true)
|
|
43313
|
+
self:T(self.lid..string.format("Free nfree=%d nspots=%d",nfree,#spots))
|
|
43167
43314
|
elseif parkingdata~=nil then
|
|
43315
|
+
self:T2("Spawning with explicit parking data")
|
|
43168
43316
|
nfree=#parkingdata
|
|
43169
43317
|
spots=parkingdata
|
|
43170
43318
|
else
|
|
43171
43319
|
if self.category==RAT.cat.heli then
|
|
43172
43320
|
if termtype==nil then
|
|
43173
|
-
self:T(
|
|
43321
|
+
self:T(self.lid..string.format("Helo group %s is spawned at %s using terminal type %d.",self.alias,departure:GetName(),AIRBASE.TerminalType.HelicopterOnly))
|
|
43174
43322
|
spots=departure:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.HelicopterOnly,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits)
|
|
43175
43323
|
nfree=#spots
|
|
43176
43324
|
if nfree<nunits then
|
|
43177
|
-
self:T(
|
|
43325
|
+
self:T(self.lid..string.format("Helo group %s is spawned at %s using terminal type %d.",self.alias,departure:GetName(),AIRBASE.TerminalType.HelicopterUsable))
|
|
43178
43326
|
spots=departure:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.HelicopterUsable,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits)
|
|
43179
43327
|
nfree=#spots
|
|
43180
43328
|
end
|
|
43181
43329
|
else
|
|
43182
|
-
self:T(
|
|
43330
|
+
self:T(self.lid..string.format("Helo group %s is at %s using terminal type %d.",self.alias,departure:GetName(),termtype))
|
|
43183
43331
|
spots=departure:FindFreeParkingSpotForAircraft(TemplateGroup,termtype,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits)
|
|
43184
43332
|
nfree=#spots
|
|
43185
43333
|
end
|
|
@@ -43188,33 +43336,35 @@ if termtype==nil then
|
|
|
43188
43336
|
local bomber=TemplateUnit:HasAttribute("Bombers")
|
|
43189
43337
|
local transport=TemplateUnit:HasAttribute("Transports")
|
|
43190
43338
|
if bomber or transport then
|
|
43191
|
-
self:T(
|
|
43339
|
+
self:T(self.lid..string.format("Transport/bomber group %s is spawned at %s using terminal type %d.",self.alias,departure:GetName(),AIRBASE.TerminalType.OpenBig))
|
|
43192
43340
|
spots=departure:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.OpenBig,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits)
|
|
43193
43341
|
nfree=#spots
|
|
43194
43342
|
if nfree<nunits then
|
|
43195
|
-
self:T(
|
|
43343
|
+
self:T(self.lid..string.format("Transport/bomber group %s is at %s using terminal type %d.",self.alias,departure:GetName(),AIRBASE.TerminalType.OpenMed))
|
|
43196
43344
|
spots=departure:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.OpenMed,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits)
|
|
43197
43345
|
nfree=#spots
|
|
43198
43346
|
end
|
|
43199
43347
|
else
|
|
43200
|
-
self:T(
|
|
43348
|
+
self:T(self.lid..string.format("Fighter group %s is spawned at %s using terminal type %d.",self.alias,departure:GetName(),AIRBASE.TerminalType.FighterAircraft))
|
|
43201
43349
|
spots=departure:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.FighterAircraft,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits)
|
|
43202
43350
|
nfree=#spots
|
|
43203
43351
|
end
|
|
43204
43352
|
else
|
|
43205
|
-
self:T(
|
|
43353
|
+
self:T(self.lid..string.format("Plane group %s is spawned at %s using terminal type %d.",self.alias,departure:GetName(),termtype))
|
|
43206
43354
|
spots=departure:FindFreeParkingSpotForAircraft(TemplateGroup,termtype,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits)
|
|
43207
43355
|
nfree=#spots
|
|
43208
43356
|
end
|
|
43209
43357
|
end
|
|
43210
43358
|
end
|
|
43359
|
+
if false then
|
|
43211
43360
|
local parkingdata=departure:GetParkingSpotsTable(termtype)
|
|
43212
|
-
self:T2(
|
|
43361
|
+
self:T2(self.lid..string.format("Parking at %s, terminal type %s:",departure:GetName(),tostring(termtype)))
|
|
43213
43362
|
for _,_spot in pairs(parkingdata)do
|
|
43214
|
-
self:T2(
|
|
43363
|
+
self:T2(self.lid..string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
|
43215
43364
|
departure:GetName(),_spot.TerminalID,_spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
|
43216
43365
|
end
|
|
43217
|
-
self:T(
|
|
43366
|
+
self:T(self.lid..string.format("%s at %s: free parking spots = %d - number of units = %d",self.alias,departure:GetName(),nfree,nunits))
|
|
43367
|
+
end
|
|
43218
43368
|
local _notenough=false
|
|
43219
43369
|
if spawnonship or spawnonfarp or spawnonrunway then
|
|
43220
43370
|
if nfree>=1 then
|
|
@@ -43238,7 +43388,7 @@ end
|
|
|
43238
43388
|
end
|
|
43239
43389
|
if _notenough then
|
|
43240
43390
|
if self.respawn_inair and not self.SpawnUnControlled then
|
|
43241
|
-
self:E(
|
|
43391
|
+
self:E(self.lid..string.format("WARNING: Group %s has no parking spots at %s ==> air start!",self.SpawnTemplatePrefix,departure:GetName()))
|
|
43242
43392
|
spawnonground=false
|
|
43243
43393
|
spawnonship=false
|
|
43244
43394
|
spawnonfarp=false
|
|
@@ -43253,7 +43403,7 @@ else
|
|
|
43253
43403
|
PointVec3.y=PointVec3:GetLandHeight()+math.random(500,3000)
|
|
43254
43404
|
end
|
|
43255
43405
|
else
|
|
43256
|
-
self:E(
|
|
43406
|
+
self:E(self.lid..string.format("WARNING: Group %s has no parking spots at %s ==> No emergency air start or uncontrolled spawning ==> No spawn!",self.SpawnTemplatePrefix,departure:GetName()))
|
|
43257
43407
|
return nil
|
|
43258
43408
|
end
|
|
43259
43409
|
end
|
|
@@ -43269,18 +43419,18 @@ local TX=PointVec3.x+(SX-BX)
|
|
|
43269
43419
|
local TY=PointVec3.z+(SY-BY)
|
|
43270
43420
|
if spawnonground then
|
|
43271
43421
|
if spawnonship or spawnonfarp or spawnonrunway or automatic then
|
|
43272
|
-
self:T(
|
|
43422
|
+
self:T(self.lid..string.format("RAT group %s spawning at farp, ship or runway %s.",self.alias,departure:GetName()))
|
|
43273
43423
|
SpawnTemplate.units[UnitID].x=PointVec3.x
|
|
43274
43424
|
SpawnTemplate.units[UnitID].y=PointVec3.z
|
|
43275
43425
|
SpawnTemplate.units[UnitID].alt=PointVec3.y
|
|
43276
43426
|
else
|
|
43277
|
-
self:T(
|
|
43427
|
+
self:T(self.lid..string.format("RAT group %s spawning at airbase %s on parking spot id %d",self.alias,departure:GetName(),parkingindex[UnitID]))
|
|
43278
43428
|
SpawnTemplate.units[UnitID].x=parkingspots[UnitID].x
|
|
43279
43429
|
SpawnTemplate.units[UnitID].y=parkingspots[UnitID].z
|
|
43280
43430
|
SpawnTemplate.units[UnitID].alt=parkingspots[UnitID].y
|
|
43281
43431
|
end
|
|
43282
43432
|
else
|
|
43283
|
-
self:T(
|
|
43433
|
+
self:T(self.lid..string.format("RAT group %s spawning in air at %s.",self.alias,departure:GetName()))
|
|
43284
43434
|
SpawnTemplate.units[UnitID].x=TX
|
|
43285
43435
|
SpawnTemplate.units[UnitID].y=TY
|
|
43286
43436
|
SpawnTemplate.units[UnitID].alt=PointVec3.y
|
|
@@ -43294,8 +43444,8 @@ UnitTemplate.parking_id=nil
|
|
|
43294
43444
|
if parkingindex[UnitID]and not automatic then
|
|
43295
43445
|
UnitTemplate.parking=parkingindex[UnitID]
|
|
43296
43446
|
end
|
|
43297
|
-
self:T2(
|
|
43298
|
-
self:T2(
|
|
43447
|
+
self:T2(self.lid..string.format("RAT group %s unit number %d: Parking = %s",self.alias,UnitID,tostring(UnitTemplate.parking)))
|
|
43448
|
+
self:T2(self.lid..string.format("RAT group %s unit number %d: Parking ID = %s",self.alias,UnitID,tostring(UnitTemplate.parking_id)))
|
|
43299
43449
|
SpawnTemplate.units[UnitID].heading=heading
|
|
43300
43450
|
SpawnTemplate.units[UnitID].psi=-heading
|
|
43301
43451
|
if livery then
|
|
@@ -43332,149 +43482,167 @@ end
|
|
|
43332
43482
|
end
|
|
43333
43483
|
return true
|
|
43334
43484
|
end
|
|
43335
|
-
function RAT
|
|
43485
|
+
function RAT._ATCInit(airports_map)
|
|
43336
43486
|
if not RAT.ATC.init then
|
|
43337
|
-
local text
|
|
43338
|
-
|
|
43339
|
-
BASE:T(RAT.id..text)
|
|
43340
|
-
RAT.ATC.init=true
|
|
43487
|
+
local text="Starting RAT ATC.\nSimultanious = "..RAT.ATC.Nclearance.."\n".."Delay = "..RAT.ATC.delay
|
|
43488
|
+
BASE:I(RAT.id..text)
|
|
43341
43489
|
for _,ap in pairs(airports_map)do
|
|
43342
|
-
local
|
|
43343
|
-
|
|
43344
|
-
|
|
43345
|
-
|
|
43346
|
-
|
|
43347
|
-
|
|
43348
|
-
|
|
43349
|
-
|
|
43350
|
-
|
|
43351
|
-
|
|
43352
|
-
|
|
43490
|
+
local airbase=ap
|
|
43491
|
+
local name=airbase:GetName()
|
|
43492
|
+
local fc=_DATABASE:GetFlightControl(name)
|
|
43493
|
+
if not fc then
|
|
43494
|
+
local airport={}
|
|
43495
|
+
airport.queue={}
|
|
43496
|
+
airport.busy=false
|
|
43497
|
+
airport.onfinal={}
|
|
43498
|
+
airport.Nonfinal=0
|
|
43499
|
+
airport.traffic=0
|
|
43500
|
+
airport.Tlastclearance=nil
|
|
43501
|
+
RAT.ATC.airport[name]=airport
|
|
43502
|
+
end
|
|
43503
|
+
end
|
|
43504
|
+
SCHEDULER:New(nil,RAT._ATCCheck,{},5,15)
|
|
43505
|
+
SCHEDULER:New(nil,RAT._ATCStatus,{},5,60)
|
|
43353
43506
|
RAT.ATC.T0=timer.getTime()
|
|
43354
43507
|
end
|
|
43508
|
+
RAT.ATC.init=true
|
|
43355
43509
|
end
|
|
43356
43510
|
function RAT:_ATCAddFlight(name,dest)
|
|
43357
|
-
BASE:
|
|
43358
|
-
|
|
43359
|
-
|
|
43360
|
-
|
|
43361
|
-
|
|
43362
|
-
|
|
43363
|
-
|
|
43364
|
-
|
|
43511
|
+
BASE:I(RAT.id..string.format("ATC %s: Adding flight %s with destination %s.",dest,name,dest))
|
|
43512
|
+
local flight={}
|
|
43513
|
+
flight.destination=dest
|
|
43514
|
+
flight.Tarrive=-1
|
|
43515
|
+
flight.holding=-1
|
|
43516
|
+
flight.Tarrive=-1
|
|
43517
|
+
RAT.ATC.flight[name]=flight
|
|
43518
|
+
end
|
|
43519
|
+
function RAT._ATCDelFlight(t,entry)
|
|
43365
43520
|
for k,_ in pairs(t)do
|
|
43366
43521
|
if k==entry then
|
|
43522
|
+
BASE:I(RAT.id..string.format("Removing flight %s from queue",entry))
|
|
43367
43523
|
t[entry]=nil
|
|
43368
43524
|
end
|
|
43369
43525
|
end
|
|
43370
43526
|
end
|
|
43371
|
-
function RAT
|
|
43372
|
-
BASE:
|
|
43527
|
+
function RAT._ATCRegisterFlight(name,time)
|
|
43528
|
+
BASE:I(RAT.id..string.format("Flight %s registered at ATC for landing clearance.",name))
|
|
43373
43529
|
RAT.ATC.flight[name].Tarrive=time
|
|
43374
43530
|
RAT.ATC.flight[name].holding=0
|
|
43375
43531
|
end
|
|
43376
|
-
function RAT
|
|
43532
|
+
function RAT._ATCStatus()
|
|
43377
43533
|
local Tnow=timer.getTime()
|
|
43378
|
-
for name,
|
|
43534
|
+
for name,_flight in pairs(RAT.ATC.flight)do
|
|
43535
|
+
local flight=_flight
|
|
43379
43536
|
local hold=RAT.ATC.flight[name].holding
|
|
43380
43537
|
local dest=RAT.ATC.flight[name].destination
|
|
43538
|
+
local airport=RAT.ATC.airport[dest]
|
|
43539
|
+
if airport then
|
|
43381
43540
|
if hold>=0 then
|
|
43382
43541
|
local busy="Runway state is unknown"
|
|
43383
|
-
if
|
|
43384
|
-
busy="Runway is occupied by "..
|
|
43542
|
+
if airport.Nonfinal>0 then
|
|
43543
|
+
busy="Runway is occupied by "..airport.Nonfinal
|
|
43385
43544
|
else
|
|
43386
43545
|
busy="Runway is currently clear"
|
|
43387
43546
|
end
|
|
43388
43547
|
local text=string.format("ATC %s: Flight %s is holding for %i:%02d. %s.",dest,name,hold/60,hold%60,busy)
|
|
43389
|
-
BASE:
|
|
43548
|
+
BASE:I(RAT.id..text)
|
|
43390
43549
|
elseif hold==RAT.ATC.onfinal then
|
|
43391
|
-
local Tfinal=Tnow-
|
|
43550
|
+
local Tfinal=Tnow-flight.Tonfinal
|
|
43392
43551
|
local text=string.format("ATC %s: Flight %s is on final. Waiting %i:%02d for landing event.",dest,name,Tfinal/60,Tfinal%60)
|
|
43393
|
-
BASE:
|
|
43552
|
+
BASE:I(RAT.id..text)
|
|
43394
43553
|
elseif hold==RAT.ATC.unregistered then
|
|
43395
43554
|
else
|
|
43396
43555
|
BASE:E(RAT.id.."ERROR: Unknown holding time in RAT:_ATCStatus().")
|
|
43397
43556
|
end
|
|
43557
|
+
else
|
|
43398
43558
|
end
|
|
43399
43559
|
end
|
|
43400
|
-
function RAT:_ATCCheck()
|
|
43401
|
-
RAT:_ATCQueue()
|
|
43402
|
-
local Tnow=timer.getTime()
|
|
43403
|
-
for name,_ in pairs(RAT.ATC.airport)do
|
|
43404
|
-
for qID,flight in ipairs(RAT.ATC.airport[name].queue)do
|
|
43405
|
-
local nqueue=#RAT.ATC.airport[name].queue
|
|
43406
|
-
local landing1
|
|
43407
|
-
if RAT.ATC.airport[name].Tlastclearance then
|
|
43408
|
-
landing1=(Tnow-RAT.ATC.airport[name].Tlastclearance>RAT.ATC.delay)and RAT.ATC.airport[name].Nonfinal<RAT.ATC.Nclearance
|
|
43409
|
-
else
|
|
43410
|
-
landing1=false
|
|
43411
43560
|
end
|
|
43412
|
-
|
|
43561
|
+
function RAT._ATCCheck()
|
|
43562
|
+
RAT._ATCQueue()
|
|
43563
|
+
local Tnow=timer.getTime()
|
|
43564
|
+
for airportname,_airport in pairs(RAT.ATC.airport)do
|
|
43565
|
+
local airport=_airport
|
|
43566
|
+
for qID,flightname in pairs(airport.queue)do
|
|
43567
|
+
local flight=RAT.ATC.flight[flightname]
|
|
43568
|
+
local nqueue=#airport.queue
|
|
43569
|
+
local landing1=false
|
|
43570
|
+
if airport.Tlastclearance then
|
|
43571
|
+
landing1=(Tnow-airport.Tlastclearance>RAT.ATC.delay)and airport.Nonfinal<RAT.ATC.Nclearance
|
|
43572
|
+
end
|
|
43573
|
+
local landing2=airport.Nonfinal==0
|
|
43413
43574
|
if not landing1 and not landing2 then
|
|
43414
|
-
|
|
43415
|
-
local text=string.format("ATC %s: Flight %s runway is busy. You are #%d of %d in landing queue. Your holding time is %i:%02d.",
|
|
43416
|
-
|
|
43575
|
+
flight.holding=Tnow-flight.Tarrive
|
|
43576
|
+
local text=string.format("ATC %s: Flight %s runway is busy. You are #%d of %d in landing queue. Your holding time is %i:%02d.",
|
|
43577
|
+
airportname,flightname,qID,nqueue,flight.holding/60,flight.holding%60)
|
|
43578
|
+
BASE:I(RAT.id..text)
|
|
43417
43579
|
else
|
|
43418
|
-
local text=string.format("ATC %s: Flight %s was cleared for landing. Your holding time was %i:%02d.",
|
|
43419
|
-
|
|
43420
|
-
|
|
43580
|
+
local text=string.format("ATC %s: Flight %s was cleared for landing. Your holding time was %i:%02d.",
|
|
43581
|
+
airportname,flightname,flight.holding/60,flight.holding%60)
|
|
43582
|
+
BASE:I(RAT.id..text)
|
|
43583
|
+
RAT._ATCClearForLanding(airportname,flightname)
|
|
43421
43584
|
end
|
|
43422
43585
|
end
|
|
43423
43586
|
end
|
|
43424
|
-
RAT
|
|
43587
|
+
RAT._ATCQueue()
|
|
43425
43588
|
end
|
|
43426
|
-
function RAT
|
|
43427
|
-
|
|
43428
|
-
|
|
43429
|
-
|
|
43430
|
-
|
|
43431
|
-
RAT.ATC.
|
|
43432
|
-
|
|
43433
|
-
|
|
43434
|
-
|
|
43435
|
-
|
|
43436
|
-
|
|
43437
|
-
|
|
43589
|
+
function RAT._ATCClearForLanding(airportname,flightname)
|
|
43590
|
+
local flightgroup=_DATABASE:FindOpsGroup(flightname)
|
|
43591
|
+
if flightgroup then
|
|
43592
|
+
flightgroup:ClearToLand()
|
|
43593
|
+
local flight=RAT.ATC.flight[flightname]
|
|
43594
|
+
flight.holding=RAT.ATC.onfinal
|
|
43595
|
+
flight.Tonfinal=timer.getTime()
|
|
43596
|
+
local airport=RAT.ATC.airport[airportname]
|
|
43597
|
+
airport.busy=true
|
|
43598
|
+
airport.onfinal[flightname]=flight
|
|
43599
|
+
airport.Nonfinal=airport.Nonfinal+1
|
|
43600
|
+
airport.Tlastclearance=timer.getTime()
|
|
43601
|
+
BASE:I(RAT.id..string.format("ATC %s: Flight %s cleared for landing",airportname,flightname))
|
|
43602
|
+
if string.find(flightname,"#")then
|
|
43603
|
+
flightname=string.match(flightname,"^(.+)#")
|
|
43438
43604
|
end
|
|
43439
|
-
local
|
|
43440
|
-
|
|
43441
|
-
|
|
43605
|
+
local text=string.format("ATC %s: Flight %s you are cleared for landing.",airportname,flightname)
|
|
43606
|
+
MESSAGE:New(text,10):ToAllIf(RAT.ATC.messages)
|
|
43607
|
+
else
|
|
43608
|
+
BASE:E("Could not clear flight for landing!")
|
|
43442
43609
|
end
|
|
43443
|
-
|
|
43444
|
-
|
|
43445
|
-
local
|
|
43610
|
+
end
|
|
43611
|
+
function RAT._ATCFlightLanded(name)
|
|
43612
|
+
local flight=RAT.ATC.flight[name]
|
|
43613
|
+
if flight then
|
|
43614
|
+
local dest=flight.destination
|
|
43446
43615
|
local Tnow=timer.getTime()
|
|
43447
|
-
local Tfinal=Tnow-
|
|
43448
|
-
local Thold=
|
|
43449
|
-
RAT.ATC.airport[dest]
|
|
43450
|
-
|
|
43451
|
-
|
|
43452
|
-
|
|
43453
|
-
RAT.
|
|
43454
|
-
|
|
43455
|
-
local
|
|
43456
|
-
|
|
43457
|
-
|
|
43616
|
+
local Tfinal=Tnow-flight.Tonfinal
|
|
43617
|
+
local Thold=flight.Tonfinal-flight.Tarrive
|
|
43618
|
+
local airport=RAT.ATC.airport[dest]
|
|
43619
|
+
airport.busy=false
|
|
43620
|
+
airport.onfinal[name]=nil
|
|
43621
|
+
airport.Nonfinal=airport.Nonfinal-1
|
|
43622
|
+
RAT._ATCDelFlight(RAT.ATC.flight,name)
|
|
43623
|
+
airport.traffic=airport.traffic+1
|
|
43624
|
+
local TrafficPerHour=airport.traffic/(timer.getTime()-RAT.ATC.T0)*3600
|
|
43625
|
+
BASE:I(RAT.id..string.format("ATC %s: Flight %s landed. Tholding = %i:%02d, Tfinal = %i:%02d.",dest,name,Thold/60,Thold%60,Tfinal/60,Tfinal%60))
|
|
43626
|
+
BASE:I(RAT.id..string.format("ATC %s: Number of flights still on final %d.",dest,airport.Nonfinal))
|
|
43627
|
+
BASE:I(RAT.id..string.format("ATC %s: Traffic report: Number of planes landed in total %d. Flights/hour = %3.2f.",dest,airport.traffic,TrafficPerHour))
|
|
43458
43628
|
if string.find(name,"#")then
|
|
43459
43629
|
name=string.match(name,"^(.+)#")
|
|
43460
43630
|
end
|
|
43461
|
-
local
|
|
43462
|
-
|
|
43463
|
-
BASE:T(RAT.id..text2)
|
|
43464
|
-
BASE:T(RAT.id..text3)
|
|
43465
|
-
MESSAGE:New(text4,10):ToAllIf(RAT.ATC.messages)
|
|
43631
|
+
local text=string.format("ATC %s: Flight %s landed. Welcome to %s.",dest,name,dest)
|
|
43632
|
+
MESSAGE:New(text,10):ToAllIf(RAT.ATC.messages)
|
|
43466
43633
|
end
|
|
43467
43634
|
end
|
|
43468
|
-
function RAT
|
|
43635
|
+
function RAT._ATCQueue()
|
|
43636
|
+
local Tnow=timer.getTime()
|
|
43469
43637
|
for airport,_ in pairs(RAT.ATC.airport)do
|
|
43470
43638
|
local _queue={}
|
|
43471
|
-
for name,
|
|
43472
|
-
local
|
|
43473
|
-
if
|
|
43474
|
-
|
|
43639
|
+
for name,_flight in pairs(RAT.ATC.flight)do
|
|
43640
|
+
local flight=_flight
|
|
43641
|
+
if flight.holding>=0 then
|
|
43642
|
+
flight.holding=Tnow-flight.Tarrive
|
|
43475
43643
|
end
|
|
43476
|
-
local hold=
|
|
43477
|
-
local dest=
|
|
43644
|
+
local hold=flight.holding
|
|
43645
|
+
local dest=flight.destination
|
|
43478
43646
|
if hold>=0 and airport==dest then
|
|
43479
43647
|
_queue[#_queue+1]={name,hold}
|
|
43480
43648
|
end
|
|
@@ -43508,7 +43676,7 @@ RATMANAGER.id="RATMANAGER | "
|
|
|
43508
43676
|
function RATMANAGER:New(ntot)
|
|
43509
43677
|
local self=BASE:Inherit(self,BASE:New())
|
|
43510
43678
|
self.ntot=ntot or 1
|
|
43511
|
-
self:
|
|
43679
|
+
self:I(RATMANAGER.id..string.format("Creating manager for %d groups",ntot))
|
|
43512
43680
|
return self
|
|
43513
43681
|
end
|
|
43514
43682
|
function RATMANAGER:Add(ratobject,min)
|
|
@@ -43525,7 +43693,8 @@ ratobject:Spawn(0)
|
|
|
43525
43693
|
return self
|
|
43526
43694
|
end
|
|
43527
43695
|
function RATMANAGER:Start(delay)
|
|
43528
|
-
|
|
43696
|
+
delay=delay or 5
|
|
43697
|
+
if delay and delay>0 then
|
|
43529
43698
|
local text=string.format(RATMANAGER.id.."RAT manager will be started in %d seconds.\n",delay)
|
|
43530
43699
|
text=text..string.format("Managed groups:\n")
|
|
43531
43700
|
for i=1,self.nrat do
|
|
@@ -43533,10 +43702,8 @@ text=text..string.format("- %s with min groups %d\n",self.name[i],self.min[i])
|
|
|
43533
43702
|
end
|
|
43534
43703
|
text=text..string.format("Number of constantly alive groups %d",self.ntot)
|
|
43535
43704
|
self:E(text)
|
|
43536
|
-
|
|
43537
|
-
|
|
43538
|
-
end
|
|
43539
|
-
function RATMANAGER:_Start()
|
|
43705
|
+
self:ScheduleOnce(delay,RATMANAGER.Start,self,0)
|
|
43706
|
+
else
|
|
43540
43707
|
local n=0
|
|
43541
43708
|
for i=1,self.nrat do
|
|
43542
43709
|
n=n+self.min[i]
|
|
@@ -43547,30 +43714,32 @@ local time=0.0
|
|
|
43547
43714
|
for i=1,self.nrat do
|
|
43548
43715
|
for j=1,N[i]do
|
|
43549
43716
|
time=time+self.dTspawn
|
|
43550
|
-
|
|
43717
|
+
self:ScheduleOnce(time,RAT._SpawnWithRoute,self.rat[i])
|
|
43551
43718
|
end
|
|
43552
43719
|
end
|
|
43553
43720
|
for i=1,self.nrat do
|
|
43554
|
-
|
|
43555
|
-
|
|
43556
|
-
|
|
43721
|
+
local rat=self.rat[i]
|
|
43722
|
+
if rat.uncontrolled and rat.activate_uncontrolled then
|
|
43723
|
+
local Tactivate=math.max(time+1,rat.activate_delay)
|
|
43724
|
+
self:ScheduleRepeat(Tactivate,rat.activate_delta,rat.activate_frand,nil,rat._ActivateUncontrolled,rat)
|
|
43557
43725
|
end
|
|
43558
43726
|
end
|
|
43559
43727
|
local TstartManager=math.max(time+1,self.Tcheck)
|
|
43560
43728
|
self.manager,self.managerid=SCHEDULER:New(self,self._Manage,{self},TstartManager,self.Tcheck)
|
|
43561
43729
|
local text=string.format(RATMANAGER.id.."Starting RAT manager with scheduler ID %s in %d seconds. Repeat interval %d seconds.",self.managerid,TstartManager,self.Tcheck)
|
|
43562
|
-
self:
|
|
43730
|
+
self:I(text)
|
|
43731
|
+
end
|
|
43563
43732
|
return self
|
|
43564
43733
|
end
|
|
43565
43734
|
function RATMANAGER:Stop(delay)
|
|
43566
43735
|
delay=delay or 1
|
|
43567
|
-
|
|
43568
|
-
|
|
43569
|
-
|
|
43570
|
-
|
|
43571
|
-
|
|
43572
|
-
self:E(string.format(RATMANAGER.id.."Stopping manager with scheduler ID %s.",self.managerid))
|
|
43736
|
+
if delay and delay>0 then
|
|
43737
|
+
self:I(RATMANAGER.id..string.format("Manager will be stopped in %d seconds.",delay))
|
|
43738
|
+
self:ScheduleOnce(delay,RATMANAGER.Stop,self,0)
|
|
43739
|
+
else
|
|
43740
|
+
self:I(RATMANAGER.id..string.format("Stopping manager with scheduler ID %s",self.managerid))
|
|
43573
43741
|
self.manager:Stop(self.managerid)
|
|
43742
|
+
end
|
|
43574
43743
|
return self
|
|
43575
43744
|
end
|
|
43576
43745
|
function RATMANAGER:SetTcheck(dt)
|
|
@@ -43583,15 +43752,14 @@ return self
|
|
|
43583
43752
|
end
|
|
43584
43753
|
function RATMANAGER:_Manage()
|
|
43585
43754
|
local ntot=self:_Count()
|
|
43586
|
-
|
|
43587
|
-
self:T(RATMANAGER.id..text)
|
|
43755
|
+
self:T(RATMANAGER.id..string.format("Number of alive groups %d. New groups to be spawned %d.",ntot,self.ntot-ntot))
|
|
43588
43756
|
local N=self:_RollDice(self.nrat,self.ntot,self.min,self.alive)
|
|
43589
43757
|
local time=0.0
|
|
43590
43758
|
for i=1,self.nrat do
|
|
43591
43759
|
for j=1,N[i]do
|
|
43592
43760
|
time=time+self.dTspawn
|
|
43593
43761
|
self.planned[i]=self.planned[i]+1
|
|
43594
|
-
|
|
43762
|
+
self:ScheduleOnce(time,RATMANAGER._Spawn,self,i)
|
|
43595
43763
|
end
|
|
43596
43764
|
end
|
|
43597
43765
|
end
|
|
@@ -59414,6 +59582,7 @@ brc=self:GetBRCintoWind(self.recoverywindow.SPEED)
|
|
|
59414
59582
|
end
|
|
59415
59583
|
flight.Tcharlie=self:_GetCharlieTime(flight)
|
|
59416
59584
|
local Ccharlie=UTILS.SecondsToClock(flight.Tcharlie)
|
|
59585
|
+
brc=brc%360
|
|
59417
59586
|
self:_MarshalCallArrived(flight.onboard,flight.case,brc,alt,Ccharlie,P)
|
|
59418
59587
|
if self.TACANon and(not flight.ai)and flight.difficulty==AIRBOSS.Difficulty.EASY then
|
|
59419
59588
|
local radial=self:GetRadial(flight.case,true,true,true)
|
|
@@ -59777,7 +59946,7 @@ playerData.stable=false
|
|
|
59777
59946
|
playerData.landed=false
|
|
59778
59947
|
playerData.Tlso=timer.getTime()
|
|
59779
59948
|
playerData.Tgroove=nil
|
|
59780
|
-
playerData.TIG0=
|
|
59949
|
+
playerData.TIG0=0
|
|
59781
59950
|
playerData.wire=nil
|
|
59782
59951
|
playerData.flag=-100
|
|
59783
59952
|
playerData.debriefschedulerID=nil
|
|
@@ -60807,77 +60976,9 @@ if self:_CheckAbort(X,Z,self.BreakEntry)then
|
|
|
60807
60976
|
self:_AbortPattern(playerData,X,Z,self.BreakEntry,true)
|
|
60808
60977
|
return
|
|
60809
60978
|
end
|
|
60810
|
-
local stern=self:_GetSternCoord()
|
|
60811
|
-
local coord=playerData.unit:GetCoordinate()
|
|
60812
|
-
local dist=coord:Get2DDistance(stern)
|
|
60813
|
-
local playerCallsign=playerData.unit:GetCallsign()
|
|
60814
|
-
local playerName=playerData.name
|
|
60815
|
-
local unit=playerData.unit
|
|
60816
|
-
local unitClient=Unit.getByName(unit:GetName())
|
|
60817
|
-
local hookArgument=unitClient:getDrawArgumentValue(25)
|
|
60818
|
-
local hookArgument_Tomcat=unitClient:getDrawArgumentValue(1305)
|
|
60819
|
-
local speedMPS=playerData.unit:GetVelocityMPS()
|
|
60820
|
-
local speedKTS=UTILS.MpsToKnots(speedMPS)
|
|
60821
|
-
local player_alt=playerData.unit:GetAltitude()
|
|
60822
|
-
player_alt_feet=player_alt*3.28
|
|
60823
|
-
player_alt_feet=player_alt_feet/10
|
|
60824
|
-
player_alt_feet=math.floor(player_alt_feet)*10
|
|
60825
|
-
local player_velocity_round=speedKTS*1.00
|
|
60826
|
-
player_velocity_round=player_velocity_round/10
|
|
60827
|
-
player_velocity_round=math.floor(player_velocity_round)*10
|
|
60828
|
-
local player_alt_feet=player_alt*3.28
|
|
60829
|
-
player_alt_feet=player_alt_feet/10
|
|
60830
|
-
player_alt_feet=math.floor(player_alt_feet)*10
|
|
60831
|
-
local Play_SH_Sound=USERSOUND:New("Airboss Soundfiles/GreatBallsOfFire.ogg")
|
|
60832
|
-
local Play_666SH_Sound=USERSOUND:New("Airboss Soundfiles/Runninwiththedevil.ogg")
|
|
60833
|
-
local playerType=playerData.actype
|
|
60834
|
-
if dist<1000 and clientSHBFlag==false then
|
|
60835
|
-
if speedKTS>450 and speedKTS<590 then
|
|
60836
|
-
if player_alt_feet<1500 then
|
|
60837
|
-
if hookArgument>0 or hookArgument_Tomcat>0 then
|
|
60838
|
-
playerData.shb=true
|
|
60839
|
-
trigger.action.outText(playerName..' performing a Sierra Hotel Break in a '..playerType,10)
|
|
60840
|
-
local sh_message_to_discord=('**'..playerName..' is performing a Sierra Hotel Break in a '..playerType..' at '..player_velocity_round..' knots and '..player_alt_feet..' feet!**')
|
|
60841
|
-
HypeMan.sendBotMessage(sh_message_to_discord)
|
|
60842
|
-
Play_SH_Sound:ToAll()
|
|
60843
|
-
clientSHBFlag=true
|
|
60844
|
-
else
|
|
60845
|
-
playerData.shb=false
|
|
60846
|
-
end
|
|
60847
|
-
else
|
|
60848
|
-
end
|
|
60849
|
-
elseif speedKTS>589 then
|
|
60850
|
-
if player_alt_feet<625 and player_alt_feet>575 then
|
|
60851
|
-
if hookArgument>0 or hookArgument_Tomcat>0 then
|
|
60852
|
-
playerData.shb=true
|
|
60853
|
-
trigger.action.outText(playerName..' performing a 666 Sierra Hotel Break in a '..playerType,10)
|
|
60854
|
-
local sh_message_to_discord=('**'..playerName..' is performing a 666 Sierra Hotel Break in a '..playerType..' at '..player_velocity_round..' knots and '..player_alt_feet..' feet!**')
|
|
60855
|
-
HypeMan.sendBotMessage(sh_message_to_discord)
|
|
60856
|
-
Play_666SH_Sound:ToAll()
|
|
60857
|
-
clientSHBFlag=true
|
|
60858
|
-
else
|
|
60859
|
-
playerData.shb=false
|
|
60860
|
-
end
|
|
60861
|
-
else
|
|
60862
|
-
if hookArgument>0 or hookArgument_Tomcat>0 then
|
|
60863
|
-
playerData.shb=true
|
|
60864
|
-
trigger.action.outText(playerName..' performing a Sierra Hotel Break in a '..playerType,10)
|
|
60865
|
-
local sh_message_to_discord=('**'..playerName..' is performing a Sierra Hotel Break in a '..playerType..' at '..player_velocity_round..' knots and '..player_alt_feet..' feet!**')
|
|
60866
|
-
HypeMan.sendBotMessage(sh_message_to_discord)
|
|
60867
|
-
Play_SH_Sound:ToAll()
|
|
60868
|
-
clientSHBFlag=true
|
|
60869
|
-
else
|
|
60870
|
-
playerData.shb=false
|
|
60871
|
-
end
|
|
60872
|
-
end
|
|
60873
|
-
else
|
|
60874
|
-
end
|
|
60875
|
-
else
|
|
60876
|
-
end
|
|
60877
60979
|
if self:_CheckLimits(X,Z,self.BreakEntry)then
|
|
60878
60980
|
self:_PlayerHint(playerData)
|
|
60879
60981
|
self:_SetPlayerStep(playerData,AIRBOSS.PatternStep.EARLYBREAK)
|
|
60880
|
-
clientSHBFlag=false
|
|
60881
60982
|
end
|
|
60882
60983
|
end
|
|
60883
60984
|
function AIRBOSS:_Break(playerData,part)
|
|
@@ -61165,19 +61266,19 @@ end
|
|
|
61165
61266
|
if rho>=RAR and rho<=RIM then
|
|
61166
61267
|
if gd.LUE>0.22 and lineupError<-0.22 then
|
|
61167
61268
|
env.info" Drift Right across centre ==> DR-"
|
|
61168
|
-
gd.Drift="
|
|
61269
|
+
gd.Drift="DR"
|
|
61169
61270
|
self:T(self.lid..string.format("Got Drift Right across centre step %s, d=%.3f: Max LUE=%.3f, lower LUE=%.3f",gs,d,gd.LUE,lineupError))
|
|
61170
61271
|
elseif gd.LUE<-0.22 and lineupError>0.22 then
|
|
61171
61272
|
env.info" Drift Left ==> DL-"
|
|
61172
|
-
gd.Drift="
|
|
61273
|
+
gd.Drift="DL"
|
|
61173
61274
|
self:T(self.lid..string.format("Got Drift Left across centre at step %s, d=%.3f: Min LUE=%.3f, lower LUE=%.3f",gs,d,gd.LUE,lineupError))
|
|
61174
61275
|
elseif gd.LUE>0.13 and lineupError<-0.14 then
|
|
61175
61276
|
env.info" Little Drift Right across centre ==> (DR-)"
|
|
61176
|
-
gd.Drift="
|
|
61277
|
+
gd.Drift="(DR)"
|
|
61177
61278
|
self:T(self.lid..string.format("Got Little Drift Right across centre at step %s, d=%.3f: Max LUE=%.3f, lower LUE=%.3f",gs,d,gd.LUE,lineupError))
|
|
61178
61279
|
elseif gd.LUE<-0.13 and lineupError>0.14 then
|
|
61179
61280
|
env.info" Little Drift Left across centre ==> (DL-)"
|
|
61180
|
-
gd.Drift="
|
|
61281
|
+
gd.Drift="(DL)"
|
|
61181
61282
|
self:E(self.lid..string.format("Got Little Drift Left across centre at step %s, d=%.3f: Min LUE=%.3f, lower LUE=%.3f",gs,d,gd.LUE,lineupError))
|
|
61182
61283
|
end
|
|
61183
61284
|
end
|
|
@@ -61976,9 +62077,7 @@ local hdg=self.carrier:GetHeading()
|
|
|
61976
62077
|
if magnetic then
|
|
61977
62078
|
hdg=hdg-self.magvar
|
|
61978
62079
|
end
|
|
61979
|
-
|
|
61980
|
-
hdg=hdg+360
|
|
61981
|
-
end
|
|
62080
|
+
hdg=hdg%360
|
|
61982
62081
|
return hdg
|
|
61983
62082
|
end
|
|
61984
62083
|
function AIRBOSS:GetBRC()
|
|
@@ -62077,7 +62176,7 @@ theta=math.asin(vdeck*math.sin(alpha)/vwind)
|
|
|
62077
62176
|
v=vdeck*math.cos(alpha)-vwind*math.cos(theta)
|
|
62078
62177
|
end
|
|
62079
62178
|
local magvar=magnetic and self.magvar or 0
|
|
62080
|
-
local intowind=self:GetHeadingIntoWind_old(vdeck)
|
|
62179
|
+
local intowind=self:GetHeadingIntoWind_old(vdeck,magnetic)
|
|
62081
62180
|
return intowind,v
|
|
62082
62181
|
end
|
|
62083
62182
|
function AIRBOSS:GetBRCintoWind(vdeck)
|
|
@@ -62268,7 +62367,7 @@ return select(2,string.gsub(base,pattern,""))
|
|
|
62268
62367
|
end
|
|
62269
62368
|
local TIG=""
|
|
62270
62369
|
if playerData.Tgroove and playerData.Tgroove<=360 and playerData.case<3 then
|
|
62271
|
-
TIG=self:_EvalGrooveTime(playerData)
|
|
62370
|
+
TIG=self:_EvalGrooveTime(playerData)or"N/A"
|
|
62272
62371
|
end
|
|
62273
62372
|
local GXX,nXX=self:_Flightdata2Text(playerData,AIRBOSS.GroovePos.XX)
|
|
62274
62373
|
local GIM,nIM=self:_Flightdata2Text(playerData,AIRBOSS.GroovePos.IM)
|
|
@@ -62390,14 +62489,8 @@ grade="CUT"
|
|
|
62390
62489
|
points=0.0
|
|
62391
62490
|
end
|
|
62392
62491
|
end
|
|
62393
|
-
if playerData.wire==1 and points>
|
|
62394
|
-
|
|
62395
|
-
points=3
|
|
62396
|
-
grade="(OK)"
|
|
62397
|
-
elseif points==3 then
|
|
62398
|
-
points=2
|
|
62399
|
-
grade="--"
|
|
62400
|
-
end
|
|
62492
|
+
if playerData.wire==1 and points>=3 and N>4 then
|
|
62493
|
+
points=points-1
|
|
62401
62494
|
end
|
|
62402
62495
|
env.info("Returning: "..grade.." "..points.." "..G)
|
|
62403
62496
|
return grade,points,G
|
|
@@ -62445,6 +62538,7 @@ O=little("OS")
|
|
|
62445
62538
|
end
|
|
62446
62539
|
end
|
|
62447
62540
|
local S=nil
|
|
62541
|
+
local A=nil
|
|
62448
62542
|
if step~=AIRBOSS.PatternStep.GROOVE_IW then
|
|
62449
62543
|
if AIRBOSS.PatternStep.GROOVE_AR and playerData.waveoff==true and playerData.owo==true then
|
|
62450
62544
|
else
|
|
@@ -62461,7 +62555,6 @@ S="F"
|
|
|
62461
62555
|
elseif AOA<acaoa.OnSpeedMin then
|
|
62462
62556
|
S=little("F")
|
|
62463
62557
|
end
|
|
62464
|
-
local A=nil
|
|
62465
62558
|
if GSE>self.gle.HIGH then
|
|
62466
62559
|
A=underline("H")
|
|
62467
62560
|
elseif GSE>self.gle.High then
|
|
@@ -69133,6 +69226,7 @@ CTLD.UnitTypeCapabilities={
|
|
|
69133
69226
|
["Mi-24V"]={type="Mi-24V",crates=true,troops=true,cratelimit=2,trooplimit=8,length=18,cargoweightlimit=700},
|
|
69134
69227
|
["Hercules"]={type="Hercules",crates=true,troops=true,cratelimit=7,trooplimit=64,length=25,cargoweightlimit=19000},
|
|
69135
69228
|
["UH-60L"]={type="UH-60L",crates=true,troops=true,cratelimit=2,trooplimit=20,length=16,cargoweightlimit=3500},
|
|
69229
|
+
["UH-60L_DAP"]={type="UH-60L_DAP",crates=false,troops=true,cratelimit=0,trooplimit=2,length=16,cargoweightlimit=500},
|
|
69136
69230
|
["MH-60R"]={type="MH-60R",crates=true,troops=true,cratelimit=2,trooplimit=20,length=16,cargoweightlimit=3500},
|
|
69137
69231
|
["SH-60B"]={type="SH-60B",crates=true,troops=true,cratelimit=2,trooplimit=20,length=16,cargoweightlimit=3500},
|
|
69138
69232
|
["AH-64D_BLK_II"]={type="AH-64D_BLK_II",crates=false,troops=true,cratelimit=0,trooplimit=2,length=17,cargoweightlimit=200},
|
|
@@ -69148,7 +69242,7 @@ CTLD.FixedWingTypes={
|
|
|
69148
69242
|
["Bronco"]="Bronco",
|
|
69149
69243
|
["Mosquito"]="Mosquito",
|
|
69150
69244
|
}
|
|
69151
|
-
CTLD.version="1.3.
|
|
69245
|
+
CTLD.version="1.3.38"
|
|
69152
69246
|
function CTLD:New(Coalition,Prefixes,Alias)
|
|
69153
69247
|
local self=BASE:Inherit(self,FSM:New())
|
|
69154
69248
|
BASE:T({Coalition,Prefixes,Alias})
|
|
@@ -69250,6 +69344,7 @@ self.dropAsCargoCrate=false
|
|
|
69250
69344
|
self.smokedistance=2000
|
|
69251
69345
|
self.movetroopstowpzone=true
|
|
69252
69346
|
self.movetroopsdistance=5000
|
|
69347
|
+
self.returntroopstobase=true
|
|
69253
69348
|
self.troopdropzoneradius=100
|
|
69254
69349
|
self.VehicleMoveFormation=AI.Task.VehicleFormation.VEE
|
|
69255
69350
|
self.enableHercules=false
|
|
@@ -70354,6 +70449,7 @@ self:_UpdateUnitCargoMass(Unit)
|
|
|
70354
70449
|
self:_RefreshDropCratesMenu(Group,Unit)
|
|
70355
70450
|
self:_RefreshLoadCratesMenu(Group,Unit)
|
|
70356
70451
|
self:_CleanupTrackedCrates(crateidsloaded)
|
|
70452
|
+
self:__CratesPickedUp(1,Group,Unit,loaded.Cargo)
|
|
70357
70453
|
end
|
|
70358
70454
|
end
|
|
70359
70455
|
return self
|
|
@@ -70621,7 +70717,7 @@ if not inzone then
|
|
|
70621
70717
|
inzone,zonename,zone,distance=self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP)
|
|
70622
70718
|
end
|
|
70623
70719
|
if inzone then
|
|
70624
|
-
droppingatbase=
|
|
70720
|
+
droppingatbase=self.returntroopstobase
|
|
70625
70721
|
end
|
|
70626
70722
|
local hoverunload=self:IsCorrectHover(Unit)
|
|
70627
70723
|
local IsHerc=self:IsFixedWing(Unit)
|
|
@@ -71352,7 +71448,7 @@ end
|
|
|
71352
71448
|
end
|
|
71353
71449
|
end
|
|
71354
71450
|
else
|
|
71355
|
-
if self.usesubcats then
|
|
71451
|
+
if self.usesubcats==true then
|
|
71356
71452
|
local subcatmenus={}
|
|
71357
71453
|
for catName,_ in pairs(self.subcats)do
|
|
71358
71454
|
subcatmenus[catName]=MENU_GROUP:New(_group,catName,cratesmenu)
|
|
@@ -71811,7 +71907,7 @@ if not inzone then
|
|
|
71811
71907
|
inzone,zonename,zone,distance=self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP)
|
|
71812
71908
|
end
|
|
71813
71909
|
if inzone then
|
|
71814
|
-
droppingatbase=
|
|
71910
|
+
droppingatbase=self.returntroopstobase
|
|
71815
71911
|
end
|
|
71816
71912
|
if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen(Unit:GetName())then
|
|
71817
71913
|
self:_SendMessage("You need to open the door(s) to unload troops!",10,false,Group)
|
|
@@ -72192,7 +72288,12 @@ self:E(self.lid.."**** Ship does not exist: "..Name)
|
|
|
72192
72288
|
return self
|
|
72193
72289
|
end
|
|
72194
72290
|
end
|
|
72195
|
-
local
|
|
72291
|
+
local exists=true
|
|
72292
|
+
local ctldzone=self:GetCTLDZone(Name,Type)
|
|
72293
|
+
if not ctldzone then
|
|
72294
|
+
exists=false
|
|
72295
|
+
ctldzone={}
|
|
72296
|
+
end
|
|
72196
72297
|
ctldzone.active=Active or false
|
|
72197
72298
|
ctldzone.color=Color or SMOKECOLOR.Red
|
|
72198
72299
|
ctldzone.name=Name or"NONE"
|
|
@@ -72215,9 +72316,45 @@ if Type==CTLD.CargoZoneType.SHIP then
|
|
|
72215
72316
|
ctldzone.shiplength=Shiplength or 100
|
|
72216
72317
|
ctldzone.shipwidth=Shipwidth or 10
|
|
72217
72318
|
end
|
|
72319
|
+
if not exists then
|
|
72218
72320
|
self:AddZone(ctldzone)
|
|
72321
|
+
end
|
|
72219
72322
|
return self
|
|
72220
72323
|
end
|
|
72324
|
+
function CTLD:GetCTLDZone(Name,Type)
|
|
72325
|
+
if Type==CTLD.CargoZoneType.LOAD then
|
|
72326
|
+
for _,z in pairs(self.pickupZones)do
|
|
72327
|
+
if z.name==Name then
|
|
72328
|
+
return z
|
|
72329
|
+
end
|
|
72330
|
+
end
|
|
72331
|
+
elseif Type==CTLD.CargoZoneType.DROP then
|
|
72332
|
+
for _,z in pairs(self.dropOffZones)do
|
|
72333
|
+
if z.name==Name then
|
|
72334
|
+
return z
|
|
72335
|
+
end
|
|
72336
|
+
end
|
|
72337
|
+
elseif Type==CTLD.CargoZoneType.SHIP then
|
|
72338
|
+
for _,z in pairs(self.shipZones)do
|
|
72339
|
+
if z.name==Name then
|
|
72340
|
+
return z
|
|
72341
|
+
end
|
|
72342
|
+
end
|
|
72343
|
+
elseif Type==CTLD.CargoZoneType.BEACON then
|
|
72344
|
+
for _,z in pairs(self.droppedBeacons)do
|
|
72345
|
+
if z.name==Name then
|
|
72346
|
+
return z
|
|
72347
|
+
end
|
|
72348
|
+
end
|
|
72349
|
+
else
|
|
72350
|
+
for _,z in pairs(self.wpZones)do
|
|
72351
|
+
if z.name==Name then
|
|
72352
|
+
return z
|
|
72353
|
+
end
|
|
72354
|
+
end
|
|
72355
|
+
end
|
|
72356
|
+
return nil
|
|
72357
|
+
end
|
|
72221
72358
|
function CTLD:AddCTLDZoneFromAirbase(AirbaseName,Type,Color,Active,HasBeacon)
|
|
72222
72359
|
self:T(self.lid.." AddCTLDZoneFromAirbase")
|
|
72223
72360
|
local AFB=AIRBASE:FindByName(AirbaseName)
|
|
@@ -74211,13 +74348,14 @@ CSAR.AircraftType["Mi-24P"]=8
|
|
|
74211
74348
|
CSAR.AircraftType["Mi-24V"]=8
|
|
74212
74349
|
CSAR.AircraftType["Bell-47"]=2
|
|
74213
74350
|
CSAR.AircraftType["UH-60L"]=10
|
|
74351
|
+
CSAR.AircraftType["UH-60L_DAP"]=2
|
|
74214
74352
|
CSAR.AircraftType["AH-64D_BLK_II"]=2
|
|
74215
74353
|
CSAR.AircraftType["Bronco-OV-10A"]=2
|
|
74216
74354
|
CSAR.AircraftType["MH-60R"]=10
|
|
74217
74355
|
CSAR.AircraftType["OH-6A"]=2
|
|
74218
74356
|
CSAR.AircraftType["OH58D"]=2
|
|
74219
74357
|
CSAR.AircraftType["CH-47Fbl1"]=31
|
|
74220
|
-
CSAR.version="1.0.
|
|
74358
|
+
CSAR.version="1.0.34"
|
|
74221
74359
|
function CSAR:New(Coalition,Template,Alias)
|
|
74222
74360
|
local self=BASE:Inherit(self,FSM:New())
|
|
74223
74361
|
BASE:T({Coalition,Template,Alias})
|
|
@@ -74663,11 +74801,11 @@ return self
|
|
|
74663
74801
|
end
|
|
74664
74802
|
local initdcscoord=nil
|
|
74665
74803
|
local initcoord=nil
|
|
74666
|
-
if _event.id==EVENTS.Ejection then
|
|
74804
|
+
if _event.id==EVENTS.Ejection and _event.TgtDCSUnit then
|
|
74667
74805
|
initdcscoord=_event.TgtDCSUnit:getPoint()
|
|
74668
74806
|
initcoord=COORDINATE:NewFromVec3(initdcscoord)
|
|
74669
74807
|
self:T({initdcscoord})
|
|
74670
|
-
|
|
74808
|
+
elseif _event.IniDCSUnit then
|
|
74671
74809
|
initdcscoord=_event.IniDCSUnit:getPoint()
|
|
74672
74810
|
initcoord=COORDINATE:NewFromVec3(initdcscoord)
|
|
74673
74811
|
self:T({initdcscoord})
|
|
@@ -74730,7 +74868,10 @@ return self
|
|
|
74730
74868
|
end
|
|
74731
74869
|
if _place:GetCoalition()==self.coalition or _place:GetCoalition()==coalition.side.NEUTRAL then
|
|
74732
74870
|
self:__Landed(2,_event.IniUnitName,_place)
|
|
74733
|
-
|
|
74871
|
+
local IsHeloBase=false
|
|
74872
|
+
local ABName=_place:GetName()
|
|
74873
|
+
if ABName and string.find(ABName,"^H")then IsHeloBase=true end
|
|
74874
|
+
self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName,true,true,IsHeloBase)
|
|
74734
74875
|
else
|
|
74735
74876
|
self:T(string.format("Airfield %d, Unit %d",_place:GetCoalition(),_unit:GetCoalition()))
|
|
74736
74877
|
end
|
|
@@ -75085,7 +75226,7 @@ else
|
|
|
75085
75226
|
return false
|
|
75086
75227
|
end
|
|
75087
75228
|
end
|
|
75088
|
-
function CSAR:_ScheduledSARFlight(heliname,groupname,isairport,noreschedule)
|
|
75229
|
+
function CSAR:_ScheduledSARFlight(heliname,groupname,isairport,noreschedule,IsHeloBase)
|
|
75089
75230
|
self:T(self.lid.." _ScheduledSARFlight")
|
|
75090
75231
|
self:T({heliname,groupname})
|
|
75091
75232
|
local _heliUnit=self:_GetSARHeli(heliname)
|
|
@@ -75103,7 +75244,7 @@ self:T(self.lid.."[Drop off debug] Check distance to MASH for "..heliname.." Dis
|
|
|
75103
75244
|
return
|
|
75104
75245
|
end
|
|
75105
75246
|
self:T(self.lid.."[Drop off debug] Check distance to MASH for "..heliname.." Distance km: "..math.floor(_dist/1000))
|
|
75106
|
-
if(_dist<self.FARPRescueDistance or isairport)and
|
|
75247
|
+
if(_dist<self.FARPRescueDistance or isairport)and((_heliUnit:InAir()==false)or(IsHeloBase==true))then
|
|
75107
75248
|
self:T(self.lid.."[Drop off debug] Distance ok, door check")
|
|
75108
75249
|
if self.pilotmustopendoors and self:_IsLoadingDoorOpen(heliname)==false then
|
|
75109
75250
|
self:_DisplayMessageToSAR(_heliUnit,"Open the door to let me out!",self.messageTime,true,true)
|
|
@@ -75116,7 +75257,7 @@ end
|
|
|
75116
75257
|
end
|
|
75117
75258
|
if not noreschedule then
|
|
75118
75259
|
self:__Returning(5,heliname,_woundedGroupName,isairport)
|
|
75119
|
-
self:ScheduleOnce(5,self._ScheduledSARFlight,self,heliname,groupname,isairport,noreschedule)
|
|
75260
|
+
self:ScheduleOnce(5,self._ScheduledSARFlight,self,heliname,groupname,isairport,noreschedule,IsHeloBase)
|
|
75120
75261
|
end
|
|
75121
75262
|
return self
|
|
75122
75263
|
end
|