@jtff/miztemplate-lib 3.2.4 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- env.info('*** MOOSE GITHUB Commit Hash ID: 2024-06-09T18:32:10+02:00-4668132b37147cb37b15f6a6bb522078e56b5076 ***')
1
+ env.info('*** MOOSE GITHUB Commit Hash ID: 2024-08-12T11:39:03+02:00-a54944b0214abee2fc0206e8a246bbe9f36c41d3 ***')
2
2
  if not MOOSE_DEVELOPMENT_FOLDER then
3
3
  MOOSE_DEVELOPMENT_FOLDER='Scripts'
4
4
  end
@@ -1045,7 +1045,8 @@ Syria="Syria",
1045
1045
  MarianaIslands="MarianaIslands",
1046
1046
  Falklands="Falklands",
1047
1047
  Sinai="SinaiMap",
1048
- Kola="Kola"
1048
+ Kola="Kola",
1049
+ Afghanistan="Afghanistan",
1049
1050
  }
1050
1051
  CALLSIGN={
1051
1052
  Aircraft={
@@ -1166,6 +1167,44 @@ Trash=10,
1166
1167
  Cargo=11,
1167
1168
  Ascot=12,
1168
1169
  },
1170
+ AH64={
1171
+ Army_Air=9,
1172
+ Apache=10,
1173
+ Crow=11,
1174
+ Sioux=12,
1175
+ Gatling=13,
1176
+ Gunslinger=14,
1177
+ Hammerhead=15,
1178
+ Bootleg=16,
1179
+ Palehorse=17,
1180
+ Carnivor=18,
1181
+ Saber=19,
1182
+ },
1183
+ Kiowa={
1184
+ Anvil=1,
1185
+ Azrael=2,
1186
+ BamBam=3,
1187
+ Blackjack=4,
1188
+ Bootleg=5,
1189
+ BurninStogie=6,
1190
+ Chaos=7,
1191
+ CrazyHorse=8,
1192
+ Crusader=9,
1193
+ Darkhorse=10,
1194
+ Eagle=11,
1195
+ Lighthorse=12,
1196
+ Mustang=13,
1197
+ Outcast=14,
1198
+ Palehorse=15,
1199
+ Pegasus=16,
1200
+ Pistol=17,
1201
+ Roughneck=18,
1202
+ Saber=19,
1203
+ Shamus=20,
1204
+ Spur=21,
1205
+ Stetson=22,
1206
+ Wrath=23,
1207
+ },
1169
1208
  }
1170
1209
  UTILS={
1171
1210
  _MarkID=1
@@ -1316,6 +1355,11 @@ return s
1316
1355
  end
1317
1356
  end
1318
1357
  end
1358
+ function UTILS.TableLength(T)
1359
+ local count=0
1360
+ for _ in pairs(T or{})do count=count+1 end
1361
+ return count
1362
+ end
1319
1363
  function UTILS.PrintTableToLog(table,indent,noprint)
1320
1364
  local text="\n"
1321
1365
  if not table or type(table)~="table"then
@@ -1325,7 +1369,7 @@ end
1325
1369
  if not indent then indent=0 end
1326
1370
  for k,v in pairs(table)do
1327
1371
  if string.find(k," ")then k='"'..k..'"'end
1328
- if type(v)=="table"then
1372
+ if type(v)=="table"and UTILS.TableLength(v)>0 then
1329
1373
  if not noprint then
1330
1374
  env.info(string.rep(" ",indent)..tostring(k).." = {")
1331
1375
  end
@@ -2073,6 +2117,8 @@ elseif map==DCSMAP.Sinai then
2073
2117
  declination=4.8
2074
2118
  elseif map==DCSMAP.Kola then
2075
2119
  declination=15
2120
+ elseif map==DCSMAP.Afghanistan then
2121
+ declination=3
2076
2122
  else
2077
2123
  declination=0
2078
2124
  end
@@ -2210,6 +2256,16 @@ if value==Callsign then
2210
2256
  return name
2211
2257
  end
2212
2258
  end
2259
+ for name,value in pairs(CALLSIGN.AH64)do
2260
+ if value==Callsign then
2261
+ return name
2262
+ end
2263
+ end
2264
+ for name,value in pairs(CALLSIGN.Kiowa)do
2265
+ if value==Callsign then
2266
+ return name
2267
+ end
2268
+ end
2213
2269
  return"Ghostrider"
2214
2270
  end
2215
2271
  function UTILS.GMTToLocalTimeDifference()
@@ -2234,6 +2290,8 @@ elseif theatre==DCSMAP.Sinai then
2234
2290
  return 2
2235
2291
  elseif theatre==DCSMAP.Kola then
2236
2292
  return 3
2293
+ elseif theatre==DCSMAP.Afghanistan then
2294
+ return 4.5
2237
2295
  else
2238
2296
  BASE:E(string.format("ERROR: Unknown Map %s in UTILS.GMTToLocal function. Returning 0",tostring(theatre)))
2239
2297
  return 0
@@ -2418,10 +2476,14 @@ if type_name=="MH-60R"and(unit:getDrawArgumentValue(403)>0 or unit:getDrawArgume
2418
2476
  BASE:T(unit_name.." cargo door is open")
2419
2477
  return true
2420
2478
  end
2421
- if type_name==" OH-58D"and(unit:getDrawArgumentValue(35)>0 or unit:getDrawArgumentValue(421)==-1)then
2479
+ if type_name=="OH-58D"and(unit:getDrawArgumentValue(35)>0 or unit:getDrawArgumentValue(421)==-1)then
2422
2480
  BASE:T(unit_name.." cargo door is open")
2423
2481
  return true
2424
2482
  end
2483
+ if type_name=="CH-47Fbl1"and(unit:getDrawArgumentValue(86)>0.5)then
2484
+ BASE:T(unit_name.." rear cargo door is open")
2485
+ return true
2486
+ end
2425
2487
  return false
2426
2488
  end
2427
2489
  return nil
@@ -3548,6 +3610,57 @@ end
3548
3610
  Text="MGRS;"..Text
3549
3611
  return Text
3550
3612
  end
3613
+ function UTILS.ReadCSV(filename)
3614
+ if not UTILS.FileExists(filename)then
3615
+ env.error("File does not exist")
3616
+ return nil
3617
+ end
3618
+ local function _loadfile(filename)
3619
+ local f=io.open(filename,"rb")
3620
+ if f then
3621
+ local data=f:read("*all")
3622
+ f:close()
3623
+ return data
3624
+ else
3625
+ BASE:E(string.format("WARNING: Could read data from file %s!",tostring(filename)))
3626
+ return nil
3627
+ end
3628
+ end
3629
+ local data=_loadfile(filename)
3630
+ local lines=UTILS.Split(data,"\n")
3631
+ for _,line in pairs(lines)do
3632
+ line=string.gsub(line,"[\n\r]","")
3633
+ end
3634
+ local sep=";"
3635
+ local columns=UTILS.Split(lines[1],sep)
3636
+ table.remove(lines,1)
3637
+ local csvdata={}
3638
+ for i,line in pairs(lines)do
3639
+ line=string.gsub(line,"[\n\r]","")
3640
+ local row={}
3641
+ for j,value in pairs(UTILS.Split(line,sep))do
3642
+ local key=string.gsub(columns[j],"[\n\r]","")
3643
+ row[key]=value
3644
+ end
3645
+ table.insert(csvdata,row)
3646
+ end
3647
+ return csvdata
3648
+ end
3649
+ function UTILS.LCGRandomSeed(seed)
3650
+ UTILS.lcg={
3651
+ seed=seed or math.random(1,2^32-1),
3652
+ a=1664525,
3653
+ c=1013904223,
3654
+ m=2^32
3655
+ }
3656
+ end
3657
+ function UTILS.LCGRandom()
3658
+ if UTILS.lcg==nil then
3659
+ UTILS.LCGRandomSeed()
3660
+ end
3661
+ UTILS.lcg.seed=(UTILS.lcg.a*UTILS.lcg.seed+UTILS.lcg.c)%UTILS.lcg.m
3662
+ return UTILS.lcg.seed/UTILS.lcg.m
3663
+ end
3551
3664
  PROFILER={
3552
3665
  ClassName="PROFILER",
3553
3666
  Counters={},
@@ -4839,7 +4952,7 @@ message.volume=Volume
4839
4952
  self:SendTable(message)
4840
4953
  return self
4841
4954
  end
4842
- local _TraceOnOff=true
4955
+ local _TraceOnOff=false
4843
4956
  local _TraceLevel=1
4844
4957
  local _TraceAll=false
4845
4958
  local _TraceClass={}
@@ -5193,7 +5306,7 @@ end
5193
5306
  end
5194
5307
  end
5195
5308
  function BASE:F(Arguments)
5196
- if BASE.Debug and _TraceOnOff then
5309
+ if BASE.Debug and _TraceOnOff==true then
5197
5310
  local DebugInfoCurrent=BASE.Debug.getinfo(2,"nl")
5198
5311
  local DebugInfoFrom=BASE.Debug.getinfo(3,"l")
5199
5312
  if _TraceLevel>=1 then
@@ -5202,7 +5315,7 @@ end
5202
5315
  end
5203
5316
  end
5204
5317
  function BASE:F2(Arguments)
5205
- if BASE.Debug and _TraceOnOff then
5318
+ if BASE.Debug and _TraceOnOff==true and _TraceLevel>=2 then
5206
5319
  local DebugInfoCurrent=BASE.Debug.getinfo(2,"nl")
5207
5320
  local DebugInfoFrom=BASE.Debug.getinfo(3,"l")
5208
5321
  if _TraceLevel>=2 then
@@ -5211,7 +5324,7 @@ end
5211
5324
  end
5212
5325
  end
5213
5326
  function BASE:F3(Arguments)
5214
- if BASE.Debug and _TraceOnOff then
5327
+ if BASE.Debug and _TraceOnOff==true and _TraceLevel>=3 then
5215
5328
  local DebugInfoCurrent=BASE.Debug.getinfo(2,"nl")
5216
5329
  local DebugInfoFrom=BASE.Debug.getinfo(3,"l")
5217
5330
  if _TraceLevel>=3 then
@@ -5241,7 +5354,7 @@ end
5241
5354
  end
5242
5355
  end
5243
5356
  function BASE:T(Arguments)
5244
- if BASE.Debug and _TraceOnOff then
5357
+ if BASE.Debug and _TraceOnOff==true then
5245
5358
  local DebugInfoCurrent=BASE.Debug.getinfo(2,"nl")
5246
5359
  local DebugInfoFrom=BASE.Debug.getinfo(3,"l")
5247
5360
  if _TraceLevel>=1 then
@@ -5250,7 +5363,7 @@ end
5250
5363
  end
5251
5364
  end
5252
5365
  function BASE:T2(Arguments)
5253
- if BASE.Debug and _TraceOnOff then
5366
+ if BASE.Debug and _TraceOnOff==true and _TraceLevel>=2 then
5254
5367
  local DebugInfoCurrent=BASE.Debug.getinfo(2,"nl")
5255
5368
  local DebugInfoFrom=BASE.Debug.getinfo(3,"l")
5256
5369
  if _TraceLevel>=2 then
@@ -5259,7 +5372,7 @@ end
5259
5372
  end
5260
5373
  end
5261
5374
  function BASE:T3(Arguments)
5262
- if BASE.Debug and _TraceOnOff then
5375
+ if BASE.Debug and _TraceOnOff==true and _TraceLevel>=3 then
5263
5376
  local DebugInfoCurrent=BASE.Debug.getinfo(2,"nl")
5264
5377
  local DebugInfoFrom=BASE.Debug.getinfo(3,"l")
5265
5378
  if _TraceLevel>=3 then
@@ -6459,14 +6572,18 @@ UnitDeleteTask=world.event.S_EVENT_UNIT_DELETE_TASK or-1,
6459
6572
  SimulationStart=world.event.S_EVENT_SIMULATION_START or-1,
6460
6573
  WeaponRearm=world.event.S_EVENT_WEAPON_REARM or-1,
6461
6574
  WeaponDrop=world.event.S_EVENT_WEAPON_DROP or-1,
6462
- UnitTaskTimeout=world.event.S_EVENT_UNIT_TASK_TIMEOUT or-1,
6575
+ UnitTaskComplete=world.event.S_EVENT_UNIT_TASK_COMPLETE or-1,
6463
6576
  UnitTaskStage=world.event.S_EVENT_UNIT_TASK_STAGE or-1,
6464
- MacSubtaskScore=world.event.S_EVENT_MAC_SUBTASK_SCORE or-1,
6465
6577
  MacExtraScore=world.event.S_EVENT_MAC_EXTRA_SCORE or-1,
6466
6578
  MissionRestart=world.event.S_EVENT_MISSION_RESTART or-1,
6467
6579
  MissionWinner=world.event.S_EVENT_MISSION_WINNER or-1,
6468
- PostponedTakeoff=world.event.S_EVENT_POSTPONED_TAKEOFF or-1,
6469
- PostponedLand=world.event.S_EVENT_POSTPONED_LAND or-1,
6580
+ RunwayTakeoff=world.event.S_EVENT_RUNWAY_TAKEOFF or-1,
6581
+ RunwayTouch=world.event.S_EVENT_RUNWAY_TOUCH or-1,
6582
+ MacLMSRestart=world.event.S_EVENT_MAC_LMS_RESTART or-1,
6583
+ SimulationFreeze=world.event.S_EVENT_SIMULATION_FREEZE or-1,
6584
+ SimulationUnfreeze=world.event.S_EVENT_SIMULATION_UNFREEZE or-1,
6585
+ HumanAircraftRepairStart=world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_START or-1,
6586
+ HumanAircraftRepairFinish=world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH or-1,
6470
6587
  }
6471
6588
  local _EVENTMETA={
6472
6589
  [world.event.S_EVENT_SHOT]={
@@ -6780,24 +6897,12 @@ Side="I",
6780
6897
  Event="OnEventWeaponDrop",
6781
6898
  Text="S_EVENT_WEAPON_DROP"
6782
6899
  },
6783
- [EVENTS.UnitTaskTimeout]={
6784
- Order=1,
6785
- Side="I",
6786
- Event="OnEventUnitTaskTimeout",
6787
- Text="S_EVENT_UNIT_TASK_TIMEOUT "
6788
- },
6789
6900
  [EVENTS.UnitTaskStage]={
6790
6901
  Order=1,
6791
6902
  Side="I",
6792
6903
  Event="OnEventUnitTaskStage",
6793
6904
  Text="S_EVENT_UNIT_TASK_STAGE "
6794
6905
  },
6795
- [EVENTS.MacSubtaskScore]={
6796
- Order=1,
6797
- Side="I",
6798
- Event="OnEventMacSubtaskScore",
6799
- Text="S_EVENT_MAC_SUBTASK_SCORE"
6800
- },
6801
6906
  [EVENTS.MacExtraScore]={
6802
6907
  Order=1,
6803
6908
  Side="I",
@@ -6816,17 +6921,47 @@ Side="I",
6816
6921
  Event="OnEventMissionWinner",
6817
6922
  Text="S_EVENT_MISSION_WINNER"
6818
6923
  },
6819
- [EVENTS.PostponedTakeoff]={
6924
+ [EVENTS.RunwayTakeoff]={
6925
+ Order=1,
6926
+ Side="I",
6927
+ Event="OnEventRunwayTakeoff",
6928
+ Text="S_EVENT_RUNWAY_TAKEOFF"
6929
+ },
6930
+ [EVENTS.RunwayTouch]={
6931
+ Order=1,
6932
+ Side="I",
6933
+ Event="OnEventRunwayTouch",
6934
+ Text="S_EVENT_RUNWAY_TOUCH"
6935
+ },
6936
+ [EVENTS.MacLMSRestart]={
6820
6937
  Order=1,
6821
6938
  Side="I",
6822
- Event="OnEventPostponedTakeoff",
6823
- Text="S_EVENT_POSTPONED_TAKEOFF"
6939
+ Event="OnEventMacLMSRestart",
6940
+ Text="S_EVENT_MAC_LMS_RESTART"
6824
6941
  },
6825
- [EVENTS.PostponedLand]={
6942
+ [EVENTS.SimulationFreeze]={
6826
6943
  Order=1,
6827
6944
  Side="I",
6828
- Event="OnEventPostponedLand",
6829
- Text="S_EVENT_POSTPONED_LAND"
6945
+ Event="OnEventSimulationFreeze",
6946
+ Text="S_EVENT_SIMULATION_FREEZE"
6947
+ },
6948
+ [EVENTS.SimulationUnfreeze]={
6949
+ Order=1,
6950
+ Side="I",
6951
+ Event="OnEventSimulationUnfreeze",
6952
+ Text="S_EVENT_SIMULATION_UNFREEZE"
6953
+ },
6954
+ [EVENTS.HumanAircraftRepairStart]={
6955
+ Order=1,
6956
+ Side="I",
6957
+ Event="OnEventHumanAircraftRepairStart",
6958
+ Text="S_EVENT_HUMAN_AIRCRAFT_REPAIR_START"
6959
+ },
6960
+ [EVENTS.HumanAircraftRepairFinish]={
6961
+ Order=1,
6962
+ Side="I",
6963
+ Event="OnEventHumanAircraftRepairFinish",
6964
+ Text="S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH"
6830
6965
  },
6831
6966
  }
6832
6967
  function EVENT:New()
@@ -7185,14 +7320,14 @@ Event.TgtCategory=Event.TgtDCSUnit:getDesc().category
7185
7320
  Event.TgtTypeName=Event.TgtDCSUnit:getTypeName()
7186
7321
  end
7187
7322
  end
7188
- if Event.weapon then
7323
+ if Event.weapon and type(Event.weapon)=="table"then
7189
7324
  Event.Weapon=Event.weapon
7190
- Event.WeaponName=Event.Weapon:getTypeName()
7325
+ Event.WeaponName=Event.weapon:isExist()and Event.weapon:getTypeName()or"Unknown Weapon"
7191
7326
  Event.WeaponUNIT=CLIENT:Find(Event.Weapon,'',true)
7192
7327
  Event.WeaponPlayerName=Event.WeaponUNIT and Event.Weapon.getPlayerName and Event.Weapon:getPlayerName()
7193
- Event.WeaponCoalition=Event.WeaponUNIT and Event.Weapon:getCoalition()
7194
- Event.WeaponCategory=Event.WeaponUNIT and Event.Weapon:getDesc().category
7195
- Event.WeaponTypeName=Event.WeaponUNIT and Event.Weapon:getTypeName()
7328
+ Event.WeaponCoalition=Event.WeaponUNIT and Event.Weapon.getCoalition and Event.Weapon:getCoalition()
7329
+ Event.WeaponCategory=Event.WeaponUNIT and Event.Weapon.getDesc and Event.Weapon:getDesc().category
7330
+ Event.WeaponTypeName=Event.WeaponUNIT and Event.Weapon.getTypeName and Event.Weapon:getTypeName()
7196
7331
  end
7197
7332
  if Event.place then
7198
7333
  if Event.id==EVENTS.LandingAfterEjection then
@@ -7638,8 +7773,7 @@ end
7638
7773
  function SETTINGS:SetPlayerMenu(PlayerUnit)
7639
7774
  if _SETTINGS.ShowPlayerMenu==true then
7640
7775
  local PlayerGroup=PlayerUnit:GetGroup()
7641
- local PlayerName=PlayerUnit:GetPlayerName()
7642
- local PlayerNames=PlayerGroup:GetPlayerNames()
7776
+ local PlayerName=PlayerUnit:GetPlayerName()or"None"
7643
7777
  local PlayerMenu=MENU_GROUP:New(PlayerGroup,'Settings "'..PlayerName..'"')
7644
7778
  self.PlayerMenu=PlayerMenu
7645
7779
  self:T(string.format("Setting menu for player %s",tostring(PlayerName)))
@@ -9064,7 +9198,7 @@ local FoundUnit=UNIT:FindByName(UnitObject:getName())
9064
9198
  if FoundUnit then
9065
9199
  SetUnit:AddUnit(FoundUnit)
9066
9200
  else
9067
- local FoundStatic=STATIC:FindByName(UnitObject:getName())
9201
+ local FoundStatic=STATIC:FindByName(UnitObject:getName(),false)
9068
9202
  if FoundStatic then
9069
9203
  SetUnit:AddUnit(FoundStatic)
9070
9204
  end
@@ -10679,6 +10813,7 @@ self:HandleEvent(EVENTS.PlayerEnterUnit,self._EventOnPlayerEnterUnit)
10679
10813
  self:HandleEvent(EVENTS.Dead,self._EventOnDeadOrCrash)
10680
10814
  self:HandleEvent(EVENTS.Crash,self._EventOnDeadOrCrash)
10681
10815
  self:HandleEvent(EVENTS.RemoveUnit,self._EventOnDeadOrCrash)
10816
+ self:HandleEvent(EVENTS.UnitLost,self._EventOnDeadOrCrash)
10682
10817
  self:HandleEvent(EVENTS.Hit,self.AccountHits)
10683
10818
  self:HandleEvent(EVENTS.NewCargo)
10684
10819
  self:HandleEvent(EVENTS.DeleteCargo)
@@ -10696,14 +10831,15 @@ function DATABASE:FindUnit(UnitName)
10696
10831
  local UnitFound=self.UNITS[UnitName]
10697
10832
  return UnitFound
10698
10833
  end
10699
- function DATABASE:AddUnit(DCSUnitName)
10700
- if not self.UNITS[DCSUnitName]then
10834
+ function DATABASE:AddUnit(DCSUnitName,force)
10835
+ if not self.UNITS[DCSUnitName]or force==true then
10701
10836
  self:T({"Add UNIT:",DCSUnitName})
10702
10837
  self.UNITS[DCSUnitName]=UNIT:Register(DCSUnitName)
10703
10838
  end
10704
10839
  return self.UNITS[DCSUnitName]
10705
10840
  end
10706
10841
  function DATABASE:DeleteUnit(DCSUnitName)
10842
+ self:T("DeleteUnit "..tostring(DCSUnitName))
10707
10843
  self.UNITS[DCSUnitName]=nil
10708
10844
  end
10709
10845
  function DATABASE:AddStatic(DCSStaticName)
@@ -10987,18 +11123,22 @@ function DATABASE:FindClient(ClientName)
10987
11123
  local ClientFound=self.CLIENTS[ClientName]
10988
11124
  return ClientFound
10989
11125
  end
10990
- function DATABASE:AddClient(ClientName)
10991
- if not self.CLIENTS[ClientName]then
11126
+ function DATABASE:AddClient(ClientName,Force)
11127
+ if not self.CLIENTS[ClientName]or Force==true then
10992
11128
  self.CLIENTS[ClientName]=CLIENT:Register(ClientName)
10993
11129
  end
10994
11130
  return self.CLIENTS[ClientName]
10995
11131
  end
10996
11132
  function DATABASE:FindGroup(GroupName)
10997
11133
  local GroupFound=self.GROUPS[GroupName]
11134
+ if GroupFound==nil and GroupName~=nil and self.Templates.Groups[GroupName]==nil then
11135
+ self:_RegisterDynamicGroup(GroupName)
11136
+ return self.GROUPS[GroupName]
11137
+ end
10998
11138
  return GroupFound
10999
11139
  end
11000
- function DATABASE:AddGroup(GroupName)
11001
- if not self.GROUPS[GroupName]then
11140
+ function DATABASE:AddGroup(GroupName,force)
11141
+ if not self.GROUPS[GroupName]or force==true then
11002
11142
  self:T({"Add GROUP:",GroupName})
11003
11143
  self.GROUPS[GroupName]=GROUP:Register(GroupName)
11004
11144
  end
@@ -11191,10 +11331,13 @@ end
11191
11331
  return nextoctal
11192
11332
  end
11193
11333
  function DATABASE:GetGroupTemplate(GroupName)
11194
- local GroupTemplate=self.Templates.Groups[GroupName].Template
11334
+ local GroupTemplate=nil
11335
+ if self.Templates.Groups[GroupName]then
11336
+ GroupTemplate=self.Templates.Groups[GroupName].Template
11195
11337
  GroupTemplate.SpawnCoalitionID=self.Templates.Groups[GroupName].CoalitionID
11196
11338
  GroupTemplate.SpawnCategoryID=self.Templates.Groups[GroupName].CategoryID
11197
11339
  GroupTemplate.SpawnCountryID=self.Templates.Groups[GroupName].CountryID
11340
+ end
11198
11341
  return GroupTemplate
11199
11342
  end
11200
11343
  function DATABASE:_RegisterStaticTemplate(StaticTemplate,CoalitionID,CategoryID,CountryID)
@@ -11220,6 +11363,34 @@ Country=self.Templates.Statics[StaticTemplateName].CountryID
11220
11363
  self:AddStatic(StaticTemplateName)
11221
11364
  return self
11222
11365
  end
11366
+ function DATABASE:_GetGenericStaticCargoGroupTemplate(Name,Typename,Mass,Coalition,Country)
11367
+ local StaticTemplate={}
11368
+ StaticTemplate.name=Name or"None"
11369
+ StaticTemplate.units={[1]={
11370
+ name=Name,
11371
+ resourcePayload={
11372
+ ["weapons"]={},
11373
+ ["aircrafts"]={},
11374
+ ["gasoline"]=0,
11375
+ ["diesel"]=0,
11376
+ ["methanol_mixture"]=0,
11377
+ ["jet_fuel"]=0,
11378
+ },
11379
+ ["mass"]=Mass or 0,
11380
+ ["category"]="Cargos",
11381
+ ["canCargo"]=true,
11382
+ ["type"]=Typename or"container_cargo",
11383
+ ["rate"]=100,
11384
+ ["y"]=0,
11385
+ ["x"]=0,
11386
+ ["heading"]=0,
11387
+ }}
11388
+ StaticTemplate.CategoryID="static"
11389
+ StaticTemplate.CoalitionID=Coalition or coalition.side.BLUE
11390
+ StaticTemplate.CountryID=Country or country.id.GERMANY
11391
+ UTILS.PrintTableToLog(StaticTemplate)
11392
+ return StaticTemplate
11393
+ end
11223
11394
  function DATABASE:GetStaticGroupTemplate(StaticName)
11224
11395
  if self.Templates.Statics[StaticName]then
11225
11396
  local StaticTemplate=self.Templates.Statics[StaticName].GroupTemplate
@@ -11263,14 +11434,26 @@ return nil
11263
11434
  end
11264
11435
  end
11265
11436
  function DATABASE:GetCoalitionFromClientTemplate(ClientName)
11437
+ if self.Templates.ClientsByName[ClientName]then
11266
11438
  return self.Templates.ClientsByName[ClientName].CoalitionID
11267
11439
  end
11440
+ self:E("ERROR: Template does not exist for client "..tostring(ClientName))
11441
+ return nil
11442
+ end
11268
11443
  function DATABASE:GetCategoryFromClientTemplate(ClientName)
11444
+ if self.Templates.ClientsByName[ClientName]then
11269
11445
  return self.Templates.ClientsByName[ClientName].CategoryID
11270
11446
  end
11447
+ self:E("ERROR: Template does not exist for client "..tostring(ClientName))
11448
+ return nil
11449
+ end
11271
11450
  function DATABASE:GetCountryFromClientTemplate(ClientName)
11451
+ if self.Templates.ClientsByName[ClientName]then
11272
11452
  return self.Templates.ClientsByName[ClientName].CountryID
11273
11453
  end
11454
+ self:E("ERROR: Template does not exist for client "..tostring(ClientName))
11455
+ return nil
11456
+ end
11274
11457
  function DATABASE:GetCoalitionFromAirbase(AirbaseName)
11275
11458
  return self.AIRBASES[AirbaseName]:GetCoalition()
11276
11459
  end
@@ -11294,6 +11477,22 @@ end
11294
11477
  end
11295
11478
  return self
11296
11479
  end
11480
+ function DATABASE:_RegisterDynamicGroup(Groupname)
11481
+ local DCSGroup=Group.getByName(Groupname)
11482
+ if DCSGroup and DCSGroup:isExist()then
11483
+ local DCSGroupName=DCSGroup:getName()
11484
+ self:I(string.format("Register Group: %s",tostring(DCSGroupName)))
11485
+ self:AddGroup(DCSGroupName,true)
11486
+ for DCSUnitId,DCSUnit in pairs(DCSGroup:getUnits())do
11487
+ local DCSUnitName=DCSUnit:getName()
11488
+ self:I(string.format("Register Unit: %s",tostring(DCSUnitName)))
11489
+ self:AddUnit(DCSUnitName,true)
11490
+ end
11491
+ else
11492
+ self:E({"Group does not exist: ",DCSGroup})
11493
+ end
11494
+ return self
11495
+ end
11297
11496
  function DATABASE:_RegisterGroupsAndUnits()
11298
11497
  local CoalitionsData={GroupsRed=coalition.getGroups(coalition.side.RED),GroupsBlue=coalition.getGroups(coalition.side.BLUE),GroupsNeutral=coalition.getGroups(coalition.side.NEUTRAL)}
11299
11498
  for CoalitionId,CoalitionData in pairs(CoalitionsData)do
@@ -11382,24 +11581,27 @@ end
11382
11581
  end
11383
11582
  end
11384
11583
  if Event.IniObjectCategory==Object.Category.UNIT then
11385
- Event.IniUnit=self:FindUnit(Event.IniDCSUnitName)
11386
11584
  Event.IniGroup=self:FindGroup(Event.IniDCSGroupName)
11585
+ Event.IniUnit=self:FindUnit(Event.IniDCSUnitName)
11387
11586
  local client=self.CLIENTS[Event.IniDCSUnitName]
11388
11587
  if client then
11389
11588
  end
11390
11589
  local PlayerName=Event.IniUnit:GetPlayerName()
11391
11590
  if PlayerName then
11392
11591
  self:I(string.format("Player '%s' joined unit '%s' of group '%s'",tostring(PlayerName),tostring(Event.IniDCSUnitName),tostring(Event.IniDCSGroupName)))
11393
- if not client then
11394
- client=self:AddClient(Event.IniDCSUnitName)
11592
+ if client==nil or(client and client:CountPlayers()==0)then
11593
+ client=self:AddClient(Event.IniDCSUnitName,true)
11395
11594
  end
11396
11595
  client:AddPlayer(PlayerName)
11397
11596
  if not self.PLAYERS[PlayerName]then
11398
11597
  self:AddPlayer(Event.IniUnitName,PlayerName)
11399
11598
  end
11599
+ local function SetPlayerSettings(self,PlayerName,IniUnit)
11400
11600
  local Settings=SETTINGS:Set(PlayerName)
11401
- Settings:SetPlayerMenu(Event.IniUnit)
11402
- self:CreateEventPlayerEnterAircraft(Event.IniUnit)
11601
+ Settings:SetPlayerMenu(IniUnit)
11602
+ self:CreateEventPlayerEnterAircraft(IniUnit)
11603
+ end
11604
+ self:ScheduleOnce(1,SetPlayerSettings,self,PlayerName,Event.IniUnit)
11403
11605
  end
11404
11606
  end
11405
11607
  end
@@ -11422,7 +11624,7 @@ end
11422
11624
  else
11423
11625
  if Event.IniObjectCategory==1 then
11424
11626
  if self.UNITS[Event.IniDCSUnitName]then
11425
- self:DeleteUnit(Event.IniDCSUnitName)
11627
+ self:ScheduleOnce(1,self.DeleteUnit,self,Event.IniDCSUnitName)
11426
11628
  end
11427
11629
  local client=self.CLIENTS[name]
11428
11630
  if client then
@@ -12378,6 +12580,7 @@ self:HandleEvent(EVENTS.Birth,self._EventOnBirth)
12378
12580
  self:HandleEvent(EVENTS.Dead,self._EventOnDeadOrCrash)
12379
12581
  self:HandleEvent(EVENTS.Crash,self._EventOnDeadOrCrash)
12380
12582
  self:HandleEvent(EVENTS.RemoveUnit,self._EventOnDeadOrCrash)
12583
+ self:HandleEvent(EVENTS.UnitLost,self._EventOnDeadOrCrash)
12381
12584
  self:HandleEvent(EVENTS.PlayerLeaveUnit,self._EventOnDeadOrCrash)
12382
12585
  if self.Filter.Zones then
12383
12586
  self.ZoneTimer=TIMER:New(self._ContinousZoneFilter,self)
@@ -12397,6 +12600,7 @@ self:UnHandleEvent(EVENTS.Birth)
12397
12600
  self:UnHandleEvent(EVENTS.Dead)
12398
12601
  self:UnHandleEvent(EVENTS.Crash)
12399
12602
  self:UnHandleEvent(EVENTS.RemoveUnit)
12603
+ self:UnHandleEvent(EVENTS.UnitLost)
12400
12604
  if self.Filter.Zones and self.ZoneTimer and self.ZoneTimer:IsRunning()then
12401
12605
  self.ZoneTimer:Stop()
12402
12606
  end
@@ -12687,14 +12891,17 @@ local gmin=nil
12687
12891
  for GroupID,GroupData in pairs(Set)do
12688
12892
  local group=GroupData
12689
12893
  if group and group:IsAlive()and(Coalitions==nil or UTILS.IsAnyInTable(Coalitions,group:GetCoalition()))then
12690
- local coord=group:GetCoord()
12691
- local d=UTILS.VecDist3D(Coordinate,coord)
12894
+ local coord=group:GetCoordinate()
12895
+ local d
12896
+ if coord~=nil then
12897
+ d=UTILS.VecDist3D(Coordinate,coord)
12692
12898
  if d<dmin then
12693
12899
  dmin=d
12694
12900
  gmin=group
12695
12901
  end
12696
12902
  end
12697
12903
  end
12904
+ end
12698
12905
  return gmin,dmin
12699
12906
  end
12700
12907
  function SET_GROUP:SetCargoBayWeightLimit()
@@ -12848,6 +13055,18 @@ Active=Active or not(Active==false)
12848
13055
  self.Filter.Active=Active
12849
13056
  return self
12850
13057
  end
13058
+ function SET_UNIT:FilterAlive()
13059
+ self:FilterFunction(
13060
+ function(unit)
13061
+ if unit and unit:IsExist()and unit:IsAlive()then
13062
+ return true
13063
+ else
13064
+ return false
13065
+ end
13066
+ end
13067
+ )
13068
+ return self
13069
+ end
12851
13070
  function SET_UNIT:FilterHasRadar(RadarTypes)
12852
13071
  self.Filter.RadarTypes=self.Filter.RadarTypes or{}
12853
13072
  if type(RadarTypes)~="table"then
@@ -12916,6 +13135,7 @@ self:HandleEvent(EVENTS.Birth,self._EventOnBirth)
12916
13135
  self:HandleEvent(EVENTS.Dead,self._EventOnDeadOrCrash)
12917
13136
  self:HandleEvent(EVENTS.Crash,self._EventOnDeadOrCrash)
12918
13137
  self:HandleEvent(EVENTS.RemoveUnit,self._EventOnDeadOrCrash)
13138
+ self:HandleEvent(EVENTS.UnitLost,self._EventOnDeadOrCrash)
12919
13139
  if self.Filter.Zones then
12920
13140
  self.ZoneTimer=TIMER:New(self._ContinousZoneFilter,self)
12921
13141
  local timing=self.ZoneTimerInterval or 30
@@ -13942,6 +14162,18 @@ Active=Active or not(Active==false)
13942
14162
  self.Filter.Active=Active
13943
14163
  return self
13944
14164
  end
14165
+ function SET_CLIENT:FilterAlive()
14166
+ self:FilterFunction(
14167
+ function(unit)
14168
+ if unit and unit:IsExist()and unit:IsAlive()then
14169
+ return true
14170
+ else
14171
+ return false
14172
+ end
14173
+ end
14174
+ )
14175
+ return self
14176
+ end
13945
14177
  function SET_CLIENT:FilterZones(Zones)
13946
14178
  if not self.Filter.Zones then
13947
14179
  self.Filter.Zones={}
@@ -14099,8 +14331,11 @@ if self.Filter.Coalitions and MClientInclude then
14099
14331
  local MClientCoalition=false
14100
14332
  for CoalitionID,CoalitionName in pairs(self.Filter.Coalitions)do
14101
14333
  local ClientCoalitionID=_DATABASE:GetCoalitionFromClientTemplate(MClientName)
14334
+ if ClientCoalitionID==nil and MClient:IsAlive()~=nil then
14335
+ ClientCoalitionID=MClient:GetCoalition()
14336
+ end
14102
14337
  self:T3({"Coalition:",ClientCoalitionID,self.FilterMeta.Coalitions[CoalitionName],CoalitionName})
14103
- if self.FilterMeta.Coalitions[CoalitionName]and self.FilterMeta.Coalitions[CoalitionName]==ClientCoalitionID then
14338
+ if self.FilterMeta.Coalitions[CoalitionName]and ClientCoalitionID and self.FilterMeta.Coalitions[CoalitionName]==ClientCoalitionID then
14104
14339
  MClientCoalition=true
14105
14340
  end
14106
14341
  end
@@ -14111,11 +14346,20 @@ if self.Filter.Categories and MClientInclude then
14111
14346
  local MClientCategory=false
14112
14347
  for CategoryID,CategoryName in pairs(self.Filter.Categories)do
14113
14348
  local ClientCategoryID=_DATABASE:GetCategoryFromClientTemplate(MClientName)
14349
+ local UnitCategory=0
14350
+ if ClientCategoryID==nil and MClient:IsExist()then
14351
+ ClientCategoryID,UnitCategory=MClient:GetCategory()
14352
+ self:T3({"Category:",UnitCategory,self.FilterMeta.Categories[CategoryName],CategoryName})
14353
+ if self.FilterMeta.Categories[CategoryName]and UnitCategory and self.FilterMeta.Categories[CategoryName]==UnitCategory then
14354
+ MClientCategory=true
14355
+ end
14356
+ else
14114
14357
  self:T3({"Category:",ClientCategoryID,self.FilterMeta.Categories[CategoryName],CategoryName})
14115
- if self.FilterMeta.Categories[CategoryName]and self.FilterMeta.Categories[CategoryName]==ClientCategoryID then
14358
+ if self.FilterMeta.Categories[CategoryName]and ClientCategoryID and self.FilterMeta.Categories[CategoryName]==ClientCategoryID then
14116
14359
  MClientCategory=true
14117
14360
  end
14118
14361
  end
14362
+ end
14119
14363
  self:T({"Evaluated Category",MClientCategory})
14120
14364
  MClientInclude=MClientInclude and MClientCategory
14121
14365
  end
@@ -14134,8 +14378,11 @@ if self.Filter.Countries and MClientInclude then
14134
14378
  local MClientCountry=false
14135
14379
  for CountryID,CountryName in pairs(self.Filter.Countries)do
14136
14380
  local ClientCountryID=_DATABASE:GetCountryFromClientTemplate(MClientName)
14381
+ if ClientCountryID==nil and MClient:IsAlive()~=nil then
14382
+ ClientCountryID=MClient:GetCountry()
14383
+ end
14137
14384
  self:T3({"Country:",ClientCountryID,country.id[CountryName],CountryName})
14138
- if country.id[CountryName]and country.id[CountryName]==ClientCountryID then
14385
+ if country.id[CountryName]and ClientCountryID and country.id[CountryName]==ClientCountryID then
14139
14386
  MClientCountry=true
14140
14387
  end
14141
14388
  end
@@ -14374,27 +14621,39 @@ self:F2(MClient)
14374
14621
  local MClientInclude=true
14375
14622
  if MClient then
14376
14623
  local MClientName=MClient.UnitName
14377
- if self.Filter.Coalitions then
14624
+ if self.Filter.Coalitions and MClientInclude then
14378
14625
  local MClientCoalition=false
14379
14626
  for CoalitionID,CoalitionName in pairs(self.Filter.Coalitions)do
14380
14627
  local ClientCoalitionID=_DATABASE:GetCoalitionFromClientTemplate(MClientName)
14628
+ if ClientCoalitionID==nil and MClient:IsAlive()~=nil then
14629
+ ClientCoalitionID=MClient:GetCoalition()
14630
+ end
14381
14631
  self:T3({"Coalition:",ClientCoalitionID,self.FilterMeta.Coalitions[CoalitionName],CoalitionName})
14382
- if self.FilterMeta.Coalitions[CoalitionName]and self.FilterMeta.Coalitions[CoalitionName]==ClientCoalitionID then
14632
+ if self.FilterMeta.Coalitions[CoalitionName]and ClientCoalitionID and self.FilterMeta.Coalitions[CoalitionName]==ClientCoalitionID then
14383
14633
  MClientCoalition=true
14384
14634
  end
14385
14635
  end
14386
14636
  self:T({"Evaluated Coalition",MClientCoalition})
14387
14637
  MClientInclude=MClientInclude and MClientCoalition
14388
14638
  end
14389
- if self.Filter.Categories then
14639
+ if self.Filter.Categories and MClientInclude then
14390
14640
  local MClientCategory=false
14391
14641
  for CategoryID,CategoryName in pairs(self.Filter.Categories)do
14392
14642
  local ClientCategoryID=_DATABASE:GetCategoryFromClientTemplate(MClientName)
14643
+ local UnitCategory=0
14644
+ if ClientCategoryID==nil and MClient:IsExist()then
14645
+ ClientCategoryID,UnitCategory=MClient:GetCategory()
14646
+ self:T3({"Category:",UnitCategory,self.FilterMeta.Categories[CategoryName],CategoryName})
14647
+ if self.FilterMeta.Categories[CategoryName]and UnitCategory and self.FilterMeta.Categories[CategoryName]==UnitCategory then
14648
+ MClientCategory=true
14649
+ end
14650
+ else
14393
14651
  self:T3({"Category:",ClientCategoryID,self.FilterMeta.Categories[CategoryName],CategoryName})
14394
- if self.FilterMeta.Categories[CategoryName]and self.FilterMeta.Categories[CategoryName]==ClientCategoryID then
14652
+ if self.FilterMeta.Categories[CategoryName]and ClientCategoryID and self.FilterMeta.Categories[CategoryName]==ClientCategoryID then
14395
14653
  MClientCategory=true
14396
14654
  end
14397
14655
  end
14656
+ end
14398
14657
  self:T({"Evaluated Category",MClientCategory})
14399
14658
  MClientInclude=MClientInclude and MClientCategory
14400
14659
  end
@@ -15633,6 +15892,7 @@ self:HandleEvent(EVENTS.Birth,self._EventOnBirth)
15633
15892
  self:HandleEvent(EVENTS.Dead,self._EventOnDeadOrCrash)
15634
15893
  self:HandleEvent(EVENTS.Crash,self._EventOnDeadOrCrash)
15635
15894
  self:HandleEvent(EVENTS.RemoveUnit,self._EventOnDeadOrCrash)
15895
+ self:HandleEvent(EVENTS.UnitLost,self._EventOnDeadOrCrash)
15636
15896
  end
15637
15897
  return self
15638
15898
  end
@@ -17219,6 +17479,8 @@ local Latitude,Longitude=self:GetLLDDM()
17219
17479
  local Tdiff=UTILS.GMTToLocalTimeDifference()
17220
17480
  local sunrise=UTILS.GetSunRiseAndSet(DayOfYear,Latitude,Longitude,true,Tdiff)
17221
17481
  local sunset=UTILS.GetSunRiseAndSet(DayOfYear,Latitude,Longitude,false,Tdiff)
17482
+ if sunrise=="N/R"then return false end
17483
+ if sunrise=="N/S"then return true end
17222
17484
  local time=UTILS.ClockToSeconds(clock)
17223
17485
  if time>sunrise and time<=sunset then
17224
17486
  return true
@@ -17890,19 +18152,7 @@ return self
17890
18152
  end
17891
18153
  function MESSAGE:ToClient(Client,Settings)
17892
18154
  self:F(Client)
17893
- if Client and Client:GetClientGroupID()then
17894
- if self.MessageType then
17895
- local Settings=Settings or(Client and _DATABASE:GetPlayerSettings(Client:GetPlayerName()))or _SETTINGS
17896
- self.MessageDuration=Settings:GetMessageTime(self.MessageType)
17897
- self.MessageCategory=""
17898
- end
17899
- local Unit=Client:GetClient()
17900
- if self.MessageDuration~=0 then
17901
- local ClientGroupID=Client:GetClientGroupID()
17902
- self:T(self.MessageCategory..self.MessageText:gsub("\n$",""):gsub("\n$","").." / "..self.MessageDuration)
17903
- trigger.action.outTextForUnit(Unit:GetID(),self.MessageCategory..self.MessageText:gsub("\n$",""):gsub("\n$",""),self.MessageDuration,self.ClearScreen)
17904
- end
17905
- end
18155
+ self:ToUnit(Client,Settings)
17906
18156
  return self
17907
18157
  end
17908
18158
  function MESSAGE:ToGroup(Group,Settings)
@@ -18598,7 +18848,6 @@ Cold=4,
18598
18848
  }
18599
18849
  function SPAWN:New(SpawnTemplatePrefix)
18600
18850
  local self=BASE:Inherit(self,BASE:New())
18601
- self:F({SpawnTemplatePrefix})
18602
18851
  local TemplateGroup=GROUP:FindByName(SpawnTemplatePrefix)
18603
18852
  if TemplateGroup then
18604
18853
  self.SpawnTemplatePrefix=SpawnTemplatePrefix
@@ -18640,7 +18889,6 @@ return self
18640
18889
  end
18641
18890
  function SPAWN:NewWithAlias(SpawnTemplatePrefix,SpawnAliasPrefix)
18642
18891
  local self=BASE:Inherit(self,BASE:New())
18643
- self:F({SpawnTemplatePrefix,SpawnAliasPrefix})
18644
18892
  local TemplateGroup=GROUP:FindByName(SpawnTemplatePrefix)
18645
18893
  if TemplateGroup then
18646
18894
  self.SpawnTemplatePrefix=SpawnTemplatePrefix
@@ -18682,7 +18930,6 @@ return self
18682
18930
  end
18683
18931
  function SPAWN:NewFromTemplate(SpawnTemplate,SpawnTemplatePrefix,SpawnAliasPrefix,NoMooseNamingPostfix)
18684
18932
  local self=BASE:Inherit(self,BASE:New())
18685
- self:F({SpawnTemplate,SpawnTemplatePrefix,SpawnAliasPrefix})
18686
18933
  if SpawnTemplatePrefix==nil or SpawnTemplatePrefix==""then
18687
18934
  BASE:I("ERROR: in function NewFromTemplate, required parameter SpawnTemplatePrefix is not set")
18688
18935
  return nil
@@ -18731,7 +18978,6 @@ self.SpawnHookScheduler=SCHEDULER:New(nil)
18731
18978
  return self
18732
18979
  end
18733
18980
  function SPAWN:InitLimit(SpawnMaxUnitsAlive,SpawnMaxGroups)
18734
- self:F({self.SpawnTemplatePrefix,SpawnMaxUnitsAlive,SpawnMaxGroups})
18735
18981
  self.SpawnInitLimit=true
18736
18982
  self.SpawnMaxUnitsAlive=SpawnMaxUnitsAlive
18737
18983
  self.SpawnMaxGroups=SpawnMaxGroups
@@ -18741,25 +18987,21 @@ end
18741
18987
  return self
18742
18988
  end
18743
18989
  function SPAWN:InitKeepUnitNames(KeepUnitNames)
18744
- self:F()
18745
18990
  self.SpawnInitKeepUnitNames=false
18746
18991
  if KeepUnitNames==true then self.SpawnInitKeepUnitNames=true end
18747
18992
  return self
18748
18993
  end
18749
18994
  function SPAWN:InitLateActivated(LateActivated)
18750
- self:F()
18751
18995
  self.LateActivated=LateActivated or true
18752
18996
  return self
18753
18997
  end
18754
18998
  function SPAWN:InitAirbase(AirbaseName,Takeoff,TerminalType)
18755
- self:F()
18756
18999
  self.SpawnInitAirbase=AIRBASE:FindByName(AirbaseName)
18757
19000
  self.SpawnInitTakeoff=Takeoff or SPAWN.Takeoff.Hot
18758
19001
  self.SpawnInitTerminalType=TerminalType
18759
19002
  return self
18760
19003
  end
18761
19004
  function SPAWN:InitHeading(HeadingMin,HeadingMax)
18762
- self:F()
18763
19005
  self.SpawnInitHeadingMin=HeadingMin
18764
19006
  self.SpawnInitHeadingMax=HeadingMax
18765
19007
  return self
@@ -18777,22 +19019,18 @@ self.SpawnInitCoalition=Coalition
18777
19019
  return self
18778
19020
  end
18779
19021
  function SPAWN:InitCountry(Country)
18780
- self:F()
18781
19022
  self.SpawnInitCountry=Country
18782
19023
  return self
18783
19024
  end
18784
19025
  function SPAWN:InitCategory(Category)
18785
- self:F()
18786
19026
  self.SpawnInitCategory=Category
18787
19027
  return self
18788
19028
  end
18789
19029
  function SPAWN:InitLivery(Livery)
18790
- self:F({livery=Livery})
18791
19030
  self.SpawnInitLivery=Livery
18792
19031
  return self
18793
19032
  end
18794
19033
  function SPAWN:InitSkill(Skill)
18795
- self:F({skill=Skill})
18796
19034
  if Skill:lower()=="average"then
18797
19035
  self.SpawnInitSkill="Average"
18798
19036
  elseif Skill:lower()=="good"then
@@ -18807,7 +19045,6 @@ end
18807
19045
  return self
18808
19046
  end
18809
19047
  function SPAWN:InitSTN(Octal)
18810
- self:F({Octal=Octal})
18811
19048
  self.SpawnInitSTN=Octal or 77777
18812
19049
  local num=UTILS.OctalToDecimal(Octal)
18813
19050
  if num==nil or num<1 then
@@ -18820,7 +19057,6 @@ end
18820
19057
  return self
18821
19058
  end
18822
19059
  function SPAWN:InitSADL(Octal)
18823
- self:F({Octal=Octal})
18824
19060
  self.SpawnInitSADL=Octal or 7777
18825
19061
  local num=UTILS.OctalToDecimal(Octal)
18826
19062
  if num==nil or num<1 then
@@ -18833,7 +19069,6 @@ end
18833
19069
  return self
18834
19070
  end
18835
19071
  function SPAWN:InitSpeedMps(MPS)
18836
- self:F({MPS=MPS})
18837
19072
  if MPS==nil or tonumber(MPS)<0 then
18838
19073
  MPS=125
18839
19074
  end
@@ -18841,7 +19076,6 @@ self.InitSpeed=MPS
18841
19076
  return self
18842
19077
  end
18843
19078
  function SPAWN:InitSpeedKnots(Knots)
18844
- self:F({Knots=Knots})
18845
19079
  if Knots==nil or tonumber(Knots)<0 then
18846
19080
  Knots=300
18847
19081
  end
@@ -18849,7 +19083,6 @@ self.InitSpeed=UTILS.KnotsToMps(Knots)
18849
19083
  return self
18850
19084
  end
18851
19085
  function SPAWN:InitSpeedKph(KPH)
18852
- self:F({KPH=KPH})
18853
19086
  if KPH==nil or tonumber(KPH)<0 then
18854
19087
  KPH=UTILS.KnotsToKmph(300)
18855
19088
  end
@@ -18857,17 +19090,14 @@ self.InitSpeed=UTILS.KmphToMps(KPH)
18857
19090
  return self
18858
19091
  end
18859
19092
  function SPAWN:InitRadioCommsOnOff(switch)
18860
- self:F({switch=switch})
18861
19093
  self.SpawnInitRadio=switch or true
18862
19094
  return self
18863
19095
  end
18864
19096
  function SPAWN:InitRadioFrequency(frequency)
18865
- self:F({frequency=frequency})
18866
19097
  self.SpawnInitFreq=frequency
18867
19098
  return self
18868
19099
  end
18869
19100
  function SPAWN:InitRadioModulation(modulation)
18870
- self:F({modulation=modulation})
18871
19101
  if modulation and modulation:lower()=="fm"then
18872
19102
  self.SpawnInitModu=radio.modulation.FM
18873
19103
  else
@@ -18884,7 +19114,6 @@ self.SpawnInitModexPostfix=postfix
18884
19114
  return self
18885
19115
  end
18886
19116
  function SPAWN:InitRandomizeRoute(SpawnStartPoint,SpawnEndPoint,SpawnRadius,SpawnHeight)
18887
- self:F({self.SpawnTemplatePrefix,SpawnStartPoint,SpawnEndPoint,SpawnRadius,SpawnHeight})
18888
19117
  self.SpawnRandomizeRoute=true
18889
19118
  self.SpawnRandomizeRouteStartPoint=SpawnStartPoint
18890
19119
  self.SpawnRandomizeRouteEndPoint=SpawnEndPoint
@@ -18896,7 +19125,6 @@ end
18896
19125
  return self
18897
19126
  end
18898
19127
  function SPAWN:InitRandomizePosition(RandomizePosition,OuterRadius,InnerRadius)
18899
- self:F({self.SpawnTemplatePrefix,RandomizePosition,OuterRadius,InnerRadius})
18900
19128
  self.SpawnRandomizePosition=RandomizePosition or false
18901
19129
  self.SpawnRandomizePositionOuterRadius=OuterRadius or 0
18902
19130
  self.SpawnRandomizePositionInnerRadius=InnerRadius or 0
@@ -18906,7 +19134,6 @@ end
18906
19134
  return self
18907
19135
  end
18908
19136
  function SPAWN:InitRandomizeUnits(RandomizeUnits,OuterRadius,InnerRadius)
18909
- self:F({self.SpawnTemplatePrefix,RandomizeUnits,OuterRadius,InnerRadius})
18910
19137
  self.SpawnRandomizeUnits=RandomizeUnits or false
18911
19138
  self.SpawnOuterRadius=OuterRadius or 0
18912
19139
  self.SpawnInnerRadius=InnerRadius or 0
@@ -18916,19 +19143,16 @@ end
18916
19143
  return self
18917
19144
  end
18918
19145
  function SPAWN:InitSetUnitRelativePositions(Positions)
18919
- self:F({self.SpawnTemplatePrefix,Positions})
18920
19146
  self.SpawnUnitsWithRelativePositions=true
18921
19147
  self.UnitsRelativePositions=Positions
18922
19148
  return self
18923
19149
  end
18924
19150
  function SPAWN:InitSetUnitAbsolutePositions(Positions)
18925
- self:F({self.SpawnTemplatePrefix,Positions})
18926
19151
  self.SpawnUnitsWithAbsolutePositions=true
18927
19152
  self.UnitsAbsolutePositions=Positions
18928
19153
  return self
18929
19154
  end
18930
19155
  function SPAWN:InitRandomizeTemplate(SpawnTemplatePrefixTable)
18931
- self:F({self.SpawnTemplatePrefix,SpawnTemplatePrefixTable})
18932
19156
  local temptable={}
18933
19157
  for _,_temp in pairs(SpawnTemplatePrefixTable)do
18934
19158
  temptable[#temptable+1]=_temp
@@ -18941,24 +19165,20 @@ end
18941
19165
  return self
18942
19166
  end
18943
19167
  function SPAWN:InitRandomizeTemplateSet(SpawnTemplateSet)
18944
- self:F({self.SpawnTemplatePrefix})
18945
19168
  local setnames=SpawnTemplateSet:GetSetNames()
18946
19169
  self:InitRandomizeTemplate(setnames)
18947
19170
  return self
18948
19171
  end
18949
19172
  function SPAWN:InitRandomizeTemplatePrefixes(SpawnTemplatePrefixes)
18950
- self:F({self.SpawnTemplatePrefix})
18951
19173
  local SpawnTemplateSet=SET_GROUP:New():FilterPrefixes(SpawnTemplatePrefixes):FilterOnce()
18952
19174
  self:InitRandomizeTemplateSet(SpawnTemplateSet)
18953
19175
  return self
18954
19176
  end
18955
19177
  function SPAWN:InitGrouping(Grouping)
18956
- self:F({self.SpawnTemplatePrefix,Grouping})
18957
19178
  self.SpawnGrouping=Grouping
18958
19179
  return self
18959
19180
  end
18960
19181
  function SPAWN:InitRandomizeZones(SpawnZoneTable)
18961
- self:F({self.SpawnTemplatePrefix,SpawnZoneTable})
18962
19182
  local temptable={}
18963
19183
  for _,_temp in pairs(SpawnZoneTable)do
18964
19184
  temptable[#temptable+1]=_temp
@@ -18984,59 +19204,54 @@ self.SpawnInitCallSignName=string.lower(Name):gsub("^%l",string.upper)
18984
19204
  return self
18985
19205
  end
18986
19206
  function SPAWN:InitPositionCoordinate(Coordinate)
18987
- self:T({self.SpawnTemplatePrefix,Coordinate:GetVec2()})
19207
+ self:T2({self.SpawnTemplatePrefix,Coordinate:GetVec2()})
18988
19208
  self:InitPositionVec2(Coordinate:GetVec2())
18989
19209
  return self
18990
19210
  end
18991
19211
  function SPAWN:InitPositionVec2(Vec2)
18992
- self:T({self.SpawnTemplatePrefix,Vec2})
19212
+ self:T2({self.SpawnTemplatePrefix,Vec2})
18993
19213
  self.SpawnInitPosition=Vec2
18994
19214
  self.SpawnFromNewPosition=true
18995
- self:I("MaxGroups:"..self.SpawnMaxGroups)
19215
+ self:T2("MaxGroups:"..self.SpawnMaxGroups)
18996
19216
  for SpawnGroupID=1,self.SpawnMaxGroups do
18997
19217
  self:_SetInitialPosition(SpawnGroupID)
18998
19218
  end
18999
19219
  return self
19000
19220
  end
19001
19221
  function SPAWN:InitRepeat()
19002
- self:F({self.SpawnTemplatePrefix,self.SpawnIndex})
19003
19222
  self.Repeat=true
19004
19223
  self.RepeatOnEngineShutDown=false
19005
19224
  self.RepeatOnLanding=true
19006
19225
  return self
19007
19226
  end
19008
19227
  function SPAWN:InitRepeatOnLanding()
19009
- self:F({self.SpawnTemplatePrefix})
19010
19228
  self:InitRepeat()
19011
19229
  self.RepeatOnEngineShutDown=false
19012
19230
  self.RepeatOnLanding=true
19013
19231
  return self
19014
19232
  end
19015
19233
  function SPAWN:InitRepeatOnEngineShutDown()
19016
- self:F({self.SpawnTemplatePrefix})
19017
19234
  self:InitRepeat()
19018
19235
  self.RepeatOnEngineShutDown=true
19019
19236
  self.RepeatOnLanding=false
19020
19237
  return self
19021
19238
  end
19022
19239
  function SPAWN:InitCleanUp(SpawnCleanUpInterval)
19023
- self:F({self.SpawnTemplatePrefix,SpawnCleanUpInterval})
19024
19240
  self.SpawnCleanUpInterval=SpawnCleanUpInterval
19025
19241
  self.SpawnCleanUpTimeStamps={}
19026
19242
  local SpawnGroup,SpawnCursor=self:GetFirstAliveGroup()
19027
- self:T({"CleanUp Scheduler:",SpawnGroup})
19243
+ self:T2({"CleanUp Scheduler:",SpawnGroup})
19028
19244
  self.CleanUpScheduler=SCHEDULER:New(self,self._SpawnCleanUpScheduler,{},1,SpawnCleanUpInterval,0.2)
19029
19245
  return self
19030
19246
  end
19031
19247
  function SPAWN:InitArray(SpawnAngle,SpawnWidth,SpawnDeltaX,SpawnDeltaY)
19032
- self:F({self.SpawnTemplatePrefix,SpawnAngle,SpawnWidth,SpawnDeltaX,SpawnDeltaY})
19033
19248
  self.SpawnVisible=true
19034
19249
  local SpawnX=0
19035
19250
  local SpawnY=0
19036
19251
  local SpawnXIndex=0
19037
19252
  local SpawnYIndex=0
19038
19253
  for SpawnGroupID=1,self.SpawnMaxGroups do
19039
- self:T({SpawnX,SpawnY,SpawnXIndex,SpawnYIndex})
19254
+ self:T2({SpawnX,SpawnY,SpawnXIndex,SpawnYIndex})
19040
19255
  self.SpawnGroups[SpawnGroupID].Visible=true
19041
19256
  self.SpawnGroups[SpawnGroupID].Spawned=false
19042
19257
  SpawnXIndex=SpawnXIndex+1
@@ -19053,9 +19268,9 @@ self.SpawnGroups[SpawnGroupID].SpawnTemplate.lateActivation=true
19053
19268
  self.SpawnGroups[SpawnGroupID].SpawnTemplate.visible=true
19054
19269
  self.SpawnGroups[SpawnGroupID].Visible=true
19055
19270
  self:HandleEvent(EVENTS.Birth,self._OnBirth)
19056
- self:HandleEvent(EVENTS.Dead,self._OnDeadOrCrash)
19057
19271
  self:HandleEvent(EVENTS.Crash,self._OnDeadOrCrash)
19058
19272
  self:HandleEvent(EVENTS.RemoveUnit,self._OnDeadOrCrash)
19273
+ self:HandleEvent(EVENTS.UnitLost,self._OnDeadOrCrash)
19059
19274
  if self.Repeat then
19060
19275
  self:HandleEvent(EVENTS.Takeoff,self._OnTakeOff)
19061
19276
  self:HandleEvent(EVENTS.Land,self._OnLand)
@@ -19069,6 +19284,19 @@ SpawnY=SpawnYIndex*SpawnDeltaY
19069
19284
  end
19070
19285
  return self
19071
19286
  end
19287
+ function SPAWN:StopRepeat()
19288
+ if self.Repeat then
19289
+ self:UnHandleEvent(EVENTS.Takeoff)
19290
+ self:UnHandleEvent(EVENTS.Land)
19291
+ end
19292
+ if self.RepeatOnEngineShutDown then
19293
+ self:UnHandleEvent(EVENTS.EngineShutdown)
19294
+ end
19295
+ self.Repeat=false
19296
+ self.RepeatOnEngineShutDown=false
19297
+ self.RepeatOnLanding=false
19298
+ return self
19299
+ end
19072
19300
  do
19073
19301
  function SPAWN:InitAIOnOff(AIOnOff)
19074
19302
  self.AIOnOff=AIOnOff
@@ -19093,8 +19321,8 @@ function SPAWN:InitDelayOff()
19093
19321
  return self:InitDelayOnOff(false)
19094
19322
  end
19095
19323
  end
19096
- function SPAWN:InitHiddenOnMap()
19097
- self.SpawnHiddenOnMap=true
19324
+ function SPAWN:InitHiddenOnMap(OnOff)
19325
+ self.SpawnHiddenOnMap=OnOff==false and false or true
19098
19326
  return self
19099
19327
  end
19100
19328
  function SPAWN:InitHiddenOnMFD()
@@ -19106,7 +19334,6 @@ self.SpawnHiddenOnPlanner=true
19106
19334
  return self
19107
19335
  end
19108
19336
  function SPAWN:Spawn()
19109
- self:F({self.SpawnTemplatePrefix,self.SpawnIndex,self.AliveUnits})
19110
19337
  if self.SpawnInitAirbase then
19111
19338
  return self:SpawnAtAirbase(self.SpawnInitAirbase,self.SpawnInitTakeoff,nil,self.SpawnInitTerminalType)
19112
19339
  else
@@ -19114,7 +19341,6 @@ return self:SpawnWithIndex(self.SpawnIndex+1)
19114
19341
  end
19115
19342
  end
19116
19343
  function SPAWN:ReSpawn(SpawnIndex)
19117
- self:F({self.SpawnTemplatePrefix,SpawnIndex})
19118
19344
  if not SpawnIndex then
19119
19345
  SpawnIndex=1
19120
19346
  end
@@ -19131,17 +19357,29 @@ if SpawnGroup and WayPoints then
19131
19357
  SpawnGroup:WayPointInitialize(WayPoints)
19132
19358
  SpawnGroup:WayPointExecute(1,5)
19133
19359
  end
19134
- if SpawnGroup.ReSpawnFunction then
19360
+ if SpawnGroup and SpawnGroup.ReSpawnFunction then
19135
19361
  SpawnGroup:ReSpawnFunction()
19136
19362
  end
19137
- SpawnGroup:ResetEvents()
19363
+ if SpawnGroup then SpawnGroup:ResetEvents()end
19138
19364
  return SpawnGroup
19139
19365
  end
19140
19366
  function SPAWN:SetSpawnIndex(SpawnIndex)
19141
19367
  self.SpawnIndex=SpawnIndex or 0
19142
19368
  end
19143
19369
  function SPAWN:SpawnWithIndex(SpawnIndex,NoBirth)
19144
- self:F2({SpawnTemplatePrefix=self.SpawnTemplatePrefix,SpawnIndex=SpawnIndex,AliveUnits=self.AliveUnits,SpawnMaxGroups=self.SpawnMaxGroups})
19370
+ local set=SET_GROUP:New():FilterAlive():FilterPrefixes({self.SpawnTemplatePrefix,self.SpawnAliasPrefix}):FilterOnce()
19371
+ local aliveunits=0
19372
+ set:ForEachGroupAlive(
19373
+ function(grp)
19374
+ aliveunits=aliveunits+grp:CountAliveUnits()
19375
+ end
19376
+ )
19377
+ if aliveunits~=self.AliveUnits then
19378
+ self.AliveUnits=aliveunits
19379
+ self:T2("***** self.AliveUnits accounting failure! Corrected! *****")
19380
+ end
19381
+ set=nil
19382
+ self:T2({SpawnTemplatePrefix=self.SpawnTemplatePrefix,SpawnIndex=SpawnIndex,AliveUnits=self.AliveUnits,SpawnMaxGroups=self.SpawnMaxGroups})
19145
19383
  if self:_GetSpawnIndex(SpawnIndex)then
19146
19384
  if self.SpawnFromNewPosition then
19147
19385
  self:_SetInitialPosition(SpawnIndex)
@@ -19151,10 +19389,10 @@ self.SpawnGroups[self.SpawnIndex].Group:Activate()
19151
19389
  else
19152
19390
  local SpawnTemplate=self.SpawnGroups[self.SpawnIndex].SpawnTemplate
19153
19391
  local SpawnZone=self.SpawnGroups[self.SpawnIndex].SpawnZone
19154
- self:T(SpawnTemplate.name)
19392
+ self:T2(SpawnTemplate.name)
19155
19393
  if SpawnTemplate then
19156
19394
  local PointVec3=POINT_VEC3:New(SpawnTemplate.route.points[1].x,SpawnTemplate.route.points[1].alt,SpawnTemplate.route.points[1].y)
19157
- self:T({"Current point of ",self.SpawnTemplatePrefix,PointVec3})
19395
+ self:T2({"Current point of ",self.SpawnTemplatePrefix,PointVec3})
19158
19396
  if self.SpawnRandomizePosition then
19159
19397
  local RandomVec2=PointVec3:GetRandomVec2InRadius(self.SpawnRandomizePositionOuterRadius,self.SpawnRandomizePositionInnerRadius)
19160
19398
  local CurrentX=SpawnTemplate.units[1].x
@@ -19164,7 +19402,7 @@ SpawnTemplate.y=RandomVec2.y
19164
19402
  for UnitID=1,#SpawnTemplate.units do
19165
19403
  SpawnTemplate.units[UnitID].x=SpawnTemplate.units[UnitID].x+(RandomVec2.x-CurrentX)
19166
19404
  SpawnTemplate.units[UnitID].y=SpawnTemplate.units[UnitID].y+(RandomVec2.y-CurrentY)
19167
- self:T('SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
19405
+ self:T2('SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
19168
19406
  end
19169
19407
  end
19170
19408
  if self.SpawnRandomizeUnits then
@@ -19181,13 +19419,13 @@ inZone=SpawnZone:IsVec2InZone(RandomVec2)
19181
19419
  end
19182
19420
  end
19183
19421
  if(not inZone)then
19184
- self:I("Could not place unit within zone and within radius!")
19422
+ self:T2("Could not place unit within zone and within radius!")
19185
19423
  RandomVec2=SpawnZone:GetRandomVec2()
19186
19424
  end
19187
19425
  end
19188
19426
  SpawnTemplate.units[UnitID].x=RandomVec2.x
19189
19427
  SpawnTemplate.units[UnitID].y=RandomVec2.y
19190
- self:T('SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
19428
+ self:T2('SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
19191
19429
  end
19192
19430
  end
19193
19431
  local function _Heading(courseDeg)
@@ -19302,7 +19540,7 @@ if self.SpawnHiddenOnMFD then
19302
19540
  SpawnTemplate.hiddenOnMFD=true
19303
19541
  end
19304
19542
  if self.SpawnHiddenOnMap then
19305
- SpawnTemplate.hidden=true
19543
+ SpawnTemplate.hidden=self.SpawnHiddenOnMap
19306
19544
  end
19307
19545
  SpawnTemplate.CategoryID=self.SpawnInitCategory or SpawnTemplate.CategoryID
19308
19546
  SpawnTemplate.CountryID=self.SpawnInitCountry or SpawnTemplate.CountryID
@@ -19311,8 +19549,8 @@ end
19311
19549
  if not NoBirth then
19312
19550
  self:HandleEvent(EVENTS.Birth,self._OnBirth)
19313
19551
  end
19314
- self:HandleEvent(EVENTS.Dead,self._OnDeadOrCrash)
19315
19552
  self:HandleEvent(EVENTS.Crash,self._OnDeadOrCrash)
19553
+ self:HandleEvent(EVENTS.UnitLost,self._OnDeadOrCrash)
19316
19554
  self:HandleEvent(EVENTS.RemoveUnit,self._OnDeadOrCrash)
19317
19555
  if self.Repeat then
19318
19556
  self:HandleEvent(EVENTS.Takeoff,self._OnTakeOff)
@@ -19339,7 +19577,6 @@ end
19339
19577
  return nil
19340
19578
  end
19341
19579
  function SPAWN:SpawnScheduled(SpawnTime,SpawnTimeVariation,WithDelay)
19342
- self:F({SpawnTime,SpawnTimeVariation})
19343
19580
  local SpawnTime=SpawnTime or 60
19344
19581
  local SpawnTimeVariation=SpawnTimeVariation or 0.5
19345
19582
  if SpawnTime~=nil and SpawnTimeVariation~=nil then
@@ -19352,17 +19589,14 @@ end
19352
19589
  return self
19353
19590
  end
19354
19591
  function SPAWN:SpawnScheduleStart()
19355
- self:F({self.SpawnTemplatePrefix})
19356
19592
  self.SpawnScheduler:Start()
19357
19593
  return self
19358
19594
  end
19359
19595
  function SPAWN:SpawnScheduleStop()
19360
- self:F({self.SpawnTemplatePrefix})
19361
19596
  self.SpawnScheduler:Stop()
19362
19597
  return self
19363
19598
  end
19364
19599
  function SPAWN:OnSpawnGroup(SpawnCallBackFunction,...)
19365
- self:F("OnSpawnGroup")
19366
19600
  self.SpawnFunctionHook=SpawnCallBackFunction
19367
19601
  self.SpawnFunctionArguments={}
19368
19602
  if arg then
@@ -19371,21 +19605,17 @@ end
19371
19605
  return self
19372
19606
  end
19373
19607
  function SPAWN:SpawnAtAirbase(SpawnAirbase,Takeoff,TakeoffAltitude,TerminalType,EmergencyAirSpawn,Parkingdata)
19374
- self:F({self.SpawnTemplatePrefix,SpawnAirbase,Takeoff,TakeoffAltitude,TerminalType})
19375
19608
  local PointVec3=SpawnAirbase:GetCoordinate()
19376
19609
  self:T2(PointVec3)
19377
19610
  Takeoff=Takeoff or SPAWN.Takeoff.Hot
19378
19611
  if EmergencyAirSpawn==nil then
19379
19612
  EmergencyAirSpawn=true
19380
19613
  end
19381
- self:F({SpawnIndex=self.SpawnIndex})
19382
19614
  if self:_GetSpawnIndex(self.SpawnIndex+1)then
19383
19615
  local SpawnTemplate=self.SpawnGroups[self.SpawnIndex].SpawnTemplate
19384
- self:F({SpawnTemplate=SpawnTemplate})
19385
19616
  if SpawnTemplate then
19386
19617
  local GroupAlive=self:GetGroupFromIndex(self.SpawnIndex)
19387
- self:F({GroupAlive=GroupAlive})
19388
- self:T({"Current point of ",self.SpawnTemplatePrefix,SpawnAirbase})
19618
+ self:T2({"Current point of ",self.SpawnTemplatePrefix,SpawnAirbase})
19389
19619
  local TemplateGroup=GROUP:FindByName(self.SpawnTemplatePrefix)
19390
19620
  local TemplateUnit=TemplateGroup:GetUnit(1)
19391
19621
  local group=TemplateGroup
@@ -19402,7 +19632,6 @@ SpawnPoint.helipadId=nil
19402
19632
  SpawnPoint.airdromeId=nil
19403
19633
  local AirbaseID=SpawnAirbase:GetID()
19404
19634
  local AirbaseCategory=SpawnAirbase:GetAirbaseCategory()
19405
- self:F({AirbaseCategory=AirbaseCategory})
19406
19635
  if AirbaseCategory==Airbase.Category.SHIP then
19407
19636
  SpawnPoint.linkUnit=AirbaseID
19408
19637
  SpawnPoint.helipadId=AirbaseID
@@ -19416,7 +19645,7 @@ SpawnPoint.alt=0
19416
19645
  SpawnPoint.type=GROUPTEMPLATE.Takeoff[Takeoff][1]
19417
19646
  SpawnPoint.action=GROUPTEMPLATE.Takeoff[Takeoff][2]
19418
19647
  local spawnonground=not(Takeoff==SPAWN.Takeoff.Air)
19419
- self:T({spawnonground=spawnonground,TOtype=Takeoff,TOair=Takeoff==SPAWN.Takeoff.Air})
19648
+ self:T2({spawnonground=spawnonground,TOtype=Takeoff,TOair=Takeoff==SPAWN.Takeoff.Air})
19420
19649
  local spawnonship=false
19421
19650
  local spawnonfarp=false
19422
19651
  local spawnonrunway=false
@@ -19454,43 +19683,43 @@ local scanstatics=true
19454
19683
  local scanscenery=false
19455
19684
  local verysafe=false
19456
19685
  if spawnonship or spawnonfarp or spawnonrunway then
19457
- self:T(string.format("Group %s is spawned on farp/ship/runway %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
19686
+ self:T2(string.format("Group %s is spawned on farp/ship/runway %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
19458
19687
  nfree=SpawnAirbase:GetFreeParkingSpotsNumber(termtype,true)
19459
19688
  spots=SpawnAirbase:GetFreeParkingSpotsTable(termtype,true)
19460
19689
  else
19461
19690
  if ishelo then
19462
19691
  if termtype==nil then
19463
- self:T(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.HelicopterOnly))
19692
+ self:T2(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.HelicopterOnly))
19464
19693
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.HelicopterOnly,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19465
19694
  nfree=#spots
19466
19695
  if nfree<nunits then
19467
- self:T(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.HelicopterUsable))
19696
+ self:T2(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.HelicopterUsable))
19468
19697
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.HelicopterUsable,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19469
19698
  nfree=#spots
19470
19699
  end
19471
19700
  else
19472
- self:T(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),termtype))
19701
+ self:T2(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),termtype))
19473
19702
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,termtype,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19474
19703
  nfree=#spots
19475
19704
  end
19476
19705
  else
19477
19706
  if termtype==nil then
19478
19707
  if isbomber or istransport or istanker or isawacs then
19479
- self:T(string.format("Transport/bomber group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.OpenBig))
19708
+ self:T2(string.format("Transport/bomber group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.OpenBig))
19480
19709
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.OpenBig,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19481
19710
  nfree=#spots
19482
19711
  if nfree<nunits then
19483
- self:T(string.format("Transport/bomber group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.OpenMedOrBig))
19712
+ self:T2(string.format("Transport/bomber group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.OpenMedOrBig))
19484
19713
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.OpenMedOrBig,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19485
19714
  nfree=#spots
19486
19715
  end
19487
19716
  else
19488
- self:T(string.format("Fighter group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.FighterAircraft))
19717
+ self:T2(string.format("Fighter group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.FighterAircraft))
19489
19718
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.FighterAircraft,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19490
19719
  nfree=#spots
19491
19720
  end
19492
19721
  else
19493
- self:T(string.format("Plane group %s is at %s using terminal type %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),tostring(termtype)))
19722
+ self:T2(string.format("Plane group %s is at %s using terminal type %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),tostring(termtype)))
19494
19723
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,termtype,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19495
19724
  nfree=#spots
19496
19725
  end
@@ -19563,18 +19792,18 @@ local TX=PointVec3.x+(SX-BX)
19563
19792
  local TY=PointVec3.z+(SY-BY)
19564
19793
  if spawnonground then
19565
19794
  if spawnonship or spawnonfarp or spawnonrunway then
19566
- self:T(string.format("Group %s spawning at farp, ship or runway %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
19795
+ self:T2(string.format("Group %s spawning at farp, ship or runway %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
19567
19796
  SpawnTemplate.units[UnitID].x=PointVec3.x
19568
19797
  SpawnTemplate.units[UnitID].y=PointVec3.z
19569
19798
  SpawnTemplate.units[UnitID].alt=PointVec3.y
19570
19799
  else
19571
- self:T(string.format("Group %s spawning at airbase %s on parking spot id %d",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),parkingindex[UnitID]))
19800
+ self:T2(string.format("Group %s spawning at airbase %s on parking spot id %d",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),parkingindex[UnitID]))
19572
19801
  SpawnTemplate.units[UnitID].x=parkingspots[UnitID].x
19573
19802
  SpawnTemplate.units[UnitID].y=parkingspots[UnitID].z
19574
19803
  SpawnTemplate.units[UnitID].alt=parkingspots[UnitID].y
19575
19804
  end
19576
19805
  else
19577
- self:T(string.format("Group %s spawning in air at %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
19806
+ self:T2(string.format("Group %s spawning in air at %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
19578
19807
  SpawnTemplate.units[UnitID].x=TX
19579
19808
  SpawnTemplate.units[UnitID].y=TY
19580
19809
  SpawnTemplate.units[UnitID].alt=PointVec3.y
@@ -19584,8 +19813,8 @@ UnitTemplate.parking_id=nil
19584
19813
  if parkingindex[UnitID]then
19585
19814
  UnitTemplate.parking=parkingindex[UnitID]
19586
19815
  end
19587
- self:T(string.format("Group %s unit number %d: Parking = %s",self.SpawnTemplatePrefix,UnitID,tostring(UnitTemplate.parking)))
19588
- self:T(string.format("Group %s unit number %d: Parking ID = %s",self.SpawnTemplatePrefix,UnitID,tostring(UnitTemplate.parking_id)))
19816
+ self:T2(string.format("Group %s unit number %d: Parking = %s",self.SpawnTemplatePrefix,UnitID,tostring(UnitTemplate.parking)))
19817
+ self:T2(string.format("Group %s unit number %d: Parking ID = %s",self.SpawnTemplatePrefix,UnitID,tostring(UnitTemplate.parking_id)))
19589
19818
  self:T2('After Translation SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
19590
19819
  end
19591
19820
  end
@@ -19610,7 +19839,6 @@ end
19610
19839
  return nil
19611
19840
  end
19612
19841
  function SPAWN:SpawnAtParkingSpot(Airbase,Spots,Takeoff)
19613
- self:F({Airbase=Airbase,Spots=Spots,Takeoff=Takeoff})
19614
19842
  if type(Spots)~="table"then
19615
19843
  Spots={Spots}
19616
19844
  end
@@ -19629,7 +19857,7 @@ for _,TerminalID in pairs(Spots)do
19629
19857
  local spot=Airbase:GetParkingSpotData(TerminalID)
19630
19858
  self:T2({spot=spot})
19631
19859
  if spot and spot.Free then
19632
- self:T(string.format("Adding parking spot ID=%d TermType=%d",spot.TerminalID,spot.TerminalType))
19860
+ self:T2(string.format("Adding parking spot ID=%d TermType=%d",spot.TerminalID,spot.TerminalType))
19633
19861
  table.insert(Parkingdata,spot)
19634
19862
  end
19635
19863
  end
@@ -19644,14 +19872,13 @@ end
19644
19872
  return nil
19645
19873
  end
19646
19874
  function SPAWN:ParkAircraft(SpawnAirbase,TerminalType,Parkingdata,SpawnIndex)
19647
- self:F({SpawnIndex=SpawnIndex,SpawnMaxGroups=self.SpawnMaxGroups})
19648
19875
  local PointVec3=SpawnAirbase:GetCoordinate()
19649
19876
  self:T2(PointVec3)
19650
19877
  local Takeoff=SPAWN.Takeoff.Cold
19651
19878
  local SpawnTemplate=self.SpawnGroups[SpawnIndex].SpawnTemplate
19652
19879
  if SpawnTemplate then
19653
19880
  local GroupAlive=self:GetGroupFromIndex(SpawnIndex)
19654
- self:T({"Current point of ",self.SpawnTemplatePrefix,SpawnAirbase})
19881
+ self:T2({"Current point of ",self.SpawnTemplatePrefix,SpawnAirbase})
19655
19882
  local TemplateGroup=GROUP:FindByName(self.SpawnTemplatePrefix)
19656
19883
  local TemplateUnit=TemplateGroup:GetUnit(1)
19657
19884
  local ishelo=TemplateUnit:HasAttribute("Helicopters")
@@ -19665,7 +19892,6 @@ SpawnPoint.helipadId=nil
19665
19892
  SpawnPoint.airdromeId=nil
19666
19893
  local AirbaseID=SpawnAirbase:GetID()
19667
19894
  local AirbaseCategory=SpawnAirbase:GetAirbaseCategory()
19668
- self:F({AirbaseCategory=AirbaseCategory})
19669
19895
  if AirbaseCategory==Airbase.Category.SHIP then
19670
19896
  SpawnPoint.linkUnit=AirbaseID
19671
19897
  SpawnPoint.helipadId=AirbaseID
@@ -19679,7 +19905,7 @@ SpawnPoint.alt=0
19679
19905
  SpawnPoint.type=GROUPTEMPLATE.Takeoff[Takeoff][1]
19680
19906
  SpawnPoint.action=GROUPTEMPLATE.Takeoff[Takeoff][2]
19681
19907
  local spawnonground=not(Takeoff==SPAWN.Takeoff.Air)
19682
- self:T({spawnonground=spawnonground,TOtype=Takeoff,TOair=Takeoff==SPAWN.Takeoff.Air})
19908
+ self:T2({spawnonground=spawnonground,TOtype=Takeoff,TOair=Takeoff==SPAWN.Takeoff.Air})
19683
19909
  local spawnonship=false
19684
19910
  local spawnonfarp=false
19685
19911
  local spawnonrunway=false
@@ -19706,43 +19932,43 @@ local scanstatics=true
19706
19932
  local scanscenery=false
19707
19933
  local verysafe=false
19708
19934
  if spawnonship or spawnonfarp or spawnonrunway then
19709
- self:T(string.format("Group %s is spawned on farp/ship/runway %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
19935
+ self:T2(string.format("Group %s is spawned on farp/ship/runway %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
19710
19936
  nfree=SpawnAirbase:GetFreeParkingSpotsNumber(termtype,true)
19711
19937
  spots=SpawnAirbase:GetFreeParkingSpotsTable(termtype,true)
19712
19938
  else
19713
19939
  if ishelo then
19714
19940
  if termtype==nil then
19715
- self:T(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.HelicopterOnly))
19941
+ self:T2(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.HelicopterOnly))
19716
19942
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.HelicopterOnly,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19717
19943
  nfree=#spots
19718
19944
  if nfree<nunits then
19719
- self:T(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.HelicopterUsable))
19945
+ self:T2(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.HelicopterUsable))
19720
19946
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.HelicopterUsable,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19721
19947
  nfree=#spots
19722
19948
  end
19723
19949
  else
19724
- self:T(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),termtype))
19950
+ self:T2(string.format("Helo group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),termtype))
19725
19951
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,termtype,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19726
19952
  nfree=#spots
19727
19953
  end
19728
19954
  else
19729
19955
  if termtype==nil then
19730
19956
  if isbomber or istransport then
19731
- self:T(string.format("Transport/bomber group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.OpenBig))
19957
+ self:T2(string.format("Transport/bomber group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.OpenBig))
19732
19958
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.OpenBig,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19733
19959
  nfree=#spots
19734
19960
  if nfree<nunits then
19735
- self:T(string.format("Transport/bomber group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.OpenMedOrBig))
19961
+ self:T2(string.format("Transport/bomber group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.OpenMedOrBig))
19736
19962
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.OpenMedOrBig,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19737
19963
  nfree=#spots
19738
19964
  end
19739
19965
  else
19740
- self:T(string.format("Fighter group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.FighterAircraft))
19966
+ self:T2(string.format("Fighter group %s is at %s using terminal type %d.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),AIRBASE.TerminalType.FighterAircraft))
19741
19967
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,AIRBASE.TerminalType.FighterAircraft,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19742
19968
  nfree=#spots
19743
19969
  end
19744
19970
  else
19745
- self:T(string.format("Plane group %s is at %s using terminal type %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),tostring(termtype)))
19971
+ self:T2(string.format("Plane group %s is at %s using terminal type %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),tostring(termtype)))
19746
19972
  spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup,termtype,scanradius,scanunits,scanstatics,scanscenery,verysafe,nunits,Parkingdata)
19747
19973
  nfree=#spots
19748
19974
  end
@@ -19781,7 +20007,6 @@ end
19781
20007
  if not SpawnTemplate.parked then
19782
20008
  SpawnTemplate.parked=true
19783
20009
  for UnitID=1,nunits do
19784
- self:F('Before Translation SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
19785
20010
  local UnitTemplate=SpawnTemplate.units[UnitID]
19786
20011
  local SX=UnitTemplate.x
19787
20012
  local SY=UnitTemplate.y
@@ -19791,18 +20016,18 @@ local TX=PointVec3.x+(SX-BX)
19791
20016
  local TY=PointVec3.z+(SY-BY)
19792
20017
  if spawnonground then
19793
20018
  if spawnonship or spawnonfarp or spawnonrunway then
19794
- self:T(string.format("Group %s spawning at farp, ship or runway %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
20019
+ self:T2(string.format("Group %s spawning at farp, ship or runway %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
19795
20020
  SpawnTemplate.units[UnitID].x=PointVec3.x
19796
20021
  SpawnTemplate.units[UnitID].y=PointVec3.z
19797
20022
  SpawnTemplate.units[UnitID].alt=PointVec3.y
19798
20023
  else
19799
- self:T(string.format("Group %s spawning at airbase %s on parking spot id %d",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),parkingindex[UnitID]))
20024
+ self:T2(string.format("Group %s spawning at airbase %s on parking spot id %d",self.SpawnTemplatePrefix,SpawnAirbase:GetName(),parkingindex[UnitID]))
19800
20025
  SpawnTemplate.units[UnitID].x=parkingspots[UnitID].x
19801
20026
  SpawnTemplate.units[UnitID].y=parkingspots[UnitID].z
19802
20027
  SpawnTemplate.units[UnitID].alt=parkingspots[UnitID].y
19803
20028
  end
19804
20029
  else
19805
- self:T(string.format("Group %s spawning in air at %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
20030
+ self:T2(string.format("Group %s spawning in air at %s.",self.SpawnTemplatePrefix,SpawnAirbase:GetName()))
19806
20031
  SpawnTemplate.units[UnitID].x=TX
19807
20032
  SpawnTemplate.units[UnitID].y=TY
19808
20033
  SpawnTemplate.units[UnitID].alt=PointVec3.y
@@ -19835,7 +20060,6 @@ end
19835
20060
  end
19836
20061
  end
19837
20062
  function SPAWN:ParkAtAirbase(SpawnAirbase,TerminalType,Parkingdata)
19838
- self:F({self.SpawnTemplatePrefix,SpawnAirbase,TerminalType})
19839
20063
  self:ParkAircraft(SpawnAirbase,TerminalType,Parkingdata,1)
19840
20064
  for SpawnIndex=2,self.SpawnMaxGroups do
19841
20065
  self:ParkAircraft(SpawnAirbase,TerminalType,Parkingdata,SpawnIndex)
@@ -19844,7 +20068,6 @@ self:SetSpawnIndex(0)
19844
20068
  return nil
19845
20069
  end
19846
20070
  function SPAWN:SpawnFromVec3(Vec3,SpawnIndex)
19847
- self:F({self.SpawnTemplatePrefix,Vec3,SpawnIndex})
19848
20071
  local PointVec3=POINT_VEC3:NewFromVec3(Vec3)
19849
20072
  self:T2(PointVec3)
19850
20073
  if SpawnIndex then
@@ -19854,7 +20077,7 @@ end
19854
20077
  if self:_GetSpawnIndex(SpawnIndex)then
19855
20078
  local SpawnTemplate=self.SpawnGroups[self.SpawnIndex].SpawnTemplate
19856
20079
  if SpawnTemplate then
19857
- self:T({"Current point of ",self.SpawnTemplatePrefix,Vec3})
20080
+ self:T2({"Current point of ",self.SpawnTemplatePrefix,Vec3})
19858
20081
  local TemplateHeight=SpawnTemplate.route and SpawnTemplate.route.points[1].alt or nil
19859
20082
  SpawnTemplate.route=SpawnTemplate.route or{}
19860
20083
  SpawnTemplate.route.points=SpawnTemplate.route.points or{}
@@ -19874,7 +20097,7 @@ SpawnTemplate.units[UnitID].y=TY
19874
20097
  if SpawnTemplate.CategoryID~=Group.Category.SHIP then
19875
20098
  SpawnTemplate.units[UnitID].alt=Vec3.y or TemplateHeight
19876
20099
  end
19877
- self:T('After Translation SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
20100
+ self:T2('After Translation SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
19878
20101
  end
19879
20102
  SpawnTemplate.route.points[1].x=Vec3.x
19880
20103
  SpawnTemplate.route.points[1].y=Vec3.z
@@ -19890,15 +20113,12 @@ end
19890
20113
  return nil
19891
20114
  end
19892
20115
  function SPAWN:SpawnFromCoordinate(Coordinate,SpawnIndex)
19893
- self:F({self.SpawnTemplatePrefix,SpawnIndex})
19894
20116
  return self:SpawnFromVec3(Coordinate:GetVec3(),SpawnIndex)
19895
20117
  end
19896
20118
  function SPAWN:SpawnFromPointVec3(PointVec3,SpawnIndex)
19897
- self:F({self.SpawnTemplatePrefix,SpawnIndex})
19898
20119
  return self:SpawnFromVec3(PointVec3:GetVec3(),SpawnIndex)
19899
20120
  end
19900
20121
  function SPAWN:SpawnFromVec2(Vec2,MinHeight,MaxHeight,SpawnIndex)
19901
- self:F({self.SpawnTemplatePrefix,self.SpawnIndex,Vec2,MinHeight,MaxHeight,SpawnIndex})
19902
20122
  local Height=nil
19903
20123
  if MinHeight and MaxHeight then
19904
20124
  Height=math.random(MinHeight,MaxHeight)
@@ -19906,25 +20126,21 @@ end
19906
20126
  return self:SpawnFromVec3({x=Vec2.x,y=Height,z=Vec2.y},SpawnIndex)
19907
20127
  end
19908
20128
  function SPAWN:SpawnFromPointVec2(PointVec2,MinHeight,MaxHeight,SpawnIndex)
19909
- self:F({self.SpawnTemplatePrefix,self.SpawnIndex})
19910
20129
  return self:SpawnFromVec2(PointVec2:GetVec2(),MinHeight,MaxHeight,SpawnIndex)
19911
20130
  end
19912
20131
  function SPAWN:SpawnFromUnit(HostUnit,MinHeight,MaxHeight,SpawnIndex)
19913
- self:F({self.SpawnTemplatePrefix,HostUnit,MinHeight,MaxHeight,SpawnIndex})
19914
20132
  if HostUnit and HostUnit:IsAlive()~=nil then
19915
20133
  return self:SpawnFromVec2(HostUnit:GetVec2(),MinHeight,MaxHeight,SpawnIndex)
19916
20134
  end
19917
20135
  return nil
19918
20136
  end
19919
20137
  function SPAWN:SpawnFromStatic(HostStatic,MinHeight,MaxHeight,SpawnIndex)
19920
- self:F({self.SpawnTemplatePrefix,HostStatic,MinHeight,MaxHeight,SpawnIndex})
19921
20138
  if HostStatic and HostStatic:IsAlive()then
19922
20139
  return self:SpawnFromVec2(HostStatic:GetVec2(),MinHeight,MaxHeight,SpawnIndex)
19923
20140
  end
19924
20141
  return nil
19925
20142
  end
19926
20143
  function SPAWN:SpawnInZone(Zone,RandomizeGroup,MinHeight,MaxHeight,SpawnIndex)
19927
- self:F({self.SpawnTemplatePrefix,Zone,RandomizeGroup,MinHeight,MaxHeight,SpawnIndex})
19928
20144
  if Zone then
19929
20145
  if RandomizeGroup then
19930
20146
  return self:SpawnFromVec2(Zone:GetRandomVec2(),MinHeight,MaxHeight,SpawnIndex)
@@ -19950,22 +20166,20 @@ end
19950
20166
  return nil
19951
20167
  end
19952
20168
  function SPAWN:SpawnGroupName(SpawnIndex)
19953
- self:F({self.SpawnTemplatePrefix,SpawnIndex})
19954
20169
  local SpawnPrefix=self.SpawnTemplatePrefix
19955
20170
  if self.SpawnAliasPrefix then
19956
20171
  SpawnPrefix=self.SpawnAliasPrefix
19957
20172
  end
19958
20173
  if SpawnIndex then
19959
20174
  local SpawnName=string.format('%s#%03d',SpawnPrefix,SpawnIndex)
19960
- self:T(SpawnName)
20175
+ self:T2(SpawnName)
19961
20176
  return SpawnName
19962
20177
  else
19963
- self:T(SpawnPrefix)
20178
+ self:T2(SpawnPrefix)
19964
20179
  return SpawnPrefix
19965
20180
  end
19966
20181
  end
19967
20182
  function SPAWN:GetFirstAliveGroup()
19968
- self:F({self.SpawnTemplatePrefix,self.SpawnAliasPrefix})
19969
20183
  for SpawnIndex=1,self.SpawnCount do
19970
20184
  local SpawnGroup=self:GetGroupFromIndex(SpawnIndex)
19971
20185
  if SpawnGroup and SpawnGroup:IsAlive()then
@@ -19975,7 +20189,6 @@ end
19975
20189
  return nil,nil
19976
20190
  end
19977
20191
  function SPAWN:GetNextAliveGroup(SpawnIndexStart)
19978
- self:F({self.SpawnTemplatePrefix,self.SpawnAliasPrefix,SpawnIndexStart})
19979
20192
  SpawnIndexStart=SpawnIndexStart+1
19980
20193
  for SpawnIndex=SpawnIndexStart,self.SpawnCount do
19981
20194
  local SpawnGroup=self:GetGroupFromIndex(SpawnIndex)
@@ -19986,7 +20199,6 @@ end
19986
20199
  return nil,nil
19987
20200
  end
19988
20201
  function SPAWN:GetLastAliveGroup()
19989
- self:F({self.SpawnTemplatePrefix,self.SpawnAliasPrefix})
19990
20202
  for SpawnIndex=self.SpawnCount,1,-1 do
19991
20203
  local SpawnGroup=self:GetGroupFromIndex(SpawnIndex)
19992
20204
  if SpawnGroup and SpawnGroup:IsAlive()then
@@ -19998,7 +20210,6 @@ self.SpawnIndex=nil
19998
20210
  return nil
19999
20211
  end
20000
20212
  function SPAWN:GetGroupFromIndex(SpawnIndex)
20001
- self:F({self.SpawnTemplatePrefix,self.SpawnAliasPrefix,SpawnIndex})
20002
20213
  if not SpawnIndex then
20003
20214
  SpawnIndex=1
20004
20215
  end
@@ -20028,18 +20239,15 @@ end
20028
20239
  return nil
20029
20240
  end
20030
20241
  function SPAWN:GetSpawnIndexFromGroup(SpawnGroup)
20031
- self:F3({self.SpawnTemplatePrefix,self.SpawnAliasPrefix,SpawnGroup})
20032
20242
  local IndexString=string.match(SpawnGroup:GetName(),"#(%d*)$"):sub(2)
20033
20243
  local Index=tonumber(IndexString)
20034
20244
  self:T3(IndexString,Index)
20035
20245
  return Index
20036
20246
  end
20037
20247
  function SPAWN:_GetLastIndex()
20038
- self:F3({self.SpawnTemplatePrefix,self.SpawnAliasPrefix})
20039
20248
  return self.SpawnMaxGroups
20040
20249
  end
20041
20250
  function SPAWN:_InitializeSpawnGroups(SpawnIndex)
20042
- self:F3({self.SpawnTemplatePrefix,self.SpawnAliasPrefix,SpawnIndex})
20043
20251
  if not self.SpawnGroups[SpawnIndex]then
20044
20252
  self.SpawnGroups[SpawnIndex]={}
20045
20253
  self.SpawnGroups[SpawnIndex].Visible=false
@@ -20070,7 +20278,6 @@ return nil
20070
20278
  end
20071
20279
  end
20072
20280
  function SPAWN:_GetGroupCountryID(SpawnPrefix)
20073
- self:F({self.SpawnTemplatePrefix,self.SpawnAliasPrefix,SpawnPrefix})
20074
20281
  local TemplateGroup=Group.getByName(SpawnPrefix)
20075
20282
  if TemplateGroup then
20076
20283
  local TemplateUnits=TemplateGroup:getUnits()
@@ -20080,13 +20287,11 @@ return nil
20080
20287
  end
20081
20288
  end
20082
20289
  function SPAWN:_GetTemplate(SpawnTemplatePrefix)
20083
- self:F({self.SpawnTemplatePrefix,self.SpawnAliasPrefix,SpawnTemplatePrefix})
20084
20290
  local SpawnTemplate=nil
20085
20291
  if _DATABASE.Templates.Groups[SpawnTemplatePrefix]==nil then
20086
20292
  error('No Template exists for SpawnTemplatePrefix = '..SpawnTemplatePrefix)
20087
20293
  end
20088
20294
  local Template=_DATABASE.Templates.Groups[SpawnTemplatePrefix].Template
20089
- self:F({Template=Template})
20090
20295
  SpawnTemplate=UTILS.DeepCopy(_DATABASE.Templates.Groups[SpawnTemplatePrefix].Template)
20091
20296
  if SpawnTemplate==nil then
20092
20297
  error('No Template returned for SpawnTemplatePrefix = '..SpawnTemplatePrefix)
@@ -20095,7 +20300,6 @@ self:T3({SpawnTemplate})
20095
20300
  return SpawnTemplate
20096
20301
  end
20097
20302
  function SPAWN:_Prepare(SpawnTemplatePrefix,SpawnIndex)
20098
- self:F({self.SpawnTemplatePrefix,self.SpawnAliasPrefix})
20099
20303
  local SpawnTemplate
20100
20304
  if self.TweakedTemplate~=nil and self.TweakedTemplate==true then
20101
20305
  BASE:I("WARNING: You are using a tweaked template.")
@@ -20117,7 +20321,6 @@ SpawnTemplate.visible=false
20117
20321
  end
20118
20322
  if self.SpawnGrouping then
20119
20323
  local UnitAmount=#SpawnTemplate.units
20120
- self:F({UnitAmount=UnitAmount,SpawnGrouping=self.SpawnGrouping})
20121
20324
  if UnitAmount>self.SpawnGrouping then
20122
20325
  for UnitID=self.SpawnGrouping+1,UnitAmount do
20123
20326
  SpawnTemplate.units[UnitID]=nil
@@ -20148,7 +20351,7 @@ local UnitPrefix,Rest
20148
20351
  if SpawnInitKeepUnitIFF==false then
20149
20352
  UnitPrefix,Rest=string.match(SpawnTemplate.units[UnitID].name,"^([^#]+)#?"):gsub("^%s*(.-)%s*$","%1")
20150
20353
  SpawnTemplate.units[UnitID].name=string.format('%s#%03d-%02d',UnitPrefix,SpawnIndex,UnitID)
20151
- self:T({UnitPrefix,Rest})
20354
+ self:T2({UnitPrefix,Rest})
20152
20355
  end
20153
20356
  SpawnTemplate.units[UnitID].unitId=nil
20154
20357
  end
@@ -20307,7 +20510,6 @@ self:T3({"Template:",SpawnTemplate})
20307
20510
  return SpawnTemplate
20308
20511
  end
20309
20512
  function SPAWN:_RandomizeRoute(SpawnIndex)
20310
- self:F({self.SpawnTemplatePrefix,SpawnIndex,self.SpawnRandomizeRoute,self.SpawnRandomizeRouteStartPoint,self.SpawnRandomizeRouteEndPoint,self.SpawnRandomizeRouteRadius})
20311
20513
  if self.SpawnRandomizeRoute then
20312
20514
  local SpawnTemplate=self.SpawnGroups[SpawnIndex].SpawnTemplate
20313
20515
  local RouteCount=#SpawnTemplate.route.points
@@ -20321,14 +20523,13 @@ end
20321
20523
  else
20322
20524
  SpawnTemplate.route.points[t].alt=nil
20323
20525
  end
20324
- self:T('SpawnTemplate.route.points['..t..'].x = '..SpawnTemplate.route.points[t].x..', SpawnTemplate.route.points['..t..'].y = '..SpawnTemplate.route.points[t].y)
20526
+ self:T2('SpawnTemplate.route.points['..t..'].x = '..SpawnTemplate.route.points[t].x..', SpawnTemplate.route.points['..t..'].y = '..SpawnTemplate.route.points[t].y)
20325
20527
  end
20326
20528
  end
20327
20529
  self:_RandomizeZones(SpawnIndex)
20328
20530
  return self
20329
20531
  end
20330
20532
  function SPAWN:_RandomizeTemplate(SpawnIndex)
20331
- self:F({self.SpawnTemplatePrefix,SpawnIndex,self.SpawnRandomizeTemplate})
20332
20533
  if self.SpawnRandomizeTemplate then
20333
20534
  self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix=self.SpawnTemplatePrefixTable[math.random(1,#self.SpawnTemplatePrefixTable)]
20334
20535
  self.SpawnGroups[SpawnIndex].SpawnTemplate=self:_Prepare(self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix,SpawnIndex)
@@ -20349,21 +20550,21 @@ self:_RandomizeRoute(SpawnIndex)
20349
20550
  return self
20350
20551
  end
20351
20552
  function SPAWN:_SetInitialPosition(SpawnIndex)
20352
- self:T({self.SpawnTemplatePrefix,SpawnIndex,self.SpawnRandomizeZones})
20553
+ self:T2({self.SpawnTemplatePrefix,SpawnIndex,self.SpawnRandomizeZones})
20353
20554
  if self.SpawnFromNewPosition then
20354
- self:T("Preparing Spawn at Vec2 ",self.SpawnInitPosition)
20555
+ self:T2("Preparing Spawn at Vec2 ",self.SpawnInitPosition)
20355
20556
  local SpawnVec2=self.SpawnInitPosition
20356
- self:T({SpawnVec2=SpawnVec2})
20557
+ self:T2({SpawnVec2=SpawnVec2})
20357
20558
  local SpawnTemplate=self.SpawnGroups[SpawnIndex].SpawnTemplate
20358
20559
  SpawnTemplate.route=SpawnTemplate.route or{}
20359
20560
  SpawnTemplate.route.points=SpawnTemplate.route.points or{}
20360
20561
  SpawnTemplate.route.points[1]=SpawnTemplate.route.points[1]or{}
20361
20562
  SpawnTemplate.route.points[1].x=SpawnTemplate.route.points[1].x or 0
20362
20563
  SpawnTemplate.route.points[1].y=SpawnTemplate.route.points[1].y or 0
20363
- self:T({Route=SpawnTemplate.route})
20564
+ self:T2({Route=SpawnTemplate.route})
20364
20565
  for UnitID=1,#SpawnTemplate.units do
20365
20566
  local UnitTemplate=SpawnTemplate.units[UnitID]
20366
- self:T('Before Translation SpawnTemplate.units['..UnitID..'].x = '..UnitTemplate.x..', SpawnTemplate.units['..UnitID..'].y = '..UnitTemplate.y)
20567
+ self:T2('Before Translation SpawnTemplate.units['..UnitID..'].x = '..UnitTemplate.x..', SpawnTemplate.units['..UnitID..'].y = '..UnitTemplate.y)
20367
20568
  local SX=UnitTemplate.x
20368
20569
  local SY=UnitTemplate.y
20369
20570
  local BX=SpawnTemplate.route.points[1].x
@@ -20372,7 +20573,7 @@ local TX=SpawnVec2.x+(SX-BX)
20372
20573
  local TY=SpawnVec2.y+(SY-BY)
20373
20574
  UnitTemplate.x=TX
20374
20575
  UnitTemplate.y=TY
20375
- self:T('After Translation SpawnTemplate.units['..UnitID..'].x = '..UnitTemplate.x..', SpawnTemplate.units['..UnitID..'].y = '..UnitTemplate.y)
20576
+ self:T2('After Translation SpawnTemplate.units['..UnitID..'].x = '..UnitTemplate.x..', SpawnTemplate.units['..UnitID..'].y = '..UnitTemplate.y)
20376
20577
  end
20377
20578
  SpawnTemplate.route.points[1].x=SpawnVec2.x
20378
20579
  SpawnTemplate.route.points[1].y=SpawnVec2.y
@@ -20382,24 +20583,23 @@ end
20382
20583
  return self
20383
20584
  end
20384
20585
  function SPAWN:_RandomizeZones(SpawnIndex)
20385
- self:F({self.SpawnTemplatePrefix,SpawnIndex,self.SpawnRandomizeZones})
20386
20586
  if self.SpawnRandomizeZones then
20387
20587
  local SpawnZone=nil
20388
20588
  while not SpawnZone do
20389
- self:T({SpawnZoneTableCount=#self.SpawnZoneTable,self.SpawnZoneTable})
20589
+ self:T2({SpawnZoneTableCount=#self.SpawnZoneTable,self.SpawnZoneTable})
20390
20590
  local ZoneID=math.random(#self.SpawnZoneTable)
20391
- self:T(ZoneID)
20591
+ self:T2(ZoneID)
20392
20592
  SpawnZone=self.SpawnZoneTable[ZoneID]:GetZoneMaybe()
20393
20593
  end
20394
- self:T("Preparing Spawn in Zone",SpawnZone:GetName())
20594
+ self:T2("Preparing Spawn in Zone",SpawnZone:GetName())
20395
20595
  local SpawnVec2=SpawnZone:GetRandomVec2()
20396
- self:T({SpawnVec2=SpawnVec2})
20596
+ self:T2({SpawnVec2=SpawnVec2})
20397
20597
  local SpawnTemplate=self.SpawnGroups[SpawnIndex].SpawnTemplate
20398
20598
  self.SpawnGroups[SpawnIndex].SpawnZone=SpawnZone
20399
- self:T({Route=SpawnTemplate.route})
20599
+ self:T2({Route=SpawnTemplate.route})
20400
20600
  for UnitID=1,#SpawnTemplate.units do
20401
20601
  local UnitTemplate=SpawnTemplate.units[UnitID]
20402
- self:T('Before Translation SpawnTemplate.units['..UnitID..'].x = '..UnitTemplate.x..', SpawnTemplate.units['..UnitID..'].y = '..UnitTemplate.y)
20602
+ self:T2('Before Translation SpawnTemplate.units['..UnitID..'].x = '..UnitTemplate.x..', SpawnTemplate.units['..UnitID..'].y = '..UnitTemplate.y)
20403
20603
  local SX=UnitTemplate.x
20404
20604
  local SY=UnitTemplate.y
20405
20605
  local BX=SpawnTemplate.route.points[1].x
@@ -20408,7 +20608,7 @@ local TX=SpawnVec2.x+(SX-BX)
20408
20608
  local TY=SpawnVec2.y+(SY-BY)
20409
20609
  UnitTemplate.x=TX
20410
20610
  UnitTemplate.y=TY
20411
- self:T('After Translation SpawnTemplate.units['..UnitID..'].x = '..UnitTemplate.x..', SpawnTemplate.units['..UnitID..'].y = '..UnitTemplate.y)
20611
+ self:T2('After Translation SpawnTemplate.units['..UnitID..'].x = '..UnitTemplate.x..', SpawnTemplate.units['..UnitID..'].y = '..UnitTemplate.y)
20412
20612
  end
20413
20613
  SpawnTemplate.x=SpawnVec2.x
20414
20614
  SpawnTemplate.y=SpawnVec2.y
@@ -20418,7 +20618,6 @@ end
20418
20618
  return self
20419
20619
  end
20420
20620
  function SPAWN:_TranslateRotate(SpawnIndex,SpawnRootX,SpawnRootY,SpawnX,SpawnY,SpawnAngle)
20421
- self:F({self.SpawnTemplatePrefix,SpawnIndex,SpawnRootX,SpawnRootY,SpawnX,SpawnY,SpawnAngle})
20422
20621
  local TranslatedX=SpawnX
20423
20622
  local TranslatedY=SpawnY
20424
20623
  local RotatedX=-TranslatedX*math.cos(math.rad(SpawnAngle))+TranslatedY*math.sin(math.rad(SpawnAngle))
@@ -20438,10 +20637,10 @@ end
20438
20637
  return self
20439
20638
  end
20440
20639
  function SPAWN:_GetSpawnIndex(SpawnIndex)
20441
- self:F2({self.SpawnTemplatePrefix,SpawnIndex,self.SpawnMaxGroups,self.SpawnMaxUnitsAlive,self.AliveUnits,#self.SpawnTemplate.units})
20640
+ self:T2({template=self.SpawnTemplatePrefix,SpawnIndex=SpawnIndex,SpawnMaxGroups=self.SpawnMaxGroups,SpawnMaxUnitsAlive=self.SpawnMaxUnitsAlive,AliveUnits=self.AliveUnits,TemplateUnits=#self.SpawnTemplate.units})
20442
20641
  if(self.SpawnMaxGroups==0)or(SpawnIndex<=self.SpawnMaxGroups)then
20443
20642
  if(self.SpawnMaxUnitsAlive==0)or(self.AliveUnits+#self.SpawnTemplate.units<=self.SpawnMaxUnitsAlive)or self.UnControlled==true then
20444
- self:F({SpawnCount=self.SpawnCount,SpawnIndex=SpawnIndex})
20643
+ self:T2({SpawnCount=self.SpawnCount,SpawnIndex=SpawnIndex})
20445
20644
  if SpawnIndex and SpawnIndex>=self.SpawnCount+1 then
20446
20645
  self.SpawnCount=self.SpawnCount+1
20447
20646
  SpawnIndex=self.SpawnCount
@@ -20459,59 +20658,58 @@ end
20459
20658
  return self.SpawnIndex
20460
20659
  end
20461
20660
  function SPAWN:_OnBirth(EventData)
20462
- self:F(self.SpawnTemplatePrefix)
20463
20661
  local SpawnGroup=EventData.IniGroup
20464
20662
  if SpawnGroup then
20465
20663
  local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
20466
20664
  if EventPrefix then
20467
- self:T({"Birth Event:",EventPrefix,self.SpawnTemplatePrefix})
20665
+ self:T2({"Birth Event:",EventPrefix,self.SpawnTemplatePrefix})
20468
20666
  if EventPrefix==self.SpawnTemplatePrefix or(self.SpawnAliasPrefix and EventPrefix==self.SpawnAliasPrefix)then
20469
20667
  self.AliveUnits=self.AliveUnits+1
20470
- self:T("Alive Units: "..self.AliveUnits)
20668
+ self:T2("Alive Units: "..self.AliveUnits)
20471
20669
  end
20472
20670
  end
20473
20671
  end
20474
20672
  end
20475
20673
  function SPAWN:_OnDeadOrCrash(EventData)
20476
- self:F(self.SpawnTemplatePrefix)
20674
+ self:T2("Dead or crash event ID "..tostring(EventData.id or 0))
20675
+ self:T2("Dead or crash event for "..tostring(EventData.IniUnitName or"none"))
20477
20676
  local unit=UNIT:FindByName(EventData.IniUnitName)
20478
20677
  if unit then
20479
20678
  local EventPrefix=self:_GetPrefixFromGroupName(unit.GroupName)
20480
20679
  if EventPrefix then
20481
- self:T({"Dead event: "..EventPrefix})
20482
- if EventPrefix==self.SpawnTemplatePrefix or(self.SpawnAliasPrefix and EventPrefix==self.SpawnAliasPrefix)then
20680
+ self:T2({"Dead event: "..EventPrefix})
20681
+ self:T2(string.format("EventPrefix = %s | SpawnAliasPrefix = %s | Old AliveUnits = %d",EventPrefix or"",self.SpawnAliasPrefix or"",self.AliveUnits or 0))
20682
+ if EventPrefix==self.SpawnTemplatePrefix or(self.SpawnAliasPrefix and EventPrefix==self.SpawnAliasPrefix)and self.AliveUnits>0 then
20483
20683
  self.AliveUnits=self.AliveUnits-1
20484
- self:T("Alive Units: "..self.AliveUnits)
20485
20684
  end
20685
+ self:T2("New Alive Units: "..self.AliveUnits)
20486
20686
  end
20487
20687
  end
20488
20688
  end
20489
20689
  function SPAWN:_OnTakeOff(EventData)
20490
- self:F(self.SpawnTemplatePrefix)
20491
20690
  local SpawnGroup=EventData.IniGroup
20492
20691
  if SpawnGroup then
20493
20692
  local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
20494
20693
  if EventPrefix then
20495
- self:T({"TakeOff event: "..EventPrefix})
20694
+ self:T2({"TakeOff event: "..EventPrefix})
20496
20695
  if EventPrefix==self.SpawnTemplatePrefix or(self.SpawnAliasPrefix and EventPrefix==self.SpawnAliasPrefix)then
20497
- self:T("self.Landed = false")
20696
+ self:T2("self.Landed = false")
20498
20697
  SpawnGroup:SetState(SpawnGroup,"Spawn_Landed",false)
20499
20698
  end
20500
20699
  end
20501
20700
  end
20502
20701
  end
20503
20702
  function SPAWN:_OnLand(EventData)
20504
- self:F(self.SpawnTemplatePrefix)
20505
20703
  local SpawnGroup=EventData.IniGroup
20506
20704
  if SpawnGroup then
20507
20705
  local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
20508
20706
  if EventPrefix then
20509
- self:T({"Land event: "..EventPrefix})
20707
+ self:T2({"Land event: "..EventPrefix})
20510
20708
  if EventPrefix==self.SpawnTemplatePrefix or(self.SpawnAliasPrefix and EventPrefix==self.SpawnAliasPrefix)then
20511
20709
  SpawnGroup:SetState(SpawnGroup,"Spawn_Landed",true)
20512
20710
  if self.RepeatOnLanding then
20513
20711
  local SpawnGroupIndex=self:GetSpawnIndexFromGroup(SpawnGroup)
20514
- self:T({"Landed:","ReSpawn:",SpawnGroup:GetName(),SpawnGroupIndex})
20712
+ self:T2({"Landed:","ReSpawn:",SpawnGroup:GetName(),SpawnGroupIndex})
20515
20713
  SCHEDULER:New(nil,self.ReSpawn,{self,SpawnGroupIndex},3)
20516
20714
  end
20517
20715
  end
@@ -20519,17 +20717,16 @@ end
20519
20717
  end
20520
20718
  end
20521
20719
  function SPAWN:_OnEngineShutDown(EventData)
20522
- self:F(self.SpawnTemplatePrefix)
20523
20720
  local SpawnGroup=EventData.IniGroup
20524
20721
  if SpawnGroup then
20525
20722
  local EventPrefix=self:_GetPrefixFromGroup(SpawnGroup)
20526
20723
  if EventPrefix then
20527
- self:T({"EngineShutdown event: "..EventPrefix})
20724
+ self:T2({"EngineShutdown event: "..EventPrefix})
20528
20725
  if EventPrefix==self.SpawnTemplatePrefix or(self.SpawnAliasPrefix and EventPrefix==self.SpawnAliasPrefix)then
20529
20726
  local Landed=SpawnGroup:GetState(SpawnGroup,"Spawn_Landed")
20530
20727
  if Landed and self.RepeatOnEngineShutDown then
20531
20728
  local SpawnGroupIndex=self:GetSpawnIndexFromGroup(SpawnGroup)
20532
- self:T({"EngineShutDown: ","ReSpawn:",SpawnGroup:GetName(),SpawnGroupIndex})
20729
+ self:T2({"EngineShutDown: ","ReSpawn:",SpawnGroup:GetName(),SpawnGroupIndex})
20533
20730
  SCHEDULER:New(nil,self.ReSpawn,{self,SpawnGroupIndex},3)
20534
20731
  end
20535
20732
  end
@@ -20542,9 +20739,8 @@ self:Spawn()
20542
20739
  return true
20543
20740
  end
20544
20741
  function SPAWN:_SpawnCleanUpScheduler()
20545
- self:F({"CleanUp Scheduler:",self.SpawnTemplatePrefix})
20546
20742
  local SpawnGroup,SpawnCursor=self:GetFirstAliveGroup()
20547
- self:T({"CleanUp Scheduler:",SpawnGroup,SpawnCursor})
20743
+ self:T2({"CleanUp Scheduler:",SpawnGroup,SpawnCursor})
20548
20744
  local IsHelo=false
20549
20745
  while SpawnGroup do
20550
20746
  IsHelo=SpawnGroup:IsHelicopter()
@@ -20554,14 +20750,14 @@ local SpawnUnit=UnitData
20554
20750
  local SpawnUnitName=SpawnUnit:GetName()
20555
20751
  self.SpawnCleanUpTimeStamps[SpawnUnitName]=self.SpawnCleanUpTimeStamps[SpawnUnitName]or{}
20556
20752
  local Stamp=self.SpawnCleanUpTimeStamps[SpawnUnitName]
20557
- self:T({SpawnUnitName,Stamp})
20753
+ self:T2({SpawnUnitName,Stamp})
20558
20754
  if Stamp.Vec2 then
20559
20755
  if(SpawnUnit:InAir()==false and SpawnUnit:GetVelocityKMH()<1)or IsHelo then
20560
20756
  local NewVec2=SpawnUnit:GetVec2()or{x=0,y=0}
20561
20757
  if(Stamp.Vec2.x==NewVec2.x and Stamp.Vec2.y==NewVec2.y)or(SpawnUnit:GetLife()<=1)then
20562
20758
  if Stamp.Time+self.SpawnCleanUpInterval<timer.getTime()then
20563
- self:T({"CleanUp Scheduler:","ReSpawning:",SpawnGroup:GetName()})
20564
- self:ReSpawn(SpawnCursor)
20759
+ self:T2({"CleanUp Scheduler:","ReSpawning:",SpawnGroup:GetName()})
20760
+ SCHEDULER:New(nil,self.ReSpawn,{self,SpawnCursor},3)
20565
20761
  Stamp.Vec2=nil
20566
20762
  Stamp.Time=nil
20567
20763
  end
@@ -20586,7 +20782,7 @@ end
20586
20782
  end
20587
20783
  end
20588
20784
  SpawnGroup,SpawnCursor=self:GetNextAliveGroup(SpawnCursor)
20589
- self:T({"CleanUp Scheduler:",SpawnGroup,SpawnCursor})
20785
+ self:T2({"CleanUp Scheduler:",SpawnGroup,SpawnCursor})
20590
20786
  end
20591
20787
  return true
20592
20788
  end
@@ -20623,10 +20819,47 @@ self.InitStaticType=StaticType
20623
20819
  self.InitStaticCategory=StaticCategory
20624
20820
  self.CountryID=CountryID or country.id.USA
20625
20821
  self.SpawnTemplatePrefix=self.InitStaticType
20822
+ self.TemplateStaticUnit={}
20626
20823
  self.InitStaticCoordinate=COORDINATE:New(0,0,0)
20627
20824
  self.InitStaticHeading=0
20628
20825
  return self
20629
20826
  end
20827
+ function SPAWNSTATIC:_InitResourceTable(CombinedWeight)
20828
+ if not self.TemplateStaticUnit.resourcePayload then
20829
+ self.TemplateStaticUnit.resourcePayload={
20830
+ ["weapons"]={},
20831
+ ["aircrafts"]={},
20832
+ ["gasoline"]=0,
20833
+ ["diesel"]=0,
20834
+ ["methanol_mixture"]=0,
20835
+ ["jet_fuel"]=0,
20836
+ }
20837
+ end
20838
+ self:InitCargo(true)
20839
+ self:InitCargoMass(CombinedWeight or 1)
20840
+ return self
20841
+ end
20842
+ function SPAWNSTATIC:AddCargoResource(Type,Name,Amount,CombinedWeight)
20843
+ if not self.TemplateStaticUnit.resourcePayload then
20844
+ self:_InitResourceTable(CombinedWeight)
20845
+ end
20846
+ if Type==STORAGE.Type.LIQUIDS and type(Name)=="string"then
20847
+ self.TemplateStaticUnit.resourcePayload[Name]=Amount
20848
+ else
20849
+ self.TemplateStaticUnit.resourcePayload[Type]={
20850
+ [Name]={
20851
+ ["amount"]=Amount,
20852
+ }
20853
+ }
20854
+ end
20855
+ UTILS.PrintTableToLog(self.TemplateStaticUnit)
20856
+ return self
20857
+ end
20858
+ function SPAWNSTATIC:ResetCargoResources()
20859
+ self.TemplateStaticUnit.resourcePayload=nil
20860
+ self:_InitResourceTable()
20861
+ return self
20862
+ end
20630
20863
  function SPAWNSTATIC:InitCoordinate(Coordinate)
20631
20864
  self.InitStaticCoordinate=Coordinate
20632
20865
  return self
@@ -20681,6 +20914,15 @@ self.InitOffsetY=OffsetY or 0
20681
20914
  self.InitOffsetAngle=OffsetAngle or 0
20682
20915
  return self
20683
20916
  end
20917
+ function SPAWNSTATIC:OnSpawnStatic(SpawnCallBackFunction,...)
20918
+ self:F("OnSpawnStatic")
20919
+ self.SpawnFunctionHook=SpawnCallBackFunction
20920
+ self.SpawnFunctionArguments={}
20921
+ if arg then
20922
+ self.SpawnFunctionArguments=arg
20923
+ end
20924
+ return self
20925
+ end
20684
20926
  function SPAWNSTATIC:Spawn(Heading,NewName)
20685
20927
  if Heading then
20686
20928
  self.InitStaticHeading=Heading
@@ -20784,6 +21026,9 @@ self:T("Spawning Static")
20784
21026
  self:T2({Template=Template})
20785
21027
  Static=coalition.addStaticObject(CountryID,Template)
20786
21028
  end
21029
+ if self.SpawnFunctionHook then
21030
+ self:ScheduleOnce(0.3,self.SpawnFunctionHook,mystatic,unpack(self.SpawnFunctionArguments))
21031
+ end
20787
21032
  return mystatic
20788
21033
  end
20789
21034
  TIMER={
@@ -21447,11 +21692,11 @@ function IDENTIFIABLE:GetCategory()
21447
21692
  self:F2(self.ObjectName)
21448
21693
  local DCSObject=self:GetDCSObject()
21449
21694
  if DCSObject then
21450
- local ObjectCategory=DCSObject:getCategory()
21695
+ local ObjectCategory,UnitCategory=DCSObject:getCategory()
21451
21696
  self:T3(ObjectCategory)
21452
- return ObjectCategory
21697
+ return ObjectCategory,UnitCategory
21453
21698
  end
21454
- return nil
21699
+ return nil,nil
21455
21700
  end
21456
21701
  function IDENTIFIABLE:GetCategoryName()
21457
21702
  local DCSIdentifiable=self:GetDCSObject()
@@ -23298,20 +23543,25 @@ lastWptIndex=LastWptNumber
23298
23543
  }
23299
23544
  return DCSTask
23300
23545
  end
23301
- function CONTROLLABLE:TaskLandAtVec2(Vec2,Duration)
23546
+ function CONTROLLABLE:TaskLandAtVec2(Vec2,Duration,CombatLanding,DirectionAfterLand)
23302
23547
  local DCSTask={
23303
23548
  id='Land',
23304
23549
  params={
23305
23550
  point=Vec2,
23306
23551
  durationFlag=Duration and true or false,
23307
23552
  duration=Duration,
23553
+ combatLandingFlag=CombatLanding==true and true or false,
23308
23554
  },
23309
23555
  }
23556
+ if DirectionAfterLand~=nil and type(DirectionAfterLand)=="number"then
23557
+ DCSTask.params.directionEnabled=true
23558
+ DCSTask.params.direction=math.rad(DirectionAfterLand)
23559
+ end
23310
23560
  return DCSTask
23311
23561
  end
23312
- function CONTROLLABLE:TaskLandAtZone(Zone,Duration,RandomPoint)
23562
+ function CONTROLLABLE:TaskLandAtZone(Zone,Duration,RandomPoint,CombatLanding,DirectionAfterLand)
23313
23563
  local Point=RandomPoint and Zone:GetRandomVec2()or Zone:GetVec2()
23314
- local DCSTask=CONTROLLABLE.TaskLandAtVec2(self,Point,Duration)
23564
+ local DCSTask=CONTROLLABLE.TaskLandAtVec2(self,Point,Duration,CombatLanding,DirectionAfterLand)
23315
23565
  return DCSTask
23316
23566
  end
23317
23567
  function CONTROLLABLE:TaskFollow(FollowControllable,Vec3,LastWaypointIndex)
@@ -24518,6 +24768,30 @@ self:SetOption(AI.Option.Air.id.PROHIBIT_AB,Prohibit)
24518
24768
  end
24519
24769
  return self
24520
24770
  end
24771
+ function CONTROLLABLE:OptionEvasionOfARM(Seconds)
24772
+ self:F2({self.ControllableName})
24773
+ local DCSControllable=self:GetDCSObject()
24774
+ if DCSControllable then
24775
+ local Controller=self:_GetController()
24776
+ if self:IsGround()then
24777
+ if Seconds==nil then Seconds=false end
24778
+ Controller:setOption(AI.Option.Ground.id.EVASION_OF_ARM,Seconds)
24779
+ end
24780
+ end
24781
+ return self
24782
+ end
24783
+ function CONTROLLABLE:OptionFormationInterval(meters)
24784
+ self:F2({self.ControllableName})
24785
+ local DCSControllable=self:GetDCSObject()
24786
+ if DCSControllable then
24787
+ local Controller=self:_GetController()
24788
+ if self:IsGround()then
24789
+ if meters==nil or meters>100 or meters<0 then meters=50 end
24790
+ Controller:setOption(30,meters)
24791
+ end
24792
+ end
24793
+ return self
24794
+ end
24521
24795
  function CONTROLLABLE:OptionECM(ECMvalue)
24522
24796
  self:F2({self.ControllableName})
24523
24797
  local DCSControllable=self:GetDCSObject()
@@ -25774,6 +26048,7 @@ local DCSGroup=Group.getByName(self.GroupName)
25774
26048
  if DCSGroup then
25775
26049
  return DCSGroup
25776
26050
  end
26051
+ self:T2(string.format("ERROR: Could not get DCS group object of group %s because DCS object could not be found!",tostring(self.GroupName)))
25777
26052
  return nil
25778
26053
  end
25779
26054
  function GROUP:GetPositionVec3()
@@ -26603,7 +26878,11 @@ return nil
26603
26878
  end
26604
26879
  function GROUP:GetTemplate()
26605
26880
  local GroupName=self:GetName()
26606
- return UTILS.DeepCopy(_DATABASE:GetGroupTemplate(GroupName))
26881
+ local template=_DATABASE:GetGroupTemplate(GroupName)
26882
+ if template then
26883
+ return UTILS.DeepCopy(template)
26884
+ end
26885
+ return nil
26607
26886
  end
26608
26887
  function GROUP:GetTemplateRoutePoints()
26609
26888
  local GroupName=self:GetName()
@@ -27111,7 +27390,7 @@ function GROUP:GetPlayerNames()
27111
27390
  local HasPlayers=false
27112
27391
  local PlayerNames={}
27113
27392
  local Units=self:GetUnits()
27114
- for UnitID,UnitData in pairs(Units)do
27393
+ for UnitID,UnitData in pairs(Units or{})do
27115
27394
  local Unit=UnitData
27116
27395
  local PlayerName=Unit:GetPlayerName()
27117
27396
  if PlayerName and PlayerName~=""then
@@ -27493,7 +27772,16 @@ end
27493
27772
  function UNIT:IsPlayer()
27494
27773
  local group=self:GetGroup()
27495
27774
  if not group then return false end
27496
- local units=group:GetTemplate().units
27775
+ local template=group:GetTemplate()
27776
+ if(template==nil)or(template.units==nil)then
27777
+ local DCSObject=self:GetDCSObject()
27778
+ if DCSObject then
27779
+ if DCSObject:getPlayerName()~=nil then return true else return false end
27780
+ else
27781
+ return false
27782
+ end
27783
+ end
27784
+ local units=template.units
27497
27785
  for _,unit in pairs(units)do
27498
27786
  if unit.name==self:GetName()and(unit.skill=="Client"or unit.skill=="Player")then
27499
27787
  return true
@@ -27671,6 +27959,8 @@ local nrockets=0
27671
27959
  local nmissiles=0
27672
27960
  local nbombs=0
27673
27961
  local narti=0
27962
+ local nAPshells=0
27963
+ local nHEshells=0
27674
27964
  local unit=self
27675
27965
  local ammotable=unit:GetAmmo()
27676
27966
  if ammotable then
@@ -27688,6 +27978,12 @@ nshells=nshells+Nammo
27688
27978
  if ammotable[w].desc.warhead and ammotable[w].desc.warhead.explosiveMass and ammotable[w].desc.warhead.explosiveMass>0 then
27689
27979
  narti=narti+Nammo
27690
27980
  end
27981
+ if ammotable[w].desc.typeName and string.find(ammotable[w].desc.typeName,"_AP",1,true)then
27982
+ nAPshells=nAPshells+Nammo
27983
+ end
27984
+ if ammotable[w].desc.typeName and string.find(ammotable[w].desc.typeName,"_HE",1,true)then
27985
+ nHEshells=nHEshells+Nammo
27986
+ end
27691
27987
  elseif Category==Weapon.Category.ROCKET then
27692
27988
  nrockets=nrockets+Nammo
27693
27989
  elseif Category==Weapon.Category.BOMB then
@@ -27710,7 +28006,31 @@ end
27710
28006
  end
27711
28007
  end
27712
28008
  nammo=nshells+nrockets+nmissiles+nbombs
27713
- return nammo,nshells,nrockets,nbombs,nmissiles,narti
28009
+ return nammo,nshells,nrockets,nbombs,nmissiles,narti,nAPshells,nHEshells
28010
+ end
28011
+ function UNIT:HasAPShells()
28012
+ local _,_,_,_,_,_,shells=self:GetAmmunition()
28013
+ if shells>0 then return true else return false end
28014
+ end
28015
+ function UNIT:GetAPShells()
28016
+ local _,_,_,_,_,_,shells=self:GetAmmunition()
28017
+ return shells or 0
28018
+ end
28019
+ function UNIT:GetHEShells()
28020
+ local _,_,_,_,_,_,_,shells=self:GetAmmunition()
28021
+ return shells or 0
28022
+ end
28023
+ function UNIT:HasHEShells()
28024
+ local _,_,_,_,_,_,_,shells=self:GetAmmunition()
28025
+ if shells>0 then return true else return false end
28026
+ end
28027
+ function UNIT:HasArtiShells()
28028
+ local _,_,_,_,_,shells=self:GetAmmunition()
28029
+ if shells>0 then return true else return false end
28030
+ end
28031
+ function UNIT:GetArtiShells()
28032
+ local _,_,_,_,_,shells=self:GetAmmunition()
28033
+ return shells or 0
27714
28034
  end
27715
28035
  function UNIT:GetSensors()
27716
28036
  self:F2(self.UnitName)
@@ -27850,17 +28170,17 @@ if Descriptor then
27850
28170
  local Attributes=Descriptor.attributes
27851
28171
  if self:IsGround()then
27852
28172
  local ThreatLevels={
27853
- "Unarmed",
27854
- "Infantry",
27855
- "Old Tanks & APCs",
27856
- "Tanks & IFVs without ATGM",
27857
- "Tanks & IFV with ATGM",
27858
- "Modern Tanks",
27859
- "AAA",
27860
- "IR Guided SAMs",
27861
- "SR SAMs",
27862
- "MR SAMs",
27863
- "LR SAMs"
28173
+ [1]="Unarmed",
28174
+ [2]="Infantry",
28175
+ [3]="Old Tanks & APCs",
28176
+ [4]="Tanks & IFVs without ATGM",
28177
+ [5]="Tanks & IFV with ATGM",
28178
+ [6]="Modern Tanks",
28179
+ [7]="AAA",
28180
+ [8]="IR Guided SAMs",
28181
+ [9]="SR SAMs",
28182
+ [10]="MR SAMs",
28183
+ [11]="LR SAMs"
27864
28184
  }
27865
28185
  if Attributes["LR SAM"]then ThreatLevel=10
27866
28186
  elseif Attributes["MR SAM"]then ThreatLevel=9
@@ -27881,17 +28201,17 @@ ThreatText=ThreatLevels[ThreatLevel+1]
27881
28201
  end
27882
28202
  if self:IsAir()then
27883
28203
  local ThreatLevels={
27884
- "Unarmed",
27885
- "Tanker",
27886
- "AWACS",
27887
- "Transport Helicopter",
27888
- "UAV",
27889
- "Bomber",
27890
- "Strategic Bomber",
27891
- "Attack Helicopter",
27892
- "Battleplane",
27893
- "Multirole Fighter",
27894
- "Fighter"
28204
+ [1]="Unarmed",
28205
+ [2]="Tanker",
28206
+ [3]="AWACS",
28207
+ [4]="Transport Helicopter",
28208
+ [5]="UAV",
28209
+ [6]="Bomber",
28210
+ [7]="Strategic Bomber",
28211
+ [8]="Attack Helicopter",
28212
+ [9]="Battleplane",
28213
+ [10]="Multirole Fighter",
28214
+ [11]="Fighter"
27895
28215
  }
27896
28216
  if Attributes["Fighters"]then ThreatLevel=10
27897
28217
  elseif Attributes["Multirole fighters"]then ThreatLevel=9
@@ -27910,17 +28230,17 @@ ThreatText=ThreatLevels[ThreatLevel+1]
27910
28230
  end
27911
28231
  if self:IsShip()then
27912
28232
  local ThreatLevels={
27913
- "Unarmed ship",
27914
- "Light armed ships",
27915
- "Corvettes",
27916
- "",
27917
- "Frigates",
27918
- "",
27919
- "Cruiser",
27920
- "",
27921
- "Destroyer",
27922
- "",
27923
- "Aircraft Carrier"
28233
+ [1]="Unarmed ship",
28234
+ [2]="Light armed ships",
28235
+ [3]="Corvettes",
28236
+ [4]="",
28237
+ [5]="Frigates",
28238
+ [6]="",
28239
+ [7]="Cruiser",
28240
+ [8]="",
28241
+ [9]="Destroyer",
28242
+ [10]="",
28243
+ [11]="Aircraft Carrier"
27924
28244
  }
27925
28245
  if Attributes["Aircraft Carriers"]then ThreatLevel=10
27926
28246
  elseif Attributes["Destroyers"]then ThreatLevel=8
@@ -28191,6 +28511,9 @@ function CLIENT:AddPlayer(PlayerName)
28191
28511
  table.insert(self.Players,PlayerName)
28192
28512
  return self
28193
28513
  end
28514
+ function CLIENT:CountPlayers()
28515
+ return#self.Players or 0
28516
+ end
28194
28517
  function CLIENT:GetPlayers()
28195
28518
  return self.Players
28196
28519
  end
@@ -28259,7 +28582,7 @@ self.AliveCheckScheduler:NoTrace()
28259
28582
  return self
28260
28583
  end
28261
28584
  function CLIENT:_AliveCheckScheduler(SchedulerName)
28262
- self:F3({SchedulerName,self.ClientName,self.ClientAlive2,self.ClientBriefingShown,self.ClientCallBack})
28585
+ self:T2({SchedulerName,self.ClientName,self.ClientAlive2,self.ClientBriefingShown,self.ClientCallBack})
28263
28586
  if self:IsAlive()then
28264
28587
  if self.ClientAlive2==false then
28265
28588
  self:ShowBriefing()
@@ -28546,6 +28869,20 @@ end
28546
28869
  end
28547
28870
  return GroupsFound
28548
28871
  end
28872
+ function STATIC:GetStaticStorage()
28873
+ local name=self:GetName()
28874
+ local storage=STORAGE:NewFromStaticCargo(name)
28875
+ return storage
28876
+ end
28877
+ function STATIC:GetCargoWeight()
28878
+ local DCSObject=StaticObject.getByName(self.StaticName)
28879
+ local mass=-1
28880
+ if DCSObject then
28881
+ mass=DCSObject:getCargoWeight()or 0
28882
+ local masstxt=DCSObject:getCargoDisplayName()or"none"
28883
+ end
28884
+ return mass
28885
+ end
28549
28886
  AIRBASE={
28550
28887
  ClassName="AIRBASE",
28551
28888
  CategoryName={
@@ -28803,7 +29140,6 @@ AIRBASE.MarianaIslands={
28803
29140
  }
28804
29141
  AIRBASE.SouthAtlantic={
28805
29142
  ["Almirante_Schroeders"]="Almirante Schroeders",
28806
- ["Caleta_Tortel"]="Caleta Tortel",
28807
29143
  ["Comandante_Luis_Piedrabuena"]="Comandante Luis Piedrabuena",
28808
29144
  ["Cullen"]="Cullen",
28809
29145
  ["El_Calafate"]="El Calafate",
@@ -28834,38 +29170,52 @@ AIRBASE.SouthAtlantic={
28834
29170
  AIRBASE.Sinai={
28835
29171
  ["Abu_Rudeis"]="Abu Rudeis",
28836
29172
  ["Abu_Suwayr"]="Abu Suwayr",
29173
+ ["Al_Bahr_al_Ahmar"]="Al Bahr al Ahmar",
28837
29174
  ["Al_Ismailiyah"]="Al Ismailiyah",
29175
+ ["Al_Khatatbah"]="Al Khatatbah",
28838
29176
  ["Al_Mansurah"]="Al Mansurah",
29177
+ ["Al_Rahmaniyah_Air_Base"]="Al Rahmaniyah Air Base",
28839
29178
  ["As_Salihiyah"]="As Salihiyah",
28840
29179
  ["AzZaqaziq"]="AzZaqaziq",
28841
29180
  ["Baluza"]="Baluza",
28842
29181
  ["Ben_Gurion"]="Ben-Gurion",
29182
+ ["Beni_Suef"]="Beni Suef",
28843
29183
  ["Bilbeis_Air_Base"]="Bilbeis Air Base",
28844
29184
  ["Bir_Hasanah"]="Bir Hasanah",
29185
+ ["Birma_Air_Base"]="Birma Air Base",
29186
+ ["Borj_El_Arab_International_Airport"]="Borj El Arab International Airport",
28845
29187
  ["Cairo_International_Airport"]="Cairo International Airport",
28846
29188
  ["Cairo_West"]="Cairo West",
28847
29189
  ["Difarsuwar_Airfield"]="Difarsuwar Airfield",
28848
29190
  ["El_Arish"]="El Arish",
28849
29191
  ["El_Gora"]="El Gora",
29192
+ ["El_Minya"]="El Minya",
28850
29193
  ["Fayed"]="Fayed",
29194
+ ["Gebel_El_Basur_Air_Base"]="Gebel El Basur Air Base",
28851
29195
  ["Hatzerim"]="Hatzerim",
28852
29196
  ["Hatzor"]="Hatzor",
29197
+ ["Hurghada_International_Airport"]="Hurghada International Airport",
28853
29198
  ["Inshas_Airbase"]="Inshas Airbase",
29199
+ ["Jiyanklis_Air_Base"]="Jiyanklis Air Base",
28854
29200
  ["Kedem"]="Kedem",
28855
29201
  ["Kibrit_Air_Base"]="Kibrit Air Base",
29202
+ ["Kom_Awshim"]="Kom Awshim",
28856
29203
  ["Melez"]="Melez",
28857
29204
  ["Nevatim"]="Nevatim",
28858
29205
  ["Ovda"]="Ovda",
28859
- ["Palmahim"]="Palmahim",
29206
+ ["Palmachim"]="Palmachim",
29207
+ ["Quwaysina"]="Quwaysina",
28860
29208
  ["Ramon_Airbase"]="Ramon Airbase",
29209
+ ["Ramon_International_Airport"]="Ramon International Airport",
28861
29210
  ["Sde_Dov"]="Sde Dov",
29211
+ ["Sharm_El_Sheikh_International_Airport"]="Sharm El Sheikh International Airport",
28862
29212
  ["St_Catherine"]="St Catherine",
28863
29213
  ["Tel_Nof"]="Tel Nof",
29214
+ ["Wadi_Abu_Rish"]="Wadi Abu Rish",
28864
29215
  ["Wadi_al_Jandali"]="Wadi al Jandali",
28865
29216
  }
28866
29217
  AIRBASE.Kola={
28867
29218
  ["Banak"]="Banak",
28868
- ["Bas_100"]="Bas 100",
28869
29219
  ["Bodo"]="Bodo",
28870
29220
  ["Jokkmokk"]="Jokkmokk",
28871
29221
  ["Kalixfors"]="Kalixfors",
@@ -28877,6 +29227,27 @@ AIRBASE.Kola={
28877
29227
  ["Rovaniemi"]="Rovaniemi",
28878
29228
  ["Severomorsk_1"]="Severomorsk-1",
28879
29229
  ["Severomorsk_3"]="Severomorsk-3",
29230
+ ["Vuojarvi"]="Vuojarvi",
29231
+ ["Kirkenes"]="Kirkenes",
29232
+ ["Kallax"]="Kallax",
29233
+ ["Vidsel"]="Vidsel",
29234
+ }
29235
+ AIRBASE.Afghanistan={
29236
+ ["Bost"]="Bost",
29237
+ ["Camp_Bastion"]="Camp Bastion",
29238
+ ["Camp_Bastion_Heliport"]="Camp Bastion Heliport",
29239
+ ["Chaghcharan"]="Chaghcharan",
29240
+ ["Dwyer"]="Dwyer",
29241
+ ["Farah"]="Farah",
29242
+ ["Herat"]="Herat",
29243
+ ["Kandahar"]="Kandahar",
29244
+ ["Kandahar_Heliport"]="Kandahar Heliport",
29245
+ ["Maymana_Zahiraddin_Faryabi"]="Maymana Zahiraddin Faryabi",
29246
+ ["Nimroz"]="Nimroz",
29247
+ ["Qala_i_Naw"]="Qala i Naw",
29248
+ ["Shindand"]="Shindand",
29249
+ ["Shindand_Heliport"]="Shindand Heliport",
29250
+ ["Tarinkot"]="Tarinkot",
28880
29251
  }
28881
29252
  AIRBASE.TerminalType={
28882
29253
  Runway=16,
@@ -29234,7 +29605,7 @@ function AIRBASE:GetFreeParkingSpotsTable(termtype,allowTOAC)
29234
29605
  local parkingfree=self:GetParkingData(true)
29235
29606
  local freespots={}
29236
29607
  for _,_spot in pairs(parkingfree)do
29237
- if AIRBASE._CheckTerminalType(_spot.Term_Type,termtype)and _spot.Term_Index>0 then
29608
+ if AIRBASE._CheckTerminalType(_spot.Term_Type,termtype)then
29238
29609
  if(allowTOAC and allowTOAC==true)or _spot.TO_AC==false then
29239
29610
  local spot=self:_GetParkingSpotByID(_spot.Term_Index)
29240
29611
  spot.Free=true
@@ -30988,7 +31359,18 @@ GASOLINE=1,
30988
31359
  MW50=2,
30989
31360
  DIESEL=3,
30990
31361
  }
30991
- STORAGE.version="0.0.1"
31362
+ STORAGE.LiquidName={
31363
+ GASOLINE="gasoline",
31364
+ DIESEL="diesel",
31365
+ MW50="methanol_mixture",
31366
+ JETFUEL="jet_fuel",
31367
+ }
31368
+ STORAGE.Type={
31369
+ WEAPONS="weapons",
31370
+ LIQUIDS="liquids",
31371
+ AIRCRAFT="aircrafts",
31372
+ }
31373
+ STORAGE.version="0.0.3"
30992
31374
  function STORAGE:New(AirbaseName)
30993
31375
  local self=BASE:Inherit(self,BASE:New())
30994
31376
  self.airbase=Airbase.getByName(AirbaseName)
@@ -30998,6 +31380,15 @@ end
30998
31380
  self.lid=string.format("STORAGE %s",AirbaseName)
30999
31381
  return self
31000
31382
  end
31383
+ function STORAGE:NewFromStaticCargo(StaticCargoName)
31384
+ local self=BASE:Inherit(self,BASE:New())
31385
+ self.airbase=StaticObject.getByName(StaticCargoName)
31386
+ if Airbase.getWarehouse then
31387
+ self.warehouse=Warehouse.getCargoAsWarehouse(self.airbase)
31388
+ end
31389
+ self.lid=string.format("STORAGE %s",StaticCargoName)
31390
+ return self
31391
+ end
31001
31392
  function STORAGE:FindByName(AirbaseName)
31002
31393
  local storage=_DATABASE:FindStorage(AirbaseName)
31003
31394
  return storage
@@ -31098,7 +31489,7 @@ local unlimited=false
31098
31489
  if N>0 then
31099
31490
  self:RemoveAmount(Type,1)
31100
31491
  local n=self:GetAmount(Type)
31101
- unlimited=n==N
31492
+ unlimited=unlimited or n>2^29 or n==N
31102
31493
  if not unlimited then
31103
31494
  self:AddAmount(Type,1)
31104
31495
  end
@@ -35883,7 +36274,7 @@ function DETECTION_BASE:onafterStart(From,Event,To)
35883
36274
  self:__Detect(1)
35884
36275
  end
35885
36276
  function DETECTION_BASE:onafterDetect(From,Event,To)
35886
- local DetectDelay=0.1
36277
+ local DetectDelay=0.15
35887
36278
  self.DetectionCount=0
35888
36279
  self.DetectionRun=0
35889
36280
  self:UnIdentifyAllDetectedObjects()
@@ -35914,13 +36305,15 @@ self.DetectionSet:ForEachGroupAlive(IteratorFunction,arg)
35914
36305
  return self
35915
36306
  end
35916
36307
  function DETECTION_BASE:onafterDetection(From,Event,To,Detection,DetectionTimeStamp)
36308
+ self:T({DetectedObjects=self.DetectedObjects})
35917
36309
  self.DetectionRun=self.DetectionRun+1
35918
36310
  local HasDetectedObjects=false
35919
36311
  if Detection and Detection:IsAlive()then
36312
+ self:T({"DetectionGroup is Alive",Detection:GetName()})
35920
36313
  local DetectionGroupName=Detection:GetName()
35921
36314
  local DetectionUnit=Detection:GetUnit(1)
35922
36315
  local DetectedUnits={}
35923
- local DetectedTargets=Detection:GetDetectedTargets(
36316
+ local DetectedTargets=DetectionUnit:GetDetectedTargets(
35924
36317
  self.DetectVisual,
35925
36318
  self.DetectOptical,
35926
36319
  self.DetectRadar,
@@ -35928,7 +36321,6 @@ self.DetectIRST,
35928
36321
  self.DetectRWR,
35929
36322
  self.DetectDLINK
35930
36323
  )
35931
- self:F({DetectedTargets=DetectedTargets})
35932
36324
  for DetectionObjectID,Detection in pairs(DetectedTargets)do
35933
36325
  local DetectedObject=Detection.object
35934
36326
  if DetectedObject and DetectedObject:isExist()and DetectedObject.id_<50000000 then
@@ -37857,7 +38249,6 @@ local DetectedItem=self.Detection:GetDetectedItemByIndex(Index)
37857
38249
  local TargetSetUnit=self.Detection:GetDetectedItemSet(DetectedItem)
37858
38250
  local MarkingCount=0
37859
38251
  local MarkedTypes={}
37860
- TargetSetUnit:Flush(self)
37861
38252
  for TargetUnit,RecceData in pairs(self.Recces)do
37862
38253
  local Recce=RecceData
37863
38254
  self:F({TargetUnit=TargetUnit,Recce=Recce:GetName()})
@@ -37882,6 +38273,7 @@ break
37882
38273
  end
37883
38274
  end
37884
38275
  end
38276
+ if TargetSetUnit==nil then return end
37885
38277
  if self.AutoLase or(not self.AutoLase and(self.LaseStart+Duration>=timer.getTime()))then
37886
38278
  TargetSetUnit:ForEachUnitPerThreatLevel(10,0,
37887
38279
  function(TargetUnit)
@@ -37908,14 +38300,15 @@ self.LaserCodesUsed[LaserCode]=LaserCodeIndex
37908
38300
  local Spot=RecceUnit:LaseUnit(TargetUnit,LaserCode,Duration)
37909
38301
  local AttackSet=self.AttackSet
37910
38302
  local DesignateName=self.DesignateName
38303
+ local typename=TargetUnit:GetTypeName()
37911
38304
  function Spot:OnAfterDestroyed(From,Event,To)
37912
- self.Recce:MessageToSetGroup("Target "..TargetUnit:GetTypeName().." destroyed. "..TargetSetUnit:Count().." targets left.",
38305
+ self.Recce:MessageToSetGroup("Target "..typename.." destroyed. "..TargetSetUnit:CountAlive().." targets left.",
37913
38306
  5,AttackSet,self.DesignateName)
37914
38307
  end
37915
38308
  self.Recces[TargetUnit]=RecceUnit
37916
38309
  MarkingCount=MarkingCount+1
37917
38310
  local TargetUnitType=TargetUnit:GetTypeName()
37918
- RecceUnit:MessageToSetGroup("Marking "..TargetUnit:GetTypeName().." with laser "..RecceUnit:GetSpot().LaserCode.." for "..Duration.."s.",
38311
+ RecceUnit:MessageToSetGroup("Marking "..TargetUnitType.." with laser "..RecceUnit:GetSpot().LaserCode.." for "..Duration.."s.",
37919
38312
  10,self.AttackSet,DesignateName)
37920
38313
  if not MarkedTypes[TargetUnitType]then
37921
38314
  MarkedTypes[TargetUnitType]=true
@@ -38026,9 +38419,11 @@ end
38026
38419
  end
38027
38420
  end
38028
38421
  function DESIGNATE:onafterDoneSmoking(From,Event,To,Index)
38422
+ if self.Designating[Index]~=nil then
38029
38423
  self.Designating[Index]=string.gsub(self.Designating[Index],"S","")
38030
38424
  self:SetDesignateMenu()
38031
38425
  end
38426
+ end
38032
38427
  function DESIGNATE:onafterDoneIlluminating(From,Event,To,Index)
38033
38428
  self.Designating[Index]=string.gsub(self.Designating[Index],"I","")
38034
38429
  self:SetDesignateMenu()
@@ -39043,6 +39438,10 @@ elseif DCStype=="Mirage-F1CE"then
39043
39438
  self.aircraft.length=16
39044
39439
  self.aircraft.height=5
39045
39440
  self.aircraft.width=9
39441
+ elseif DCStype=="Saab340"then
39442
+ self.aircraft.length=19.73
39443
+ self.aircraft.height=6.97
39444
+ self.aircraft.width=21.44
39046
39445
  end
39047
39446
  self.aircraft.box=math.max(self.aircraft.length,self.aircraft.width)
39048
39447
  local text=string.format("\n******************************************************\n")
@@ -41550,7 +41949,7 @@ IRExitRange={filename="IR-ExitRange.ogg",duration=3.10},
41550
41949
  RANGE.Names={}
41551
41950
  RANGE.MenuF10={}
41552
41951
  RANGE.MenuF10Root=nil
41553
- RANGE.version="2.7.3"
41952
+ RANGE.version="2.8.0"
41554
41953
  function RANGE:New(RangeName,Coalition)
41555
41954
  local self=BASE:Inherit(self,FSM:New())
41556
41955
  self.rangename=RangeName or"Practice Range"
@@ -41616,32 +42015,32 @@ end
41616
42015
  if self.rangecontrolfreq and not self.useSRS then
41617
42016
  self.rangecontrol=RADIOQUEUE:New(self.rangecontrolfreq,nil,self.rangename)
41618
42017
  self.rangecontrol.schedonce=true
41619
- self.rangecontrol:SetDigit(0,RANGE.Sound.RC0.filename,RANGE.Sound.RC0.duration,self.soundpath)
41620
- self.rangecontrol:SetDigit(1,RANGE.Sound.RC1.filename,RANGE.Sound.RC1.duration,self.soundpath)
41621
- self.rangecontrol:SetDigit(2,RANGE.Sound.RC2.filename,RANGE.Sound.RC2.duration,self.soundpath)
41622
- self.rangecontrol:SetDigit(3,RANGE.Sound.RC3.filename,RANGE.Sound.RC3.duration,self.soundpath)
41623
- self.rangecontrol:SetDigit(4,RANGE.Sound.RC4.filename,RANGE.Sound.RC4.duration,self.soundpath)
41624
- self.rangecontrol:SetDigit(5,RANGE.Sound.RC5.filename,RANGE.Sound.RC5.duration,self.soundpath)
41625
- self.rangecontrol:SetDigit(6,RANGE.Sound.RC6.filename,RANGE.Sound.RC6.duration,self.soundpath)
41626
- self.rangecontrol:SetDigit(7,RANGE.Sound.RC7.filename,RANGE.Sound.RC7.duration,self.soundpath)
41627
- self.rangecontrol:SetDigit(8,RANGE.Sound.RC8.filename,RANGE.Sound.RC8.duration,self.soundpath)
41628
- self.rangecontrol:SetDigit(9,RANGE.Sound.RC9.filename,RANGE.Sound.RC9.duration,self.soundpath)
42018
+ self.rangecontrol:SetDigit(0,self.Sound.RC0.filename,self.Sound.RC0.duration,self.soundpath)
42019
+ self.rangecontrol:SetDigit(1,self.Sound.RC1.filename,self.Sound.RC1.duration,self.soundpath)
42020
+ self.rangecontrol:SetDigit(2,self.Sound.RC2.filename,self.Sound.RC2.duration,self.soundpath)
42021
+ self.rangecontrol:SetDigit(3,self.Sound.RC3.filename,self.Sound.RC3.duration,self.soundpath)
42022
+ self.rangecontrol:SetDigit(4,self.Sound.RC4.filename,self.Sound.RC4.duration,self.soundpath)
42023
+ self.rangecontrol:SetDigit(5,self.Sound.RC5.filename,self.Sound.RC5.duration,self.soundpath)
42024
+ self.rangecontrol:SetDigit(6,self.Sound.RC6.filename,self.Sound.RC6.duration,self.soundpath)
42025
+ self.rangecontrol:SetDigit(7,self.Sound.RC7.filename,self.Sound.RC7.duration,self.soundpath)
42026
+ self.rangecontrol:SetDigit(8,self.Sound.RC8.filename,self.Sound.RC8.duration,self.soundpath)
42027
+ self.rangecontrol:SetDigit(9,self.Sound.RC9.filename,self.Sound.RC9.duration,self.soundpath)
41629
42028
  self.rangecontrol:SetSenderCoordinate(self.location)
41630
42029
  self.rangecontrol:SetSenderUnitName(self.rangecontrolrelayname)
41631
42030
  self.rangecontrol:Start(1,0.1)
41632
42031
  if self.instructorfreq and not self.useSRS then
41633
42032
  self.instructor=RADIOQUEUE:New(self.instructorfreq,nil,self.rangename)
41634
42033
  self.instructor.schedonce=true
41635
- self.instructor:SetDigit(0,RANGE.Sound.IR0.filename,RANGE.Sound.IR0.duration,self.soundpath)
41636
- self.instructor:SetDigit(1,RANGE.Sound.IR1.filename,RANGE.Sound.IR1.duration,self.soundpath)
41637
- self.instructor:SetDigit(2,RANGE.Sound.IR2.filename,RANGE.Sound.IR2.duration,self.soundpath)
41638
- self.instructor:SetDigit(3,RANGE.Sound.IR3.filename,RANGE.Sound.IR3.duration,self.soundpath)
41639
- self.instructor:SetDigit(4,RANGE.Sound.IR4.filename,RANGE.Sound.IR4.duration,self.soundpath)
41640
- self.instructor:SetDigit(5,RANGE.Sound.IR5.filename,RANGE.Sound.IR5.duration,self.soundpath)
41641
- self.instructor:SetDigit(6,RANGE.Sound.IR6.filename,RANGE.Sound.IR6.duration,self.soundpath)
41642
- self.instructor:SetDigit(7,RANGE.Sound.IR7.filename,RANGE.Sound.IR7.duration,self.soundpath)
41643
- self.instructor:SetDigit(8,RANGE.Sound.IR8.filename,RANGE.Sound.IR8.duration,self.soundpath)
41644
- self.instructor:SetDigit(9,RANGE.Sound.IR9.filename,RANGE.Sound.IR9.duration,self.soundpath)
42034
+ self.instructor:SetDigit(0,self.Sound.IR0.filename,self.Sound.IR0.duration,self.soundpath)
42035
+ self.instructor:SetDigit(1,self.Sound.IR1.filename,self.Sound.IR1.duration,self.soundpath)
42036
+ self.instructor:SetDigit(2,self.Sound.IR2.filename,self.Sound.IR2.duration,self.soundpath)
42037
+ self.instructor:SetDigit(3,self.Sound.IR3.filename,self.Sound.IR3.duration,self.soundpath)
42038
+ self.instructor:SetDigit(4,self.Sound.IR4.filename,self.Sound.IR4.duration,self.soundpath)
42039
+ self.instructor:SetDigit(5,self.Sound.IR5.filename,self.Sound.IR5.duration,self.soundpath)
42040
+ self.instructor:SetDigit(6,self.Sound.IR6.filename,self.Sound.IR6.duration,self.soundpath)
42041
+ self.instructor:SetDigit(7,self.Sound.IR7.filename,self.Sound.IR7.duration,self.soundpath)
42042
+ self.instructor:SetDigit(8,self.Sound.IR8.filename,self.Sound.IR8.duration,self.soundpath)
42043
+ self.instructor:SetDigit(9,self.Sound.IR9.filename,self.Sound.IR9.duration,self.soundpath)
41645
42044
  self.instructor:SetSenderCoordinate(self.location)
41646
42045
  self.instructor:SetSenderUnitName(self.instructorrelayname)
41647
42046
  self.instructor:Start(1,0.1)
@@ -41657,7 +42056,11 @@ self:_SmokeStrafeTargets()
41657
42056
  self:_SmokeStrafeTargetBoxes()
41658
42057
  self.rangezone:SmokeZone(SMOKECOLOR.White)
41659
42058
  end
41660
- self:__Status(-60)
42059
+ self:__Status(-10)
42060
+ end
42061
+ function RANGE:SetMenuRoot(menu)
42062
+ self.menuF10root=menu
42063
+ return self
41661
42064
  end
41662
42065
  function RANGE:SetMaxStrafeAlt(maxalt)
41663
42066
  self.strafemaxalt=maxalt or RANGE.Defaults.strafemaxalt
@@ -41723,6 +42126,9 @@ self.location=coordinate
41723
42126
  return self
41724
42127
  end
41725
42128
  function RANGE:SetRangeZone(zone)
42129
+ if zone and type(zone)=="string"then
42130
+ zone=ZONE:FindByName(zone)
42131
+ end
41726
42132
  self.rangezone=zone
41727
42133
  return self
41728
42134
  end
@@ -41802,8 +42208,10 @@ self.instructmsrs:SetLabel("RANGEI")
41802
42208
  self.instructmsrs:SetVolume(Volume or 1.0)
41803
42209
  self.instructsrsQ=MSRSQUEUE:New("INSTRUCT")
41804
42210
  if PathToGoogleKey then
41805
- self.controlmsrs:SetGoogle(PathToGoogleKey)
41806
- self.instructmsrs:SetGoogle(PathToGoogleKey)
42211
+ self.controlmsrs:SetProviderOptionsGoogle(PathToGoogleKey,PathToGoogleKey)
42212
+ self.controlmsrs:SetProvider(MSRS.Provider.GOOGLE)
42213
+ self.instructmsrs:SetProviderOptionsGoogle(PathToGoogleKey,PathToGoogleKey)
42214
+ self.instructmsrs:SetProvider(MSRS.Provider.GOOGLE)
41807
42215
  end
41808
42216
  else
41809
42217
  self:E(self.lid..string.format("ERROR: No SRS path specified!"))
@@ -41864,6 +42272,31 @@ self.soundpath=tostring(path or"Range Soundfiles/")
41864
42272
  self:I(self.lid..string.format("Setting sound files path to %s",self.soundpath))
41865
42273
  return self
41866
42274
  end
42275
+ function RANGE:SetSoundfilesInfo(csvfile)
42276
+ local function getSound(filename)
42277
+ for key,_soundfile in pairs(self.Sound)do
42278
+ local soundfile=_soundfile
42279
+ if filename==soundfile.filename then
42280
+ return soundfile
42281
+ end
42282
+ end
42283
+ return nil
42284
+ end
42285
+ local data=UTILS.ReadCSV(csvfile)
42286
+ if data then
42287
+ for i,sound in pairs(data)do
42288
+ local soundfile=getSound(sound.filename..".ogg")
42289
+ if soundfile then
42290
+ soundfile.duration=tonumber(sound.duration)
42291
+ else
42292
+ self:E(string.format("ERROR: Could not get info for sound file %s",sound.filename))
42293
+ end
42294
+ end
42295
+ else
42296
+ self:E(string.format("ERROR: Could not read sound csv file!"))
42297
+ end
42298
+ return self
42299
+ end
41867
42300
  function RANGE:AddStrafePit(targetnames,boxlength,boxwidth,heading,inverseheading,goodpass,foulline)
41868
42301
  self:F({targetnames=targetnames,boxlength=boxlength,boxwidth=boxwidth,heading=heading,inverseheading=inverseheading,goodpass=goodpass,foulline=foulline})
41869
42302
  if type(targetnames)~="table"then
@@ -42045,6 +42478,9 @@ return self
42045
42478
  end
42046
42479
  function RANGE:AddBombingTargetGroup(group,goodhitrange,randommove)
42047
42480
  self:F({group=group,goodhitrange=goodhitrange,randommove=randommove})
42481
+ if group and type(group)=="string"then
42482
+ group=GROUP:FindByName(group)
42483
+ end
42048
42484
  if group then
42049
42485
  local _units=group:GetUnits()
42050
42486
  for _,_unit in pairs(_units)do
@@ -42258,7 +42694,7 @@ if self.rangecontrol then
42258
42694
  if self.useSRS then
42259
42695
  self.controlsrsQ:NewTransmission(_message,nil,self.controlmsrs,nil,1)
42260
42696
  else
42261
- self.rangecontrol:NewTransmission(RANGE.Sound.RCWeaponImpactedTooFar.filename,RANGE.Sound.RCWeaponImpactedTooFar.duration,self.soundpath,nil,nil,_message,self.subduration)
42697
+ self.rangecontrol:NewTransmission(self.Sound.RCWeaponImpactedTooFar.filename,self.Sound.RCWeaponImpactedTooFar.duration,self.soundpath,nil,nil,_message,self.subduration)
42262
42698
  end
42263
42699
  end
42264
42700
  else
@@ -42329,13 +42765,13 @@ local group=player.client:GetGroup()
42329
42765
  self.instructsrsQ:NewTransmission(ttstext,nil,self.instructmsrs,nil,1,{group},text,10)
42330
42766
  else
42331
42767
  local RF=UTILS.Split(string.format("%.3f",self.rangecontrolfreq),".")
42332
- self.instructor:NewTransmission(RANGE.Sound.IREnterRange.filename,RANGE.Sound.IREnterRange.duration,self.soundpath)
42768
+ self.instructor:NewTransmission(self.Sound.IREnterRange.filename,self.Sound.IREnterRange.duration,self.soundpath)
42333
42769
  self.instructor:Number2Transmission(RF[1])
42334
42770
  if tonumber(RF[2])>0 then
42335
- self.instructor:NewTransmission(RANGE.Sound.IRDecimal.filename,RANGE.Sound.IRDecimal.duration,self.soundpath)
42771
+ self.instructor:NewTransmission(self.Sound.IRDecimal.filename,self.Sound.IRDecimal.duration,self.soundpath)
42336
42772
  self.instructor:Number2Transmission(RF[2])
42337
42773
  end
42338
- self.instructor:NewTransmission(RANGE.Sound.IRMegaHertz.filename,RANGE.Sound.IRMegaHertz.duration,self.soundpath)
42774
+ self.instructor:NewTransmission(self.Sound.IRMegaHertz.filename,self.Sound.IRMegaHertz.duration,self.soundpath)
42339
42775
  end
42340
42776
  end
42341
42777
  end
@@ -42357,7 +42793,7 @@ text=text.."!"
42357
42793
  end
42358
42794
  self.instructsrsQ:NewTransmission(text,nil,self.instructmsrs,nil,1,{player.client:GetGroup()},text,10)
42359
42795
  else
42360
- self.instructor:NewTransmission(RANGE.Sound.IRExitRange.filename,RANGE.Sound.IRExitRange.duration,self.soundpath)
42796
+ self.instructor:NewTransmission(self.Sound.IRExitRange.filename,self.Sound.IRExitRange.duration,self.soundpath)
42361
42797
  end
42362
42798
  end
42363
42799
  end
@@ -42378,20 +42814,20 @@ if self.useSRS then
42378
42814
  local group=player.client:GetGroup()
42379
42815
  self.controlsrsQ:NewTransmission(text,nil,self.controlmsrs,nil,1,{group},text,10)
42380
42816
  else
42381
- self.rangecontrol:NewTransmission(RANGE.Sound.RCImpact.filename,RANGE.Sound.RCImpact.duration,self.soundpath,nil,nil,text,self.subduration)
42817
+ self.rangecontrol:NewTransmission(self.Sound.RCImpact.filename,self.Sound.RCImpact.duration,self.soundpath,nil,nil,text,self.subduration)
42382
42818
  self.rangecontrol:Number2Transmission(string.format("%03d",result.radial),nil,0.1)
42383
- self.rangecontrol:NewTransmission(RANGE.Sound.RCDegrees.filename,RANGE.Sound.RCDegrees.duration,self.soundpath)
42384
- self.rangecontrol:NewTransmission(RANGE.Sound.RCFor.filename,RANGE.Sound.RCFor.duration,self.soundpath)
42819
+ self.rangecontrol:NewTransmission(self.Sound.RCDegrees.filename,self.Sound.RCDegrees.duration,self.soundpath)
42820
+ self.rangecontrol:NewTransmission(self.Sound.RCFor.filename,self.Sound.RCFor.duration,self.soundpath)
42385
42821
  self.rangecontrol:Number2Transmission(string.format("%d",UTILS.MetersToFeet(result.distance)))
42386
- self.rangecontrol:NewTransmission(RANGE.Sound.RCFeet.filename,RANGE.Sound.RCFeet.duration,self.soundpath)
42822
+ self.rangecontrol:NewTransmission(self.Sound.RCFeet.filename,self.Sound.RCFeet.duration,self.soundpath)
42387
42823
  if result.quality=="POOR"then
42388
- self.rangecontrol:NewTransmission(RANGE.Sound.RCPoorHit.filename,RANGE.Sound.RCPoorHit.duration,self.soundpath,nil,0.5)
42824
+ self.rangecontrol:NewTransmission(self.Sound.RCPoorHit.filename,self.Sound.RCPoorHit.duration,self.soundpath,nil,0.5)
42389
42825
  elseif result.quality=="INEFFECTIVE"then
42390
- self.rangecontrol:NewTransmission(RANGE.Sound.RCIneffectiveHit.filename,RANGE.Sound.RCIneffectiveHit.duration,self.soundpath,nil,0.5)
42826
+ self.rangecontrol:NewTransmission(self.Sound.RCIneffectiveHit.filename,self.Sound.RCIneffectiveHit.duration,self.soundpath,nil,0.5)
42391
42827
  elseif result.quality=="GOOD"then
42392
- self.rangecontrol:NewTransmission(RANGE.Sound.RCGoodHit.filename,RANGE.Sound.RCGoodHit.duration,self.soundpath,nil,0.5)
42828
+ self.rangecontrol:NewTransmission(self.Sound.RCGoodHit.filename,self.Sound.RCGoodHit.duration,self.soundpath,nil,0.5)
42393
42829
  elseif result.quality=="EXCELLENT"then
42394
- self.rangecontrol:NewTransmission(RANGE.Sound.RCExcellentHit.filename,RANGE.Sound.RCExcellentHit.duration,self.soundpath,nil,0.5)
42830
+ self.rangecontrol:NewTransmission(self.Sound.RCExcellentHit.filename,self.Sound.RCExcellentHit.duration,self.soundpath,nil,0.5)
42395
42831
  end
42396
42832
  end
42397
42833
  end
@@ -42431,7 +42867,7 @@ else
42431
42867
  self:E(self.lid..string.format("ERROR: Could not save results to file %s",tostring(filename)))
42432
42868
  end
42433
42869
  end
42434
- local path=lfs.writedir()..[[Logs\]]
42870
+ local path=self.targetpath or lfs.writedir()..[[Logs\]]
42435
42871
  local filename=path..string.format("RANGE-%s_BombingResults.csv",self.rangename)
42436
42872
  local scores="Name,Pass,Target,Distance,Radial,Quality,Weapon,Airframe,Mission Time"
42437
42873
  for playername,results in pairs(self.bombPlayerResults)do
@@ -42470,7 +42906,7 @@ self:E(self.lid..string.format("WARNING: Could not load player results from file
42470
42906
  return nil
42471
42907
  end
42472
42908
  end
42473
- local path=lfs.writedir()..[[Logs\]]
42909
+ local path=self.targetpath or lfs.writedir()..[[Logs\]]
42474
42910
  local filename=path..string.format("RANGE-%s_BombingResults.csv",self.rangename)
42475
42911
  local text=string.format("Loading player bomb results from file %s",filename)
42476
42912
  self:I(self.lid..text)
@@ -42894,7 +43330,7 @@ local group=_unit:GetGroup()
42894
43330
  local text="You left the strafing zone too quickly! No score!"
42895
43331
  self.controlsrsQ:NewTransmission(text,nil,self.controlmsrs,nil,1)
42896
43332
  else
42897
- self.rangecontrol:NewTransmission(RANGE.Sound.RCLeftStrafePitTooQuickly.filename,RANGE.Sound.RCLeftStrafePitTooQuickly.duration,self.soundpath)
43333
+ self.rangecontrol:NewTransmission(self.Sound.RCLeftStrafePitTooQuickly.filename,self.Sound.RCLeftStrafePitTooQuickly.duration,self.soundpath)
42898
43334
  end
42899
43335
  end
42900
43336
  else
@@ -42912,23 +43348,23 @@ end
42912
43348
  local resulttext=""
42913
43349
  if _result.pastfoulline==true then
42914
43350
  resulttext="* INVALID - PASSED FOUL LINE *"
42915
- _sound=RANGE.Sound.RCPoorPass
43351
+ _sound=self.Sound.RCPoorPass
42916
43352
  else
42917
43353
  if accur>=90 then
42918
43354
  resulttext="DEADEYE PASS"
42919
- _sound=RANGE.Sound.RCExcellentPass
43355
+ _sound=self.Sound.RCExcellentPass
42920
43356
  elseif accur>=75 then
42921
43357
  resulttext="EXCELLENT PASS"
42922
- _sound=RANGE.Sound.RCExcellentPass
43358
+ _sound=self.Sound.RCExcellentPass
42923
43359
  elseif accur>=50 then
42924
43360
  resulttext="GOOD PASS"
42925
- _sound=RANGE.Sound.RCGoodPass
43361
+ _sound=self.Sound.RCGoodPass
42926
43362
  elseif accur>=25 then
42927
43363
  resulttext="INEFFECTIVE PASS"
42928
- _sound=RANGE.Sound.RCIneffectivePass
43364
+ _sound=self.Sound.RCIneffectivePass
42929
43365
  else
42930
43366
  resulttext="POOR PASS"
42931
- _sound=RANGE.Sound.RCPoorPass
43367
+ _sound=self.Sound.RCPoorPass
42932
43368
  end
42933
43369
  end
42934
43370
  local _text=string.format("%s, hits on target %s: %d",self:_myname(_unitName),_result.zone.name,_result.hits)
@@ -42963,14 +43399,14 @@ if self.rangecontrol then
42963
43399
  if self.useSRS then
42964
43400
  self.controlsrsQ:NewTransmission(ttstext,nil,self.controlmsrs,nil,1)
42965
43401
  else
42966
- self.rangecontrol:NewTransmission(RANGE.Sound.RCHitsOnTarget.filename,RANGE.Sound.RCHitsOnTarget.duration,self.soundpath)
43402
+ self.rangecontrol:NewTransmission(self.Sound.RCHitsOnTarget.filename,self.Sound.RCHitsOnTarget.duration,self.soundpath)
42967
43403
  self.rangecontrol:Number2Transmission(string.format("%d",_result.hits))
42968
43404
  if shots and accur then
42969
- self.rangecontrol:NewTransmission(RANGE.Sound.RCTotalRoundsFired.filename,RANGE.Sound.RCTotalRoundsFired.duration,self.soundpath,nil,0.2)
43405
+ self.rangecontrol:NewTransmission(self.Sound.RCTotalRoundsFired.filename,self.Sound.RCTotalRoundsFired.duration,self.soundpath,nil,0.2)
42970
43406
  self.rangecontrol:Number2Transmission(string.format("%d",shots),nil,0.2)
42971
- self.rangecontrol:NewTransmission(RANGE.Sound.RCAccuracy.filename,RANGE.Sound.RCAccuracy.duration,self.soundpath,nil,0.2)
43407
+ self.rangecontrol:NewTransmission(self.Sound.RCAccuracy.filename,self.Sound.RCAccuracy.duration,self.soundpath,nil,0.2)
42972
43408
  self.rangecontrol:Number2Transmission(string.format("%d",UTILS.Round(accur,0)))
42973
- self.rangecontrol:NewTransmission(RANGE.Sound.RCPercent.filename,RANGE.Sound.RCPercent.duration,self.soundpath)
43409
+ self.rangecontrol:NewTransmission(self.Sound.RCPercent.filename,self.Sound.RCPercent.duration,self.soundpath)
42974
43410
  end
42975
43411
  self.rangecontrol:NewTransmission(_sound.filename,_sound.duration,self.soundpath,nil,0.5)
42976
43412
  end
@@ -42994,7 +43430,7 @@ if self.rangecontrol then
42994
43430
  if self.useSRS then
42995
43431
  self.controlsrsQ:NewTransmission(_msg,nil,self.controlmsrs,nil,1)
42996
43432
  else
42997
- self.rangecontrol:NewTransmission(RANGE.Sound.RCRollingInOnStrafeTarget.filename,RANGE.Sound.RCRollingInOnStrafeTarget.duration,self.soundpath)
43433
+ self.rangecontrol:NewTransmission(self.Sound.RCRollingInOnStrafeTarget.filename,self.Sound.RCRollingInOnStrafeTarget.duration,self.soundpath)
42998
43434
  end
42999
43435
  end
43000
43436
  self:_DisplayMessageToGroup(_unit,_msg,10,true)
@@ -43014,15 +43450,21 @@ local _gid=group:GetID()
43014
43450
  if group and _gid then
43015
43451
  if not self.MenuAddedTo[_gid]then
43016
43452
  self.MenuAddedTo[_gid]=true
43017
- local _rangePath=nil
43018
- if RANGE.MenuF10Root then
43019
- _rangePath=MENU_GROUP:New(group,"On the Range")
43453
+ local _rootMenu=nil
43454
+ if self.menuF10root then
43455
+ _rootMenu=self.menuF10root
43456
+ self:T2(self.lid..string.format("Creating F10 menu for group %s",group:GetName()))
43457
+ elseif RANGE.MenuF10Root then
43458
+ _rootMenu=RANGE.MenuF10Root
43020
43459
  else
43021
43460
  if RANGE.MenuF10[_gid]==nil then
43022
- RANGE.MenuF10[_gid]=MENU_GROUP:New(group,"On the Range")
43461
+ self:T2(self.lid..string.format("Creating F10 menu 'On the Range' for group %s",group:GetName()))
43462
+ else
43463
+ self:T2(self.lid..string.format("F10 menu 'On the Range' already EXISTS for group %s",group:GetName()))
43023
43464
  end
43024
- _rangePath=MENU_GROUP:New(group,self.rangename,RANGE.MenuF10[_gid])
43465
+ _rootMenu=RANGE.MenuF10[_gid]or MENU_GROUP:New(group,"On the Range")
43025
43466
  end
43467
+ local _rangePath=MENU_GROUP:New(group,self.rangename,_rootMenu)
43026
43468
  local _statsPath=MENU_GROUP:New(group,"Statistics",_rangePath)
43027
43469
  local _markPath=MENU_GROUP:New(group,"Mark Targets",_rangePath)
43028
43470
  local _settingsPath=MENU_GROUP:New(group,"My Settings",_rangePath)
@@ -43277,12 +43719,12 @@ local text=""
43277
43719
  if self.targetsheet then
43278
43720
  playerData.targeton=not playerData.targeton
43279
43721
  if playerData and playerData.targeton==true then
43280
- text=string.format("roger, your targetsheets are now SAVED.")
43722
+ text=string.format("Roger, your targetsheets are now SAVED.")
43281
43723
  else
43282
- text=string.format("affirm, your targetsheets are NOT SAVED.")
43724
+ text=string.format("Affirm, your targetsheets are NOT SAVED.")
43283
43725
  end
43284
43726
  else
43285
- text="negative, target sheet data recorder is broken on this range."
43727
+ text="Negative, target sheet data recorder is broken on this range."
43286
43728
  end
43287
43729
  self:_DisplayMessageToGroup(unit,text,5,false,false)
43288
43730
  end
@@ -43922,7 +44364,7 @@ maxrange=32000,
43922
44364
  reloadtime=540,
43923
44365
  },
43924
44366
  }
43925
- ARTY.version="1.3.0"
44367
+ ARTY.version="1.3.1"
43926
44368
  function ARTY:New(group,alias)
43927
44369
  local self=BASE:Inherit(self,FSM_CONTROLLABLE:New())
43928
44370
  if type(group)=="string"then
@@ -44385,7 +44827,7 @@ self:_EventFromTo("onafterStart",Event,From,To)
44385
44827
  local text=string.format("Started ARTY version %s for group %s.",ARTY.version,Controllable:GetName())
44386
44828
  self:I(self.lid..text)
44387
44829
  MESSAGE:New(text,5):ToAllIf(self.Debug)
44388
- self.Nammo0,self.Nshells0,self.Nrockets0,self.Nmissiles0=self:GetAmmo(self.Debug)
44830
+ self.Nammo0,self.Nshells0,self.Nrockets0,self.Nmissiles0,self.Narty0=self:GetAmmo(self.Debug)
44389
44831
  if self.nukerange==nil then
44390
44832
  self.nukerange=1500/75000*self.nukewarhead
44391
44833
  end
@@ -44546,7 +44988,7 @@ function ARTY:_StatusReport(display)
44546
44988
  if display==nil then
44547
44989
  display=false
44548
44990
  end
44549
- local Nammo,Nshells,Nrockets,Nmissiles=self:GetAmmo()
44991
+ local Nammo,Nshells,Nrockets,Nmissiles,Narty=self:GetAmmo()
44550
44992
  local Nnukes=self.Nukes
44551
44993
  local Nillu=self.Nillu
44552
44994
  local Nsmoke=self.Nsmoke
@@ -44557,7 +44999,7 @@ text=text..string.format("ARTY group = %s\n",self.groupname)
44557
44999
  text=text..string.format("Clock = %s\n",Clock)
44558
45000
  text=text..string.format("FSM state = %s\n",self:GetState())
44559
45001
  text=text..string.format("Total ammo count = %d\n",Nammo)
44560
- text=text..string.format("Number of shells = %d\n",Nshells)
45002
+ text=text..string.format("Number of shells = %d\n",Narty)
44561
45003
  text=text..string.format("Number of rockets = %d\n",Nrockets)
44562
45004
  text=text..string.format("Number of missiles = %d\n",Nmissiles)
44563
45005
  text=text..string.format("Number of nukes = %d\n",Nnukes)
@@ -44650,7 +45092,7 @@ weapon:SetFuncTrack(ARTY._FuncTrack,self,target)
44650
45092
  weapon:SetFuncImpact(ARTY._FuncImpact,self,target)
44651
45093
  weapon:StartTrack(2)
44652
45094
  end
44653
- local _nammo,_nshells,_nrockets,_nmissiles=self:GetAmmo()
45095
+ local _nammo,_nshells,_nrockets,_nmissiles,_narty=self:GetAmmo()
44654
45096
  if self.currentTarget.weapontype==ARTY.WeaponType.TacticalNukes then
44655
45097
  self.Nukes=self.Nukes-1
44656
45098
  end
@@ -44667,7 +45109,7 @@ _outofammo=true
44667
45109
  end
44668
45110
  local _partlyoutofammo=self:_CheckOutOfAmmo({self.currentTarget})
44669
45111
  local _weapontype=self:_WeaponTypeName(self.currentTarget.weapontype)
44670
- self:T(self.lid..string.format("Group %s ammo: total=%d, shells=%d, rockets=%d, missiles=%d",self.groupname,_nammo,_nshells,_nrockets,_nmissiles))
45112
+ self:T(self.lid..string.format("Group %s ammo: total=%d, shells=%d, rockets=%d, missiles=%d",self.groupname,_nammo,_narty,_nrockets,_nmissiles))
44671
45113
  self:T(self.lid..string.format("Group %s uses weapontype %s for current target.",self.groupname,_weapontype))
44672
45114
  local _ceasefire=false
44673
45115
  local _relocate=false
@@ -44935,7 +45377,7 @@ end
44935
45377
  end
44936
45378
  function ARTY:onafterStatus(Controllable,From,Event,To)
44937
45379
  self:_EventFromTo("onafterStatus",Event,From,To)
44938
- local nammo,nshells,nrockets,nmissiles=self:GetAmmo()
45380
+ local nammo,nshells,nrockets,nmissiles,narty=self:GetAmmo()
44939
45381
  if self.iscargo and self.cargogroup then
44940
45382
  if self.cargogroup:IsLoaded()and not self:is("InTransit")then
44941
45383
  self:T(self.lid..string.format("Group %s has been loaded into a carrier and is now transported.",self.alias))
@@ -44946,7 +45388,7 @@ self:UnLoaded()
44946
45388
  end
44947
45389
  end
44948
45390
  local fsmstate=self:GetState()
44949
- self:T(self.lid..string.format("Status %s, Ammo total=%d: shells=%d [smoke=%d, illu=%d, nukes=%d*%.3f kT], rockets=%d, missiles=%d",fsmstate,nammo,nshells,self.Nsmoke,self.Nillu,self.Nukes,self.nukewarhead/1000000,nrockets,nmissiles))
45391
+ self:T(self.lid..string.format("Status %s, Ammo total=%d: shells=%d [smoke=%d, illu=%d, nukes=%d*%.3f kT], rockets=%d, missiles=%d",fsmstate,nammo,narty,self.Nsmoke,self.Nillu,self.Nukes,self.nukewarhead/1000000,nrockets,nmissiles))
44950
45392
  if self.Controllable and self.Controllable:IsAlive()then
44951
45393
  if self.Debug then
44952
45394
  self:_StatusReport()
@@ -44998,10 +45440,14 @@ elseif _timedTarget then
44998
45440
  if self.currentTarget then
44999
45441
  self:CeaseFire(self.currentTarget)
45000
45442
  end
45443
+ if self:is("CombatReady")then
45001
45444
  self:OpenFire(_timedTarget)
45445
+ end
45002
45446
  elseif _normalTarget then
45447
+ if self:is("CombatReady")then
45003
45448
  self:OpenFire(_normalTarget)
45004
45449
  end
45450
+ end
45005
45451
  local gotsome=false
45006
45452
  if#self.targets>0 then
45007
45453
  for i=1,#self.targets do
@@ -45071,14 +45517,14 @@ self.currentTarget=target
45071
45517
  self.currentTarget.Tassigned=timer.getTime()
45072
45518
  end
45073
45519
  local range=Controllable:GetCoordinate():Get2DDistance(target.coord)
45074
- local Nammo,Nshells,Nrockets,Nmissiles=self:GetAmmo()
45075
- local nfire=Nammo
45520
+ local Nammo,Nshells,Nrockets,Nmissiles,Narty=self:GetAmmo()
45521
+ local nfire=Narty
45076
45522
  local _type="shots"
45077
45523
  if target.weapontype==ARTY.WeaponType.Auto then
45078
- nfire=Nammo
45524
+ nfire=Narty
45079
45525
  _type="shots"
45080
45526
  elseif target.weapontype==ARTY.WeaponType.Cannon then
45081
- nfire=Nshells
45527
+ nfire=Narty
45082
45528
  _type="shells"
45083
45529
  elseif target.weapontype==ARTY.WeaponType.TacticalNukes then
45084
45530
  nfire=self.Nukes
@@ -45219,7 +45665,7 @@ end
45219
45665
  end
45220
45666
  function ARTY:_CheckRearmed()
45221
45667
  self:F2()
45222
- local nammo,nshells,nrockets,nmissiles=self:GetAmmo()
45668
+ local nammo,nshells,nrockets,nmissiles,narty=self:GetAmmo()
45223
45669
  local units=self.Controllable:GetUnits()
45224
45670
  local nunits=0
45225
45671
  if units then
@@ -45329,10 +45775,13 @@ local group=self.Controllable
45329
45775
  if weapontype==ARTY.WeaponType.TacticalNukes or weapontype==ARTY.WeaponType.IlluminationShells or weapontype==ARTY.WeaponType.SmokeShells then
45330
45776
  weapontype=ARTY.WeaponType.Cannon
45331
45777
  end
45778
+ if group:HasTask()then
45779
+ group:ClearTasks()
45780
+ end
45332
45781
  group:OptionROEOpenFire()
45333
45782
  local vec2=coord:GetVec2()
45334
45783
  local fire=group:TaskFireAtPoint(vec2,radius,nshells,weapontype)
45335
- group:SetTask(fire)
45784
+ group:SetTask(fire,1)
45336
45785
  end
45337
45786
  function ARTY:_AttackGroup(target)
45338
45787
  local group=self.Controllable
@@ -45340,10 +45789,13 @@ local weapontype=target.weapontype
45340
45789
  if weapontype==ARTY.WeaponType.TacticalNukes or weapontype==ARTY.WeaponType.IlluminationShells or weapontype==ARTY.WeaponType.SmokeShells then
45341
45790
  weapontype=ARTY.WeaponType.Cannon
45342
45791
  end
45792
+ if group:HasTask()then
45793
+ group:ClearTasks()
45794
+ end
45343
45795
  group:OptionROEOpenFire()
45344
45796
  local targetgroup=GROUP:FindByName(target.name)
45345
45797
  local fire=group:TaskAttackGroup(targetgroup,weapontype,AI.Task.WeaponExpend.ONE,1)
45346
- group:SetTask(fire)
45798
+ group:SetTask(fire,1)
45347
45799
  end
45348
45800
  function ARTY:_NuclearBlast(_coord)
45349
45801
  local S0=self.nukewarhead
@@ -45462,6 +45914,7 @@ local nammo=0
45462
45914
  local nshells=0
45463
45915
  local nrockets=0
45464
45916
  local nmissiles=0
45917
+ local nartyshells=0
45465
45918
  local units=self.Controllable:GetUnits()
45466
45919
  if units==nil then
45467
45920
  return nammo,nshells,nrockets,nmissiles
@@ -45529,6 +45982,8 @@ end
45529
45982
  end
45530
45983
  if _gotshell then
45531
45984
  nshells=nshells+Nammo
45985
+ local _,_,_,_,_,shells=unit:GetAmmunition()
45986
+ nartyshells=nartyshells+shells
45532
45987
  text=text..string.format("- %d shells of type %s\n",Nammo,_weaponName)
45533
45988
  elseif _gotrocket then
45534
45989
  nrockets=nrockets+Nammo
@@ -45552,7 +46007,7 @@ MESSAGE:New(text,10):ToAllIf(display)
45552
46007
  end
45553
46008
  end
45554
46009
  nammo=nshells+nrockets+nmissiles
45555
- return nammo,nshells,nrockets,nmissiles
46010
+ return nammo,nshells,nrockets,nmissiles,nartyshells
45556
46011
  end
45557
46012
  function ARTY:_MissileCategoryName(categorynumber)
45558
46013
  local cat="unknown"
@@ -46001,7 +46456,8 @@ local dt=Tnow-self.currentTarget.Tassigned
46001
46456
  if self.Nshots==0 then
46002
46457
  self:T(self.lid..string.format("%s, waiting for %d seconds for first shot on target %s.",self.groupname,dt,name))
46003
46458
  end
46004
- if dt>self.WaitForShotTime and(self.Nshots==0 or self.currentTarget.nshells>=self.Nshots)then
46459
+ self:T(string.format("dt = %d WaitTime = %d | shots = %d TargetShells = %d",dt,self.WaitForShotTime,self.Nshots,self.currentTarget.nshells))
46460
+ if(dt>self.WaitForShotTime and self.Nshots==0)or(self.currentTarget.nshells<=self.Nshots)then
46005
46461
  self:T(self.lid..string.format("%s, no shot event after %d seconds. Removing current target %s from list.",self.groupname,self.WaitForShotTime,name))
46006
46462
  self:CeaseFire(self.currentTarget)
46007
46463
  self:RemoveTarget(name)
@@ -46035,13 +46491,13 @@ self:T2(self.lid..string.format("WARNING: Move with name %s could not be found.
46035
46491
  return nil
46036
46492
  end
46037
46493
  function ARTY:_CheckOutOfAmmo(targets)
46038
- local _nammo,_nshells,_nrockets,_nmissiles=self:GetAmmo()
46494
+ local _nammo,_nshells,_nrockets,_nmissiles,_narty=self:GetAmmo()
46039
46495
  local _partlyoutofammo=false
46040
46496
  for _,Target in pairs(targets)do
46041
46497
  if Target.weapontype==ARTY.WeaponType.Auto and _nammo==0 then
46042
46498
  self:T(self.lid..string.format("Group %s, auto weapon requested for target %s but all ammo is empty.",self.groupname,Target.name))
46043
46499
  _partlyoutofammo=true
46044
- elseif Target.weapontype==ARTY.WeaponType.Cannon and _nshells==0 then
46500
+ elseif Target.weapontype==ARTY.WeaponType.Cannon and _narty==0 then
46045
46501
  self:T(self.lid..string.format("Group %s, cannons requested for target %s but shells empty.",self.groupname,Target.name))
46046
46502
  _partlyoutofammo=true
46047
46503
  elseif Target.weapontype==ARTY.WeaponType.TacticalNukes and self.Nukes<=0 then
@@ -46064,12 +46520,12 @@ end
46064
46520
  return _partlyoutofammo
46065
46521
  end
46066
46522
  function ARTY:_CheckWeaponTypeAvailable(target)
46067
- local Nammo,Nshells,Nrockets,Nmissiles=self:GetAmmo()
46523
+ local Nammo,Nshells,Nrockets,Nmissiles,Narty=self:GetAmmo()
46068
46524
  local nfire=Nammo
46069
46525
  if target.weapontype==ARTY.WeaponType.Auto then
46070
46526
  nfire=Nammo
46071
46527
  elseif target.weapontype==ARTY.WeaponType.Cannon then
46072
- nfire=Nshells
46528
+ nfire=Narty
46073
46529
  elseif target.weapontype==ARTY.WeaponType.TacticalNukes then
46074
46530
  nfire=self.Nukes
46075
46531
  elseif target.weapontype==ARTY.WeaponType.IlluminationShells then
@@ -50445,6 +50901,7 @@ if not self.allowSpawnOnClientSpots then
50445
50901
  local clients=_DATABASE.CLIENTS
50446
50902
  for clientname,client in pairs(clients)do
50447
50903
  local template=_DATABASE:GetGroupTemplateFromUnitName(clientname)
50904
+ if template then
50448
50905
  local units=template.units
50449
50906
  for i,unit in pairs(units)do
50450
50907
  local coord=COORDINATE:New(unit.x,unit.alt,unit.y)
@@ -50452,6 +50909,7 @@ coords[unit.name]=coord
50452
50909
  end
50453
50910
  end
50454
50911
  end
50912
+ end
50455
50913
  return coords
50456
50914
  end
50457
50915
  local parkingdata=airbase.parking
@@ -53550,6 +54008,313 @@ end
53550
54008
  return self
53551
54009
  end
53552
54010
  end
54011
+ CLIENTWATCH={}
54012
+ CLIENTWATCH.ClassName="CLIENTWATCH"
54013
+ CLIENTWATCH.Debug=false
54014
+ CLIENTWATCH.lid=nil
54015
+ CLIENTWATCHTools={}
54016
+ CLIENTWATCH.version="1.0.1"
54017
+ function CLIENTWATCH:New(client)
54018
+ local self=BASE:Inherit(self,FSM:New())
54019
+ self:SetStartState("Idle")
54020
+ self:AddTransition("*","Spawn","*")
54021
+ if type(client)=="table"or type(client)=="string"then
54022
+ if type(client)=="table"then
54023
+ if client.ClassName=="CLIENT"then
54024
+ self.ClientName=client:GetName()
54025
+ self:HandleEvent(EVENTS.Birth)
54026
+ function self:OnEventBirth(eventdata)
54027
+ if self.Debug then UTILS.PrintTableToLog(eventdata)end
54028
+ if eventdata.IniCategory and eventdata.IniCategory<=1 then
54029
+ if self.ClientName==eventdata.IniUnitName then
54030
+ local clientObject=CLIENTWATCHTools:_newClient(eventdata)
54031
+ self:Spawn(clientObject)
54032
+ end
54033
+ end
54034
+ end
54035
+ else
54036
+ local tableValid=true
54037
+ for _,entry in pairs(client)do
54038
+ if type(entry)~="string"then
54039
+ tableValid=false
54040
+ self:E({"The base handler failed to start because at least one entry in param1's table is not a string!",InvalidEntry=entry})
54041
+ return nil
54042
+ end
54043
+ end
54044
+ if tableValid then
54045
+ self:HandleEvent(EVENTS.Birth)
54046
+ function self:OnEventBirth(eventdata)
54047
+ if self.Debug then UTILS.PrintTableToLog(eventdata)end
54048
+ for _,entry in pairs(client)do
54049
+ if eventdata.IniCategory and eventdata.IniCategory<=1 then
54050
+ if string.match(eventdata.IniUnitName,entry)or string.match(eventdata.IniGroupName,entry)then
54051
+ local clientObject=CLIENTWATCHTools:_newClient(eventdata)
54052
+ self:Spawn(clientObject)
54053
+ break
54054
+ end
54055
+ end
54056
+ end
54057
+ end
54058
+ end
54059
+ end
54060
+ else
54061
+ self:HandleEvent(EVENTS.Birth)
54062
+ function self:OnEventBirth(eventdata)
54063
+ if self.Debug then UTILS.PrintTableToLog(eventdata)end
54064
+ if eventdata.IniCategory and eventdata.IniCategory<=1 then
54065
+ if string.match(eventdata.IniUnitName,client)or string.match(eventdata.IniGroupName,client)then
54066
+ local clientObject=CLIENTWATCHTools:_newClient(eventdata)
54067
+ self:Spawn(clientObject)
54068
+ end
54069
+ end
54070
+ end
54071
+ end
54072
+ else
54073
+ self:E({"The base handler failed to start because param1 is not a CLIENT object or a prefix string!",param1=client})
54074
+ return nil
54075
+ end
54076
+ return self
54077
+ end
54078
+ function CLIENTWATCHTools:_newClient(eventdata)
54079
+ local self=BASE:Inherit(self,FSM:New())
54080
+ self:SetStartState("Alive")
54081
+ self:AddTransition("Alive","Despawn","Dead")
54082
+ self.Unit=eventdata.IniUnit
54083
+ self.Group=self.Unit:GetGroup()
54084
+ self.Client=self.Unit:GetClient()
54085
+ self.PlayerName=self.Unit:GetPlayerName()
54086
+ self.UnitName=self.Unit:GetName()
54087
+ self.GroupName=self.Group:GetName()
54088
+ self:AddTransition("*","Hit","*")
54089
+ self:AddTransition("*","Kill","*")
54090
+ self:AddTransition("*","Score","*")
54091
+ self:AddTransition("*","Shot","*")
54092
+ self:AddTransition("*","ShootingStart","*")
54093
+ self:AddTransition("*","ShootingEnd","*")
54094
+ self:AddTransition("*","Land","*")
54095
+ self:AddTransition("*","Takeoff","*")
54096
+ self:AddTransition("*","RunwayTakeoff","*")
54097
+ self:AddTransition("*","RunwayTouch","*")
54098
+ self:AddTransition("*","Refueling","*")
54099
+ self:AddTransition("*","RefuelingStop","*")
54100
+ self:AddTransition("*","PlayerLeaveUnit","*")
54101
+ self:AddTransition("*","Crash","*")
54102
+ self:AddTransition("*","Dead","*")
54103
+ self:AddTransition("*","PilotDead","*")
54104
+ self:AddTransition("*","UnitLost","*")
54105
+ self:AddTransition("*","Ejection","*")
54106
+ self:AddTransition("*","HumanFailure","*")
54107
+ self:AddTransition("*","HumanAircraftRepairFinish","*")
54108
+ self:AddTransition("*","HumanAircraftRepairStart","*")
54109
+ self:AddTransition("*","EngineShutdown","*")
54110
+ self:AddTransition("*","EngineStartup","*")
54111
+ self:AddTransition("*","WeaponAdd","*")
54112
+ self:AddTransition("*","WeaponDrop","*")
54113
+ self:AddTransition("*","WeaponRearm","*")
54114
+ self:HandleEvent(EVENTS.Hit)
54115
+ self:HandleEvent(EVENTS.Kill)
54116
+ self:HandleEvent(EVENTS.Score)
54117
+ self:HandleEvent(EVENTS.Shot)
54118
+ self:HandleEvent(EVENTS.ShootingStart)
54119
+ self:HandleEvent(EVENTS.ShootingEnd)
54120
+ self:HandleEvent(EVENTS.Land)
54121
+ self:HandleEvent(EVENTS.Takeoff)
54122
+ self:HandleEvent(EVENTS.RunwayTakeoff)
54123
+ self:HandleEvent(EVENTS.RunwayTouch)
54124
+ self:HandleEvent(EVENTS.Refueling)
54125
+ self:HandleEvent(EVENTS.RefuelingStop)
54126
+ self:HandleEvent(EVENTS.PlayerLeaveUnit)
54127
+ self:HandleEvent(EVENTS.Crash)
54128
+ self:HandleEvent(EVENTS.Dead)
54129
+ self:HandleEvent(EVENTS.PilotDead)
54130
+ self:HandleEvent(EVENTS.UnitLost)
54131
+ self:HandleEvent(EVENTS.Ejection)
54132
+ self:HandleEvent(EVENTS.HumanFailure)
54133
+ self:HandleEvent(EVENTS.HumanAircraftRepairFinish)
54134
+ self:HandleEvent(EVENTS.HumanAircraftRepairStart)
54135
+ self:HandleEvent(EVENTS.EngineShutdown)
54136
+ self:HandleEvent(EVENTS.EngineStartup)
54137
+ self:HandleEvent(EVENTS.WeaponAdd)
54138
+ self:HandleEvent(EVENTS.WeaponDrop)
54139
+ self:HandleEvent(EVENTS.WeaponRearm)
54140
+ function self:OnEventHit(EventData)
54141
+ if EventData.TgtUnitName==self.UnitName then
54142
+ self:Hit(EventData)
54143
+ end
54144
+ end
54145
+ function self:OnEventKill(EventData)
54146
+ if EventData.IniUnitName==self.UnitName then
54147
+ self:Kill(EventData)
54148
+ end
54149
+ end
54150
+ function self:OnEventScore(EventData)
54151
+ if EventData.IniUnitName==self.UnitName then
54152
+ self:Score(EventData)
54153
+ end
54154
+ end
54155
+ function self:OnEventShot(EventData)
54156
+ if EventData.IniUnitName==self.UnitName then
54157
+ self:Shot(EventData)
54158
+ end
54159
+ end
54160
+ function self:OnEventShootingStart(EventData)
54161
+ if EventData.IniUnitName==self.UnitName then
54162
+ self:ShootingStart(EventData)
54163
+ end
54164
+ end
54165
+ function self:OnEventShootingEnd(EventData)
54166
+ if EventData.IniUnitName==self.UnitName then
54167
+ self:ShootingEnd(EventData)
54168
+ end
54169
+ end
54170
+ function self:OnEventLand(EventData)
54171
+ if EventData.IniUnitName==self.UnitName then
54172
+ self:Land(EventData)
54173
+ end
54174
+ end
54175
+ function self:OnEventTakeoff(EventData)
54176
+ if EventData.IniUnitName==self.UnitName then
54177
+ self:Takeoff(EventData)
54178
+ end
54179
+ end
54180
+ function self:OnEventRunwayTakeoff(EventData)
54181
+ if EventData.IniUnitName==self.UnitName then
54182
+ self:RunwayTakeoff(EventData)
54183
+ end
54184
+ end
54185
+ function self:OnEventRunwayTouch(EventData)
54186
+ if EventData.IniUnitName==self.UnitName then
54187
+ self:RunwayTouch(EventData)
54188
+ end
54189
+ end
54190
+ function self:OnEventRefueling(EventData)
54191
+ if EventData.IniUnitName==self.UnitName then
54192
+ self:Refueling(EventData)
54193
+ end
54194
+ end
54195
+ function self:OnEventRefuelingStop(EventData)
54196
+ if EventData.IniUnitName==self.UnitName then
54197
+ self:RefuelingStop(EventData)
54198
+ end
54199
+ end
54200
+ function self:OnEventPlayerLeaveUnit(EventData)
54201
+ if EventData.IniUnitName==self.UnitName then
54202
+ self:PlayerLeaveUnit(EventData)
54203
+ self._deadRoutine()
54204
+ end
54205
+ end
54206
+ function self:OnEventCrash(EventData)
54207
+ if EventData.IniUnitName==self.UnitName then
54208
+ self:Crash(EventData)
54209
+ self._deadRoutine()
54210
+ end
54211
+ end
54212
+ function self:OnEventDead(EventData)
54213
+ if EventData.IniUnitName==self.UnitName then
54214
+ self:Dead(EventData)
54215
+ self._deadRoutine()
54216
+ end
54217
+ end
54218
+ function self:OnEventPilotDead(EventData)
54219
+ if EventData.IniUnitName==self.UnitName then
54220
+ self:PilotDead(EventData)
54221
+ self._deadRoutine()
54222
+ end
54223
+ end
54224
+ function self:OnEventUnitLost(EventData)
54225
+ if EventData.IniUnitName==self.UnitName then
54226
+ self:UnitLost(EventData)
54227
+ self._deadRoutine()
54228
+ end
54229
+ end
54230
+ function self:OnEventEjection(EventData)
54231
+ if EventData.IniUnitName==self.UnitName then
54232
+ self:Ejection(EventData)
54233
+ self._deadRoutine()
54234
+ end
54235
+ end
54236
+ function self:OnEventHumanFailure(EventData)
54237
+ if EventData.IniUnitName==self.UnitName then
54238
+ self:HumanFailure(EventData)
54239
+ if not self.Unit:IsAlive()then
54240
+ self._deadRoutine()
54241
+ end
54242
+ end
54243
+ end
54244
+ function self:OnEventHumanAircraftRepairFinish(EventData)
54245
+ if EventData.IniUnitName==self.UnitName then
54246
+ self:HumanAircraftRepairFinish(EventData)
54247
+ end
54248
+ end
54249
+ function self:OnEventHumanAircraftRepairStart(EventData)
54250
+ if EventData.IniUnitName==self.UnitName then
54251
+ self:HumanAircraftRepairStart(EventData)
54252
+ end
54253
+ end
54254
+ function self:OnEventEngineShutdown(EventData)
54255
+ if EventData.IniUnitName==self.UnitName then
54256
+ self:EngineShutdown(EventData)
54257
+ end
54258
+ end
54259
+ function self:OnEventEngineStartup(EventData)
54260
+ if EventData.IniUnitName==self.UnitName then
54261
+ self:EngineStartup(EventData)
54262
+ end
54263
+ end
54264
+ function self:OnEventWeaponAdd(EventData)
54265
+ if EventData.IniUnitName==self.UnitName then
54266
+ self:WeaponAdd(EventData)
54267
+ end
54268
+ end
54269
+ function self:OnEventWeaponDrop(EventData)
54270
+ if EventData.IniUnitName==self.UnitName then
54271
+ self:WeaponDrop(EventData)
54272
+ end
54273
+ end
54274
+ function self:OnEventWeaponRearm(EventData)
54275
+ if EventData.IniUnitName==self.UnitName then
54276
+ self:WeaponRearm(EventData)
54277
+ end
54278
+ end
54279
+ self.FallbackTimer=TIMER:New(function()
54280
+ if not self.Unit:IsAlive()then
54281
+ self._deadRoutine()
54282
+ end
54283
+ end)
54284
+ self.FallbackTimer:Start(5,5)
54285
+ function self._deadRoutine()
54286
+ self:UnHandleEvent(EVENTS.Hit)
54287
+ self:UnHandleEvent(EVENTS.Kill)
54288
+ self:UnHandleEvent(EVENTS.Score)
54289
+ self:UnHandleEvent(EVENTS.Shot)
54290
+ self:UnHandleEvent(EVENTS.ShootingStart)
54291
+ self:UnHandleEvent(EVENTS.ShootingEnd)
54292
+ self:UnHandleEvent(EVENTS.Land)
54293
+ self:UnHandleEvent(EVENTS.Takeoff)
54294
+ self:UnHandleEvent(EVENTS.RunwayTakeoff)
54295
+ self:UnHandleEvent(EVENTS.RunwayTouch)
54296
+ self:UnHandleEvent(EVENTS.Refueling)
54297
+ self:UnHandleEvent(EVENTS.RefuelingStop)
54298
+ self:UnHandleEvent(EVENTS.PlayerLeaveUnit)
54299
+ self:UnHandleEvent(EVENTS.Crash)
54300
+ self:UnHandleEvent(EVENTS.Dead)
54301
+ self:UnHandleEvent(EVENTS.PilotDead)
54302
+ self:UnHandleEvent(EVENTS.UnitLost)
54303
+ self:UnHandleEvent(EVENTS.Ejection)
54304
+ self:UnHandleEvent(EVENTS.HumanFailure)
54305
+ self:UnHandleEvent(EVENTS.HumanAircraftRepairFinish)
54306
+ self:UnHandleEvent(EVENTS.HumanAircraftRepairStart)
54307
+ self:UnHandleEvent(EVENTS.EngineShutdown)
54308
+ self:UnHandleEvent(EVENTS.EngineStartup)
54309
+ self:UnHandleEvent(EVENTS.WeaponAdd)
54310
+ self:UnHandleEvent(EVENTS.WeaponDrop)
54311
+ self:UnHandleEvent(EVENTS.WeaponRearm)
54312
+ self.FallbackTimer:Stop()
54313
+ self:Despawn()
54314
+ end
54315
+ self:I({"CLIENT SPAWN EVENT",PlayerName=self.PlayerName,UnitName=self.UnitName,GroupName=self.GroupName})
54316
+ return self
54317
+ end
53553
54318
  AIRBOSS={
53554
54319
  ClassName="AIRBOSS",
53555
54320
  Debug=false,
@@ -59960,8 +60725,10 @@ end
59960
60725
  function AIRBOSS:_GetOnboardNumbers(group,playeronly)
59961
60726
  local groupname=group:GetName()
59962
60727
  local text=string.format("Onboard numbers of group %s:",groupname)
59963
- local units=group:GetTemplate().units
60728
+ local template=group:GetTemplate()
59964
60729
  local numbers={}
60730
+ if template then
60731
+ local units=template.units
59965
60732
  for _,unit in pairs(units)do
59966
60733
  local n=tostring(unit.onboard_num)
59967
60734
  local name=unit.name
@@ -59973,6 +60740,17 @@ end
59973
60740
  numbers[name]=n
59974
60741
  end
59975
60742
  self:T2(self.lid..text)
60743
+ else
60744
+ if playeronly then
60745
+ return 101
60746
+ else
60747
+ local units=group:GetUnits()
60748
+ for i,_unit in pairs(units)do
60749
+ local name=_unit:GetName()
60750
+ numbers[name]=100+i
60751
+ end
60752
+ end
60753
+ end
59976
60754
  return numbers
59977
60755
  end
59978
60756
  function AIRBOSS:_GetTowerFrequency()
@@ -63329,6 +64107,8 @@ SinaiMap=true,
63329
64107
  }
63330
64108
  ATIS.Sound={
63331
64109
  ActiveRunway={filename="ActiveRunway.ogg",duration=0.99},
64110
+ ActiveRunwayDeparture={filename="ActiveRunwayDeparture.ogg",duration=0.99},
64111
+ ActiveRunwayArrival={filename="ActiveRunwayArrival.ogg",duration=0.99},
63332
64112
  AdviceOnInitial={filename="AdviceOnInitial.ogg",duration=3.00},
63333
64113
  Airport={filename="Airport.ogg",duration=0.66},
63334
64114
  Altimeter={filename="Altimeter.ogg",duration=0.68},
@@ -63640,11 +64420,46 @@ function ATIS:SetLocale(locale)
63640
64420
  self.locale=string.lower(locale)
63641
64421
  return self
63642
64422
  end
63643
- function ATIS:SetSoundfilesPath(path)
63644
- self.soundpath=tostring(path or"ATIS Soundfiles/")
64423
+ function ATIS:SetSoundfilesPath(pathMain,pathAirports,pathNato)
64424
+ self.soundpath=tostring(pathMain or"ATIS Soundfiles/")
64425
+ if pathAirports==nil then
64426
+ self.soundpathAirports=self.soundpath..env.mission.theatre.."/"
64427
+ else
64428
+ self.soundpathAirports=pathAirports
64429
+ end
64430
+ if pathNato==nil then
64431
+ self.soundpathNato=self.soundpath.."NATO Alphabet/"
64432
+ else
64433
+ self.soundpathNato=pathNato
64434
+ end
63645
64435
  self:T(self.lid..string.format("Setting sound files path to %s",self.soundpath))
63646
64436
  return self
63647
64437
  end
64438
+ function ATIS:SetSoundfilesInfo(csvfile)
64439
+ local function getSound(filename)
64440
+ for key,_soundfile in pairs(self.Sound)do
64441
+ local soundfile=_soundfile
64442
+ if filename==soundfile.filename then
64443
+ return soundfile
64444
+ end
64445
+ end
64446
+ return nil
64447
+ end
64448
+ local data=UTILS.ReadCSV(csvfile)
64449
+ if data then
64450
+ for i,sound in pairs(data)do
64451
+ local soundfile=getSound(sound.filename..".ogg")
64452
+ if soundfile then
64453
+ soundfile.duration=tonumber(sound.duration)
64454
+ else
64455
+ self:E(string.format("ERROR: Could not get info for sound file %s",sound.filename))
64456
+ end
64457
+ end
64458
+ else
64459
+ self:E(string.format("ERROR: Could not read sound csv file!"))
64460
+ end
64461
+ return self
64462
+ end
63648
64463
  function ATIS:SetRadioRelayUnitName(unitname)
63649
64464
  self.relayunitname=unitname
63650
64465
  self:T(self.lid..string.format("Setting radio relay unit to %s",self.relayunitname))
@@ -63928,16 +64743,16 @@ self.radioqueue=RADIOQUEUE:New(self.frequency,self.modulation,string.format("ATI
63928
64743
  self.radioqueue:SetSenderCoordinate(self.airbase:GetCoordinate())
63929
64744
  self.radioqueue:SetSenderUnitName(self.relayunitname)
63930
64745
  self.radioqueue:SetRadioPower(self.power)
63931
- self.radioqueue:SetDigit(0,ATIS.Sound.N0.filename,ATIS.Sound.N0.duration,self.soundpath)
63932
- self.radioqueue:SetDigit(1,ATIS.Sound.N1.filename,ATIS.Sound.N1.duration,self.soundpath)
63933
- self.radioqueue:SetDigit(2,ATIS.Sound.N2.filename,ATIS.Sound.N2.duration,self.soundpath)
63934
- self.radioqueue:SetDigit(3,ATIS.Sound.N3.filename,ATIS.Sound.N3.duration,self.soundpath)
63935
- self.radioqueue:SetDigit(4,ATIS.Sound.N4.filename,ATIS.Sound.N4.duration,self.soundpath)
63936
- self.radioqueue:SetDigit(5,ATIS.Sound.N5.filename,ATIS.Sound.N5.duration,self.soundpath)
63937
- self.radioqueue:SetDigit(6,ATIS.Sound.N6.filename,ATIS.Sound.N6.duration,self.soundpath)
63938
- self.radioqueue:SetDigit(7,ATIS.Sound.N7.filename,ATIS.Sound.N7.duration,self.soundpath)
63939
- self.radioqueue:SetDigit(8,ATIS.Sound.N8.filename,ATIS.Sound.N8.duration,self.soundpath)
63940
- self.radioqueue:SetDigit(9,ATIS.Sound.N9.filename,ATIS.Sound.N9.duration,self.soundpath)
64746
+ self.radioqueue:SetDigit(0,self.Sound.N0.filename,self.Sound.N0.duration,self.soundpath)
64747
+ self.radioqueue:SetDigit(1,self.Sound.N1.filename,self.Sound.N1.duration,self.soundpath)
64748
+ self.radioqueue:SetDigit(2,self.Sound.N2.filename,self.Sound.N2.duration,self.soundpath)
64749
+ self.radioqueue:SetDigit(3,self.Sound.N3.filename,self.Sound.N3.duration,self.soundpath)
64750
+ self.radioqueue:SetDigit(4,self.Sound.N4.filename,self.Sound.N4.duration,self.soundpath)
64751
+ self.radioqueue:SetDigit(5,self.Sound.N5.filename,self.Sound.N5.duration,self.soundpath)
64752
+ self.radioqueue:SetDigit(6,self.Sound.N6.filename,self.Sound.N6.duration,self.soundpath)
64753
+ self.radioqueue:SetDigit(7,self.Sound.N7.filename,self.Sound.N7.duration,self.soundpath)
64754
+ self.radioqueue:SetDigit(8,self.Sound.N8.filename,self.Sound.N8.duration,self.soundpath)
64755
+ self.radioqueue:SetDigit(9,self.Sound.N9.filename,self.Sound.N9.duration,self.soundpath)
63941
64756
  self.radioqueue:Start(1,0.1)
63942
64757
  end
63943
64758
  self:HandleEvent(EVENTS.BaseCaptured)
@@ -64139,7 +64954,35 @@ local cloudceil=clouds.base+clouds.thickness
64139
64954
  local clouddens=clouds.density
64140
64955
  local cloudspreset=clouds.preset or"Nothing"
64141
64956
  local precepitation=0
64142
- if cloudspreset:find("Preset10")then
64957
+ if cloudspreset:find("RainyPreset1")then
64958
+ clouddens=9
64959
+ if temperature>5 then
64960
+ precepitation=1
64961
+ else
64962
+ precepitation=3
64963
+ end
64964
+ elseif cloudspreset:find("RainyPreset2")then
64965
+ clouddens=9
64966
+ if temperature>5 then
64967
+ precepitation=1
64968
+ else
64969
+ precepitation=3
64970
+ end
64971
+ elseif cloudspreset:find("RainyPreset3")then
64972
+ clouddens=9
64973
+ if temperature>5 then
64974
+ precepitation=1
64975
+ else
64976
+ precepitation=3
64977
+ end
64978
+ elseif cloudspreset:find("RainyPreset")then
64979
+ clouddens=9
64980
+ if temperature>5 then
64981
+ precepitation=1
64982
+ else
64983
+ precepitation=3
64984
+ end
64985
+ elseif cloudspreset:find("Preset10")then
64143
64986
  clouddens=4
64144
64987
  elseif cloudspreset:find("Preset11")then
64145
64988
  clouddens=4
@@ -64193,34 +65036,8 @@ elseif cloudspreset:find("Preset8")then
64193
65036
  clouddens=4
64194
65037
  elseif cloudspreset:find("Preset9")then
64195
65038
  clouddens=4
64196
- elseif cloudspreset:find("RainyPreset")then
64197
- clouddens=9
64198
- if temperature>5 then
64199
- precepitation=1
64200
65039
  else
64201
- precepitation=3
64202
- end
64203
- elseif cloudspreset:find("RainyPreset1")then
64204
- clouddens=9
64205
- if temperature>5 then
64206
- precepitation=1
64207
- else
64208
- precepitation=3
64209
- end
64210
- elseif cloudspreset:find("RainyPreset2")then
64211
- clouddens=9
64212
- if temperature>5 then
64213
- precepitation=1
64214
- else
64215
- precepitation=3
64216
- end
64217
- elseif cloudspreset:find("RainyPreset3")then
64218
- clouddens=9
64219
- if temperature>5 then
64220
- precepitation=1
64221
- else
64222
- precepitation=3
64223
- end
65040
+ self:E(string.format("WARNING! Unknown weather preset: %s",tostring(cloudspreset)))
64224
65041
  end
64225
65042
  local CLOUDBASE=string.format("%d",UTILS.MetersToFeet(cloudbase))
64226
65043
  local CLOUDCEIL=string.format("%d",UTILS.MetersToFeet(cloudceil))
@@ -64235,25 +65052,25 @@ CLOUDBASE1000,CLOUDBASE0100=self:_GetThousandsAndHundreds(cloudbase)
64235
65052
  CLOUDCEIL1000,CLOUDCEIL0100=self:_GetThousandsAndHundreds(cloudceil)
64236
65053
  end
64237
65054
  local CloudCover={}
64238
- CloudCover=ATIS.Sound.CloudsNotAvailable
65055
+ CloudCover=self.Sound.CloudsNotAvailable
64239
65056
  local CLOUDSsub=self.gettext:GetEntry("NOCLOUDINFO",self.locale)
64240
65057
  if static then
64241
65058
  if clouddens>=9 then
64242
- CloudCover=ATIS.Sound.CloudsOvercast
65059
+ CloudCover=self.Sound.CloudsOvercast
64243
65060
  CLOUDSsub=self.gettext:GetEntry("OVERCAST",self.locale)
64244
65061
  elseif clouddens>=7 then
64245
- CloudCover=ATIS.Sound.CloudsBroken
65062
+ CloudCover=self.Sound.CloudsBroken
64246
65063
  CLOUDSsub=self.gettext:GetEntry("BROKEN",self.locale)
64247
65064
  elseif clouddens>=4 then
64248
- CloudCover=ATIS.Sound.CloudsScattered
65065
+ CloudCover=self.Sound.CloudsScattered
64249
65066
  CLOUDSsub=self.gettext:GetEntry("SCATTERED",self.locale)
64250
65067
  elseif clouddens>=1 then
64251
- CloudCover=ATIS.Sound.CloudsFew
65068
+ CloudCover=self.Sound.CloudsFew
64252
65069
  CLOUDSsub=self.gettext:GetEntry("FEWCLOUDS",self.locale)
64253
65070
  else
64254
65071
  CLOUDBASE=nil
64255
65072
  CLOUDCEIL=nil
64256
- CloudCover=ATIS.Sound.CloudsNo
65073
+ CloudCover=self.Sound.CloudsNo
64257
65074
  CLOUDSsub=self.gettext:GetEntry("NOCLOUDS",self.locale)
64258
65075
  end
64259
65076
  end
@@ -64266,38 +65083,38 @@ then
64266
65083
  subtitle=subtitle.." "..self.gettext:GetEntry("AIRPORT",self.locale)
64267
65084
  end
64268
65085
  if not self.useSRS then
64269
- self.radioqueue:NewTransmission(string.format("%s/%s.ogg",self.theatre,self.airbasename),3.0,self.soundpath,nil,nil,subtitle,self.subduration)
65086
+ self.radioqueue:NewTransmission(string.format("%s.ogg",self.airbasename),3.0,self.soundpathAirports,nil,nil,subtitle,self.subduration)
64270
65087
  end
64271
65088
  local alltext=subtitle
64272
65089
  local information=self.gettext:GetEntry("INFORMATION",self.locale)
64273
65090
  subtitle=string.format("%s %s",information,NATO)
64274
65091
  local _INFORMATION=subtitle
64275
65092
  if not self.useSRS then
64276
- self:Transmission(ATIS.Sound.Information,0.5,subtitle)
64277
- self.radioqueue:NewTransmission(string.format("NATO Alphabet/%s.ogg",NATO),0.75,self.soundpath)
65093
+ self:Transmission(self.Sound.Information,0.5,subtitle)
65094
+ self.radioqueue:NewTransmission(string.format("%s.ogg",NATO),0.75,self.soundpathNato)
64278
65095
  end
64279
65096
  alltext=alltext..";\n"..subtitle
64280
65097
  subtitle=string.format("%s Zulu",ZULU)
64281
65098
  if not self.useSRS then
64282
65099
  self.radioqueue:Number2Transmission(ZULU,nil,0.5)
64283
- self:Transmission(ATIS.Sound.Zulu,0.2,subtitle)
65100
+ self:Transmission(self.Sound.Zulu,0.2,subtitle)
64284
65101
  end
64285
65102
  alltext=alltext..";\n"..subtitle
64286
65103
  if not self.zulutimeonly then
64287
65104
  local sunrise=self.gettext:GetEntry("SUNRISEAT",self.locale)
64288
65105
  subtitle=string.format(sunrise,SUNRISE)
64289
65106
  if not self.useSRS then
64290
- self:Transmission(ATIS.Sound.SunriseAt,0.5,subtitle)
65107
+ self:Transmission(self.Sound.SunriseAt,0.5,subtitle)
64291
65108
  self.radioqueue:Number2Transmission(SUNRISE,nil,0.2)
64292
- self:Transmission(ATIS.Sound.TimeLocal,0.2)
65109
+ self:Transmission(self.Sound.TimeLocal,0.2)
64293
65110
  end
64294
65111
  alltext=alltext..";\n"..subtitle
64295
65112
  local sunset=self.gettext:GetEntry("SUNSETAT",self.locale)
64296
65113
  subtitle=string.format(sunset,SUNSET)
64297
65114
  if not self.useSRS then
64298
- self:Transmission(ATIS.Sound.SunsetAt,0.5,subtitle)
65115
+ self:Transmission(self.Sound.SunsetAt,0.5,subtitle)
64299
65116
  self.radioqueue:Number2Transmission(SUNSET,nil,0.5)
64300
- self:Transmission(ATIS.Sound.TimeLocal,0.2)
65117
+ self:Transmission(self.Sound.TimeLocal,0.2)
64301
65118
  end
64302
65119
  alltext=alltext..";\n"..subtitle
64303
65120
  end
@@ -64316,17 +65133,17 @@ subtitle=subtitle..", "..self.gettext:GetEntry("GUSTING",self.locale)
64316
65133
  end
64317
65134
  local _WIND=subtitle
64318
65135
  if not self.useSRS then
64319
- self:Transmission(ATIS.Sound.WindFrom,1.0,subtitle)
65136
+ self:Transmission(self.Sound.WindFrom,1.0,subtitle)
64320
65137
  self.radioqueue:Number2Transmission(WINDFROM)
64321
- self:Transmission(ATIS.Sound.At,0.2)
65138
+ self:Transmission(self.Sound.At,0.2)
64322
65139
  self.radioqueue:Number2Transmission(WINDSPEED)
64323
65140
  if self.metric then
64324
- self:Transmission(ATIS.Sound.MetersPerSecond,0.2)
65141
+ self:Transmission(self.Sound.MetersPerSecond,0.2)
64325
65142
  else
64326
- self:Transmission(ATIS.Sound.Knots,0.2)
65143
+ self:Transmission(self.Sound.Knots,0.2)
64327
65144
  end
64328
65145
  if turbulence>0 then
64329
- self:Transmission(ATIS.Sound.Gusting,0.2)
65146
+ self:Transmission(self.Sound.Gusting,0.2)
64330
65147
  end
64331
65148
  end
64332
65149
  alltext=alltext..";\n"..subtitle
@@ -64338,12 +65155,12 @@ local visi=self.gettext:GetEntry("VISISM",self.locale)
64338
65155
  subtitle=string.format(visi,VISIBILITY)
64339
65156
  end
64340
65157
  if not self.useSRS then
64341
- self:Transmission(ATIS.Sound.Visibilty,1.0,subtitle)
65158
+ self:Transmission(self.Sound.Visibilty,1.0,subtitle)
64342
65159
  self.radioqueue:Number2Transmission(VISIBILITY)
64343
65160
  if self.metric then
64344
- self:Transmission(ATIS.Sound.Kilometers,0.2)
65161
+ self:Transmission(self.Sound.Kilometers,0.2)
64345
65162
  else
64346
- self:Transmission(ATIS.Sound.StatuteMiles,0.2)
65163
+ self:Transmission(self.Sound.StatuteMiles,0.2)
64347
65164
  end
64348
65165
  end
64349
65166
  alltext=alltext..";\n"..subtitle
@@ -64384,21 +65201,21 @@ if wp then
64384
65201
  local phenos=self.gettext:GetEntry("PHENOMENA",self.locale)
64385
65202
  subtitle=string.format("%s: %s",phenos,wpsub)
64386
65203
  if not self.useSRS then
64387
- self:Transmission(ATIS.Sound.WeatherPhenomena,1.0,subtitle)
65204
+ self:Transmission(self.Sound.WeatherPhenomena,1.0,subtitle)
64388
65205
  if precepitation==1 then
64389
- self:Transmission(ATIS.Sound.Rain,0.5)
65206
+ self:Transmission(self.Sound.Rain,0.5)
64390
65207
  elseif precepitation==2 then
64391
- self:Transmission(ATIS.Sound.ThunderStorm,0.5)
65208
+ self:Transmission(self.Sound.ThunderStorm,0.5)
64392
65209
  elseif precepitation==3 then
64393
- self:Transmission(ATIS.Sound.Snow,0.5)
65210
+ self:Transmission(self.Sound.Snow,0.5)
64394
65211
  elseif precepitation==4 then
64395
- self:Transmission(ATIS.Sound.SnowStorm,0.5)
65212
+ self:Transmission(self.Sound.SnowStorm,0.5)
64396
65213
  end
64397
65214
  if fog then
64398
- self:Transmission(ATIS.Sound.Fog,0.5)
65215
+ self:Transmission(self.Sound.Fog,0.5)
64399
65216
  end
64400
65217
  if dust then
64401
- self:Transmission(ATIS.Sound.Dust,0.5)
65218
+ self:Transmission(self.Sound.Dust,0.5)
64402
65219
  end
64403
65220
  end
64404
65221
  alltext=alltext..";\n"..subtitle
@@ -64417,28 +65234,28 @@ local cloudbase=self.gettext:GetEntry("CLOUDBASEFT",self.locale)
64417
65234
  subtitle=string.format(cloudbase,cbase,cceil)
64418
65235
  end
64419
65236
  if not self.useSRS then
64420
- self:Transmission(ATIS.Sound.CloudBase,1.0,subtitle)
65237
+ self:Transmission(self.Sound.CloudBase,1.0,subtitle)
64421
65238
  if tonumber(CLOUDBASE1000)>0 then
64422
65239
  self.radioqueue:Number2Transmission(CLOUDBASE1000)
64423
- self:Transmission(ATIS.Sound.Thousand,0.1)
65240
+ self:Transmission(self.Sound.Thousand,0.1)
64424
65241
  end
64425
65242
  if tonumber(CLOUDBASE0100)>0 then
64426
65243
  self.radioqueue:Number2Transmission(CLOUDBASE0100)
64427
- self:Transmission(ATIS.Sound.Hundred,0.1)
65244
+ self:Transmission(self.Sound.Hundred,0.1)
64428
65245
  end
64429
- self:Transmission(ATIS.Sound.CloudCeiling,0.5)
65246
+ self:Transmission(self.Sound.CloudCeiling,0.5)
64430
65247
  if tonumber(CLOUDCEIL1000)>0 then
64431
65248
  self.radioqueue:Number2Transmission(CLOUDCEIL1000)
64432
- self:Transmission(ATIS.Sound.Thousand,0.1)
65249
+ self:Transmission(self.Sound.Thousand,0.1)
64433
65250
  end
64434
65251
  if tonumber(CLOUDCEIL0100)>0 then
64435
65252
  self.radioqueue:Number2Transmission(CLOUDCEIL0100)
64436
- self:Transmission(ATIS.Sound.Hundred,0.1)
65253
+ self:Transmission(self.Sound.Hundred,0.1)
64437
65254
  end
64438
65255
  if self.metric then
64439
- self:Transmission(ATIS.Sound.Meters,0.1)
65256
+ self:Transmission(self.Sound.Meters,0.1)
64440
65257
  else
64441
- self:Transmission(ATIS.Sound.Feet,0.1)
65258
+ self:Transmission(self.Sound.Feet,0.1)
64442
65259
  end
64443
65260
  end
64444
65261
  end
@@ -64460,15 +65277,15 @@ end
64460
65277
  end
64461
65278
  local _TEMPERATURE=subtitle
64462
65279
  if not self.useSRS then
64463
- self:Transmission(ATIS.Sound.Temperature,1.0,subtitle)
65280
+ self:Transmission(self.Sound.Temperature,1.0,subtitle)
64464
65281
  if temperature<0 then
64465
- self:Transmission(ATIS.Sound.Minus,0.2)
65282
+ self:Transmission(self.Sound.Minus,0.2)
64466
65283
  end
64467
65284
  self.radioqueue:Number2Transmission(TEMPERATURE)
64468
65285
  if self.TDegF then
64469
- self:Transmission(ATIS.Sound.DegreesFahrenheit,0.2)
65286
+ self:Transmission(self.Sound.DegreesFahrenheit,0.2)
64470
65287
  else
64471
- self:Transmission(ATIS.Sound.DegreesCelsius,0.2)
65288
+ self:Transmission(self.Sound.DegreesCelsius,0.2)
64472
65289
  end
64473
65290
  end
64474
65291
  alltext=alltext..";\n"..subtitle
@@ -64488,15 +65305,15 @@ end
64488
65305
  end
64489
65306
  local _DEWPOINT=subtitle
64490
65307
  if not self.useSRS then
64491
- self:Transmission(ATIS.Sound.DewPoint,1.0,subtitle)
65308
+ self:Transmission(self.Sound.DewPoint,1.0,subtitle)
64492
65309
  if dewpoint<0 then
64493
- self:Transmission(ATIS.Sound.Minus,0.2)
65310
+ self:Transmission(self.Sound.Minus,0.2)
64494
65311
  end
64495
65312
  self.radioqueue:Number2Transmission(DEWPOINT)
64496
65313
  if self.TDegF then
64497
- self:Transmission(ATIS.Sound.DegreesFahrenheit,0.2)
65314
+ self:Transmission(self.Sound.DegreesFahrenheit,0.2)
64498
65315
  else
64499
- self:Transmission(ATIS.Sound.DegreesCelsius,0.2)
65316
+ self:Transmission(self.Sound.DegreesCelsius,0.2)
64500
65317
  end
64501
65318
  end
64502
65319
  alltext=alltext..";\n"..subtitle
@@ -64531,30 +65348,30 @@ end
64531
65348
  end
64532
65349
  local _ALTIMETER=subtitle
64533
65350
  if not self.useSRS then
64534
- self:Transmission(ATIS.Sound.Altimeter,1.0,subtitle)
65351
+ self:Transmission(self.Sound.Altimeter,1.0,subtitle)
64535
65352
  if not self.qnhonly then
64536
- self:Transmission(ATIS.Sound.QNH,0.5)
65353
+ self:Transmission(self.Sound.QNH,0.5)
64537
65354
  end
64538
65355
  self.radioqueue:Number2Transmission(QNH[1])
64539
65356
  if ATIS.ICAOPhraseology[UTILS.GetDCSMap()]then
64540
- self:Transmission(ATIS.Sound.Decimal,0.2)
65357
+ self:Transmission(self.Sound.Decimal,0.2)
64541
65358
  end
64542
65359
  self.radioqueue:Number2Transmission(QNH[2])
64543
65360
  if not self.qnhonly then
64544
- self:Transmission(ATIS.Sound.QFE,0.75)
65361
+ self:Transmission(self.Sound.QFE,0.75)
64545
65362
  self.radioqueue:Number2Transmission(QFE[1])
64546
65363
  if ATIS.ICAOPhraseology[UTILS.GetDCSMap()]then
64547
- self:Transmission(ATIS.Sound.Decimal,0.2)
65364
+ self:Transmission(self.Sound.Decimal,0.2)
64548
65365
  end
64549
65366
  self.radioqueue:Number2Transmission(QFE[2])
64550
65367
  end
64551
65368
  if self.PmmHg then
64552
- self:Transmission(ATIS.Sound.MillimetersOfMercury,0.1)
65369
+ self:Transmission(self.Sound.MillimetersOfMercury,0.1)
64553
65370
  else
64554
65371
  if self.metric then
64555
- self:Transmission(ATIS.Sound.HectoPascal,0.1)
65372
+ self:Transmission(self.Sound.HectoPascal,0.1)
64556
65373
  else
64557
- self:Transmission(ATIS.Sound.InchesOfMercury,0.1)
65374
+ self:Transmission(self.Sound.InchesOfMercury,0.1)
64558
65375
  end
64559
65376
  end
64560
65377
  end
@@ -64562,7 +65379,7 @@ alltext=alltext..";\n"..subtitle
64562
65379
  local _RUNACT
64563
65380
  if not self.ATISforFARPs then
64564
65381
  local subtitle=""
64565
- if runwayLanding then
65382
+ if runwayLanding and runwayLanding~=runwayTakeoff then
64566
65383
  local actrun=self.gettext:GetEntry("ACTIVELANDING",self.locale)
64567
65384
  subtitle=string.format("%s %s",actrun,runwayLanding)
64568
65385
  if rwyLandingLeft==true then
@@ -64571,6 +65388,15 @@ elseif rwyLandingLeft==false then
64571
65388
  subtitle=subtitle.." "..self.gettext:GetEntry("RIGHT",self.locale)
64572
65389
  end
64573
65390
  alltext=alltext..";\n"..subtitle
65391
+ if not self.useSRS then
65392
+ self:Transmission(self.Sound.ActiveRunwayArrival,1.0,subtitle)
65393
+ self.radioqueue:Number2Transmission(runwayLanding)
65394
+ if rwyLandingLeft==true then
65395
+ self:Transmission(self.Sound.Left,0.2)
65396
+ elseif rwyLandingLeft==false then
65397
+ self:Transmission(self.Sound.Right,0.2)
65398
+ end
65399
+ end
64574
65400
  end
64575
65401
  if runwayTakeoff then
64576
65402
  local actrun=self.gettext:GetEntry("ACTIVERUN",self.locale)
@@ -64580,17 +65406,18 @@ subtitle=subtitle.." "..self.gettext:GetEntry("LEFT",self.locale)
64580
65406
  elseif rwyTakeoffLeft==false then
64581
65407
  subtitle=subtitle.." "..self.gettext:GetEntry("RIGHT",self.locale)
64582
65408
  end
64583
- end
64584
- _RUNACT=subtitle
65409
+ alltext=alltext..";\n"..subtitle
64585
65410
  if not self.useSRS then
64586
- self:Transmission(ATIS.Sound.ActiveRunway,1.0,subtitle)
64587
- self.radioqueue:Number2Transmission(runwayLanding)
64588
- if rwyLandingLeft==true then
64589
- self:Transmission(ATIS.Sound.Left,0.2)
64590
- elseif rwyLandingLeft==false then
64591
- self:Transmission(ATIS.Sound.Right,0.2)
65411
+ self:Transmission(self.Sound.ActiveRunwayDeparture,1.0,subtitle)
65412
+ self.radioqueue:Number2Transmission(runwayTakeoff)
65413
+ if rwyTakeoffLeft==true then
65414
+ self:Transmission(self.Sound.Left,0.2)
65415
+ elseif rwyTakeoffLeft==false then
65416
+ self:Transmission(self.Sound.Right,0.2)
64592
65417
  end
64593
65418
  end
65419
+ end
65420
+ _RUNACT=subtitle
64594
65421
  alltext=alltext..";\n"..subtitle
64595
65422
  if self.rwylength then
64596
65423
  local runact=self.airbase:GetActiveRunway(self.runwaym2t)
@@ -64609,19 +65436,19 @@ else
64609
65436
  subtitle=subtitle.." "..feet
64610
65437
  end
64611
65438
  if not self.useSRS then
64612
- self:Transmission(ATIS.Sound.RunwayLength,1.0,subtitle)
65439
+ self:Transmission(self.Sound.RunwayLength,1.0,subtitle)
64613
65440
  if tonumber(L1000)>0 then
64614
65441
  self.radioqueue:Number2Transmission(L1000)
64615
- self:Transmission(ATIS.Sound.Thousand,0.1)
65442
+ self:Transmission(self.Sound.Thousand,0.1)
64616
65443
  end
64617
65444
  if tonumber(L0100)>0 then
64618
65445
  self.radioqueue:Number2Transmission(L0100)
64619
- self:Transmission(ATIS.Sound.Hundred,0.1)
65446
+ self:Transmission(self.Sound.Hundred,0.1)
64620
65447
  end
64621
65448
  if self.metric then
64622
- self:Transmission(ATIS.Sound.Meters,0.1)
65449
+ self:Transmission(self.Sound.Meters,0.1)
64623
65450
  else
64624
- self:Transmission(ATIS.Sound.Feet,0.1)
65451
+ self:Transmission(self.Sound.Feet,0.1)
64625
65452
  end
64626
65453
  end
64627
65454
  alltext=alltext..";\n"..subtitle
@@ -64643,19 +65470,19 @@ else
64643
65470
  subtitle=subtitle.." "..feet
64644
65471
  end
64645
65472
  if not self.useSRS then
64646
- self:Transmission(ATIS.Sound.Elevation,1.0,subtitle)
65473
+ self:Transmission(self.Sound.Elevation,1.0,subtitle)
64647
65474
  if tonumber(L1000)>0 then
64648
65475
  self.radioqueue:Number2Transmission(L1000)
64649
- self:Transmission(ATIS.Sound.Thousand,0.1)
65476
+ self:Transmission(self.Sound.Thousand,0.1)
64650
65477
  end
64651
65478
  if tonumber(L0100)>0 then
64652
65479
  self.radioqueue:Number2Transmission(L0100)
64653
- self:Transmission(ATIS.Sound.Hundred,0.1)
65480
+ self:Transmission(self.Sound.Hundred,0.1)
64654
65481
  end
64655
65482
  if self.metric then
64656
- self:Transmission(ATIS.Sound.Meters,0.1)
65483
+ self:Transmission(self.Sound.Meters,0.1)
64657
65484
  else
64658
- self:Transmission(ATIS.Sound.Feet,0.1)
65485
+ self:Transmission(self.Sound.Feet,0.1)
64659
65486
  end
64660
65487
  end
64661
65488
  alltext=alltext..";\n"..subtitle
@@ -64671,16 +65498,16 @@ end
64671
65498
  local twrfrq=self.gettext:GetEntry("TOWERFREQ",self.locale)
64672
65499
  subtitle=string.format("%s %s",twrfrq,freqs)
64673
65500
  if not self.useSRS then
64674
- self:Transmission(ATIS.Sound.TowerFrequency,1.0,subtitle)
65501
+ self:Transmission(self.Sound.TowerFrequency,1.0,subtitle)
64675
65502
  for _,freq in pairs(self.towerfrequency)do
64676
65503
  local f=string.format("%.3f",freq)
64677
65504
  f=UTILS.Split(f,".")
64678
65505
  self.radioqueue:Number2Transmission(f[1],nil,0.5)
64679
65506
  if tonumber(f[2])>0 then
64680
- self:Transmission(ATIS.Sound.Decimal,0.2)
65507
+ self:Transmission(self.Sound.Decimal,0.2)
64681
65508
  self.radioqueue:Number2Transmission(f[2])
64682
65509
  end
64683
- self:Transmission(ATIS.Sound.MegaHertz,0.2)
65510
+ self:Transmission(self.Sound.MegaHertz,0.2)
64684
65511
  end
64685
65512
  end
64686
65513
  alltext=alltext..";\n"..subtitle
@@ -64690,15 +65517,15 @@ if ils then
64690
65517
  local ilstxt=self.gettext:GetEntry("ILSFREQ",self.locale)
64691
65518
  subtitle=string.format("%s %.2f MHz",ilstxt,ils.frequency)
64692
65519
  if not self.useSRS then
64693
- self:Transmission(ATIS.Sound.ILSFrequency,1.0,subtitle)
65520
+ self:Transmission(self.Sound.ILSFrequency,1.0,subtitle)
64694
65521
  local f=string.format("%.2f",ils.frequency)
64695
65522
  f=UTILS.Split(f,".")
64696
65523
  self.radioqueue:Number2Transmission(f[1],nil,0.5)
64697
65524
  if tonumber(f[2])>0 then
64698
- self:Transmission(ATIS.Sound.Decimal,0.2)
65525
+ self:Transmission(self.Sound.Decimal,0.2)
64699
65526
  self.radioqueue:Number2Transmission(f[2])
64700
65527
  end
64701
- self:Transmission(ATIS.Sound.MegaHertz,0.2)
65528
+ self:Transmission(self.Sound.MegaHertz,0.2)
64702
65529
  end
64703
65530
  alltext=alltext..";\n"..subtitle
64704
65531
  end
@@ -64707,15 +65534,15 @@ if ndb then
64707
65534
  local ndbtxt=self.gettext:GetEntry("OUTERNDB",self.locale)
64708
65535
  subtitle=string.format("%s %.2f MHz",ndbtxt,ndb.frequency)
64709
65536
  if not self.useSRS then
64710
- self:Transmission(ATIS.Sound.OuterNDBFrequency,1.0,subtitle)
65537
+ self:Transmission(self.Sound.OuterNDBFrequency,1.0,subtitle)
64711
65538
  local f=string.format("%.2f",ndb.frequency)
64712
65539
  f=UTILS.Split(f,".")
64713
65540
  self.radioqueue:Number2Transmission(f[1],nil,0.5)
64714
65541
  if tonumber(f[2])>0 then
64715
- self:Transmission(ATIS.Sound.Decimal,0.2)
65542
+ self:Transmission(self.Sound.Decimal,0.2)
64716
65543
  self.radioqueue:Number2Transmission(f[2])
64717
65544
  end
64718
- self:Transmission(ATIS.Sound.MegaHertz,0.2)
65545
+ self:Transmission(self.Sound.MegaHertz,0.2)
64719
65546
  end
64720
65547
  alltext=alltext..";\n"..subtitle
64721
65548
  end
@@ -64724,15 +65551,15 @@ if ndb then
64724
65551
  local ndbtxt=self.gettext:GetEntry("INNERNDB",self.locale)
64725
65552
  subtitle=string.format("%s %.2f MHz",ndbtxt,ndb.frequency)
64726
65553
  if not self.useSRS then
64727
- self:Transmission(ATIS.Sound.InnerNDBFrequency,1.0,subtitle)
65554
+ self:Transmission(self.Sound.InnerNDBFrequency,1.0,subtitle)
64728
65555
  local f=string.format("%.2f",ndb.frequency)
64729
65556
  f=UTILS.Split(f,".")
64730
65557
  self.radioqueue:Number2Transmission(f[1],nil,0.5)
64731
65558
  if tonumber(f[2])>0 then
64732
- self:Transmission(ATIS.Sound.Decimal,0.2)
65559
+ self:Transmission(self.Sound.Decimal,0.2)
64733
65560
  self.radioqueue:Number2Transmission(f[2])
64734
65561
  end
64735
- self:Transmission(ATIS.Sound.MegaHertz,0.2)
65562
+ self:Transmission(self.Sound.MegaHertz,0.2)
64736
65563
  end
64737
65564
  alltext=alltext..";\n"..subtitle
64738
65565
  end
@@ -64744,15 +65571,15 @@ if self.useSRS then
64744
65571
  subtitle=string.format("%s %.2f MHz",vorttstxt,self.vor)
64745
65572
  end
64746
65573
  if not self.useSRS then
64747
- self:Transmission(ATIS.Sound.VORFrequency,1.0,subtitle)
65574
+ self:Transmission(self.Sound.VORFrequency,1.0,subtitle)
64748
65575
  local f=string.format("%.2f",self.vor)
64749
65576
  f=UTILS.Split(f,".")
64750
65577
  self.radioqueue:Number2Transmission(f[1],nil,0.5)
64751
65578
  if tonumber(f[2])>0 then
64752
- self:Transmission(ATIS.Sound.Decimal,0.2)
65579
+ self:Transmission(self.Sound.Decimal,0.2)
64753
65580
  self.radioqueue:Number2Transmission(f[2])
64754
65581
  end
64755
- self:Transmission(ATIS.Sound.MegaHertz,0.2)
65582
+ self:Transmission(self.Sound.MegaHertz,0.2)
64756
65583
  end
64757
65584
  alltext=alltext..";\n"..subtitle
64758
65585
  end
@@ -64760,9 +65587,9 @@ if self.tacan then
64760
65587
  local tactxt=self.gettext:GetEntry("TACANCH",self.locale)
64761
65588
  subtitle=string.format(tactxt,self.tacan)
64762
65589
  if not self.useSRS then
64763
- self:Transmission(ATIS.Sound.TACANChannel,1.0,subtitle)
65590
+ self:Transmission(self.Sound.TACANChannel,1.0,subtitle)
64764
65591
  self.radioqueue:Number2Transmission(tostring(self.tacan),nil,0.2)
64765
- self.radioqueue:NewTransmission("NATO Alphabet/Xray.ogg",0.75,self.soundpath,nil,0.2)
65592
+ self.radioqueue:NewTransmission("Xray.ogg",0.75,self.soundpathNato,nil,0.2)
64766
65593
  end
64767
65594
  alltext=alltext..";\n"..subtitle
64768
65595
  end
@@ -64770,7 +65597,7 @@ if self.rsbn then
64770
65597
  local rsbntxt=self.gettext:GetEntry("RSBNCH",self.locale)
64771
65598
  subtitle=string.format("%s %d",rsbntxt,self.rsbn)
64772
65599
  if not self.useSRS then
64773
- self:Transmission(ATIS.Sound.RSBNChannel,1.0,subtitle)
65600
+ self:Transmission(self.Sound.RSBNChannel,1.0,subtitle)
64774
65601
  self.radioqueue:Number2Transmission(tostring(self.rsbn),nil,0.2)
64775
65602
  end
64776
65603
  alltext=alltext..";\n"..subtitle
@@ -64780,7 +65607,7 @@ if ndb then
64780
65607
  local prmtxt=self.gettext:GetEntry("PRMGCH",self.locale)
64781
65608
  subtitle=string.format("%s %d",prmtxt,ndb.frequency)
64782
65609
  if not self.useSRS then
64783
- self:Transmission(ATIS.Sound.PRMGChannel,1.0,subtitle)
65610
+ self:Transmission(self.Sound.PRMGChannel,1.0,subtitle)
64784
65611
  self.radioqueue:Number2Transmission(tostring(ndb.frequency),nil,0.5)
64785
65612
  end
64786
65613
  alltext=alltext..";\n"..subtitle
@@ -64791,8 +65618,8 @@ end
64791
65618
  local advtxt=self.gettext:GetEntry("ADVISE",self.locale)
64792
65619
  subtitle=string.format("%s %s",advtxt,NATO)
64793
65620
  if not self.useSRS then
64794
- self:Transmission(ATIS.Sound.AdviceOnInitial,0.5,subtitle)
64795
- self.radioqueue:NewTransmission(string.format("NATO Alphabet/%s.ogg",NATO),0.75,self.soundpath)
65621
+ self:Transmission(self.Sound.AdviceOnInitial,0.5,subtitle)
65622
+ self.radioqueue:NewTransmission(string.format("%s.ogg",NATO),0.75,self.soundpathNato)
64796
65623
  end
64797
65624
  alltext=alltext..";\n"..subtitle
64798
65625
  self:Report(alltext)
@@ -64829,7 +65656,7 @@ text=string.gsub(text,"(%d+)(%.)(%d+)","%1 "..delimiter.." %3")
64829
65656
  end
64830
65657
  local text=string.gsub(text,";"," . ")
64831
65658
  self:T("SRS TTS: "..text)
64832
- local duration=STTS.getSpeechTime(text,0.95)
65659
+ local duration=MSRS.getSpeechTime(text,0.95)
64833
65660
  self.msrsQ:NewTransmission(text,duration,self.msrs,nil,2)
64834
65661
  self.SRSText=text
64835
65662
  end
@@ -65012,12 +65839,20 @@ self.Stock=Stock or nil
65012
65839
  self.Mark=nil
65013
65840
  self.Subcategory=Subcategory or"Other"
65014
65841
  self.DontShowInMenu=DontShowInMenu or false
65842
+ self.ResourceMap=nil
65015
65843
  if type(Location)=="string"then
65016
65844
  Location=ZONE:New(Location)
65017
65845
  end
65018
65846
  self.Location=Location
65019
65847
  return self
65020
65848
  end
65849
+ function CTLD_CARGO:SetStaticResourceMap(ResourceMap)
65850
+ self.ResourceMap=ResourceMap
65851
+ return self
65852
+ end
65853
+ function CTLD_CARGO:GetStaticResourceMap()
65854
+ return self.ResourceMap
65855
+ end
65021
65856
  function CTLD_CARGO:GetLocation()
65022
65857
  return self.Location
65023
65858
  end
@@ -65335,9 +66170,10 @@ CTLD.UnitTypeCapabilities={
65335
66170
  ["AH-64D_BLK_II"]={type="AH-64D_BLK_II",crates=false,troops=true,cratelimit=0,trooplimit=2,length=17,cargoweightlimit=200},
65336
66171
  ["Bronco-OV-10A"]={type="Bronco-OV-10A",crates=false,troops=true,cratelimit=0,trooplimit=5,length=13,cargoweightlimit=1450},
65337
66172
  ["OH-6A"]={type="OH-6A",crates=false,troops=true,cratelimit=0,trooplimit=4,length=7,cargoweightlimit=550},
65338
- ["OH-58D"]={type="OH-58D",crates=false,troops=false,cratelimit=0,trooplimit=0,length=14,cargoweightlimit=400},
66173
+ ["OH-58D"]={type="OH58D",crates=false,troops=false,cratelimit=0,trooplimit=0,length=14,cargoweightlimit=400},
66174
+ ["CH-47Fbl1"]={type="CH-47Fbl1",crates=true,troops=true,cratelimit=4,trooplimit=31,length=20,cargoweightlimit=8000},
65339
66175
  }
65340
- CTLD.version="1.0.54"
66176
+ CTLD.version="1.0.58"
65341
66177
  function CTLD:New(Coalition,Prefixes,Alias)
65342
66178
  local self=BASE:Inherit(self,FSM:New())
65343
66179
  BASE:T({Coalition,Prefixes,Alias})
@@ -65460,6 +66296,7 @@ self.subcatsTroop={}
65460
66296
  self.nobuildinloadzones=true
65461
66297
  self.movecratesbeforebuild=true
65462
66298
  self.surfacetypes={land.SurfaceType.LAND,land.SurfaceType.ROAD,land.SurfaceType.RUNWAY,land.SurfaceType.SHALLOW_WATER}
66299
+ self.enableChinookGCLoading=true
65463
66300
  local AliaS=string.gsub(self.alias," ","_")
65464
66301
  self.filename=string.format("CTLD_%s_Persist.csv",AliaS)
65465
66302
  self.allowcratepickupagain=true
@@ -65527,7 +66364,7 @@ self.PlayerTaskQueue:Push(PlayerTask,PlayerTask.PlayerTaskNr)
65527
66364
  return self
65528
66365
  end
65529
66366
  function CTLD:_EventHandler(EventData)
65530
- self:T(string.format("%s Event = %d",self.lid,EventData.id))
66367
+ self:I(string.format("%s Event = %d",self.lid,EventData.id))
65531
66368
  local event=EventData
65532
66369
  if event.id==EVENTS.PlayerEnterAircraft or event.id==EVENTS.PlayerEnterUnit then
65533
66370
  local _coalition=event.IniCoalition
@@ -65549,11 +66386,29 @@ self.Loaded_Cargo[unitname]=nil
65549
66386
  self:_RefreshF10Menus()
65550
66387
  end
65551
66388
  return
65552
- elseif event.id==EVENTS.PlayerLeaveUnit then
66389
+ elseif event.id==EVENTS.PlayerLeaveUnit or event.id==EVENTS.UnitLost then
65553
66390
  local unitname=event.IniUnitName or"none"
65554
66391
  self.CtldUnits[unitname]=nil
65555
66392
  self.Loaded_Cargo[unitname]=nil
65556
66393
  self.MenusDone[unitname]=nil
66394
+ elseif event.id==EVENTS.Birth and event.IniObjectCategory==6 and string.match(event.IniUnitName,".+|%d%d:%d%d|PKG%d+")then
66395
+ local function RegisterDynamicCargo()
66396
+ local static=_DATABASE:AddStatic(event.IniUnitName)
66397
+ if static then
66398
+ static.DCSCargoObject=event.IniDCSUnit
66399
+ local Mass=event.IniDCSUnit:getCargoWeight()
66400
+ local country=event.IniDCSUnit:getCountry()
66401
+ local template=_DATABASE:_GetGenericStaticCargoGroupTemplate(event.IniUnitName,event.IniTypeName,Mass,event.IniCoalition,country)
66402
+ _DATABASE:_RegisterStaticTemplate(template,event.IniCoalition,"static",country)
66403
+ self:I("**** Ground crew created static cargo added: "..event.IniUnitName.." | Weight in kgs: "..Mass)
66404
+ local cargotype=self:AddStaticsCargo(event.IniUnitName,Mass,1,nil,true)
66405
+ self.CrateCounter=self.CrateCounter+1
66406
+ self.Spawned_Crates[self.CrateCounter]=static
66407
+ cargotype.Positionable=static
66408
+ table.insert(self.Spawned_Cargo,cargotype)
66409
+ end
66410
+ end
66411
+ self:ScheduleOnce(0.5,RegisterDynamicCargo)
65557
66412
  end
65558
66413
  return self
65559
66414
  end
@@ -65984,6 +66839,7 @@ self:_SendMessage("There are enough crates nearby already! Take care of those fi
65984
66839
  return self
65985
66840
  end
65986
66841
  local IsHerc=self:IsHercules(Unit)
66842
+ local IsHook=self:IsHook(Unit)
65987
66843
  local cargotype=Cargo
65988
66844
  local number=number or cargotype:GetCratesNeeded()
65989
66845
  local cratesneeded=cargotype:GetCratesNeeded()
@@ -66004,7 +66860,7 @@ local cratedistance=0
66004
66860
  local rheading=0
66005
66861
  local angleOffNose=0
66006
66862
  local addon=0
66007
- if IsHerc then
66863
+ if IsHerc or IsHook then
66008
66864
  addon=180
66009
66865
  end
66010
66866
  for i=1,number do
@@ -66048,17 +66904,25 @@ local dist=shipcoord:Get2DDistance(unitcoord)
66048
66904
  dist=dist-(20+math.random(1,10))
66049
66905
  local width=width/2
66050
66906
  local Offy=math.random(-width,width)
66051
- self.Spawned_Crates[self.CrateCounter]=SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
66907
+ local spawnstatic=SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
66052
66908
  :InitCargoMass(cgomass)
66053
66909
  :InitCargo(self.enableslingload)
66054
66910
  :InitLinkToUnit(Ship,dist,Offy,0)
66055
- :Spawn(270,cratealias)
66911
+ if isstatic then
66912
+ local map=cargotype:GetStaticResourceMap()
66913
+ spawnstatic.TemplateStaticUnit.resourcePayload=map
66914
+ end
66915
+ self.Spawned_Crates[self.CrateCounter]=spawnstatic:Spawn(270,cratealias)
66056
66916
  else
66057
- self.Spawned_Crates[self.CrateCounter]=SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
66917
+ local spawnstatic=SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
66058
66918
  :InitCoordinate(cratecoord)
66059
66919
  :InitCargoMass(cgomass)
66060
66920
  :InitCargo(self.enableslingload)
66061
- :Spawn(270,cratealias)
66921
+ if isstatic then
66922
+ local map=cargotype:GetStaticResourceMap()
66923
+ spawnstatic.TemplateStaticUnit.resourcePayload=map
66924
+ end
66925
+ self.Spawned_Crates[self.CrateCounter]=spawnstatic:Spawn(270,cratealias)
66062
66926
  end
66063
66927
  local templ=cargotype:GetTemplates()
66064
66928
  local sorte=cargotype:GetType()
@@ -66067,9 +66931,13 @@ self.CargoCounter=self.CargoCounter+1
66067
66931
  local realcargo=nil
66068
66932
  if drop then
66069
66933
  realcargo=CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,true,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],true,cargotype.PerCrateMass,nil,subcat)
66934
+ local map=cargotype:GetStaticResourceMap()
66935
+ realcargo:SetStaticResourceMap(map)
66070
66936
  table.insert(droppedcargo,realcargo)
66071
66937
  else
66072
66938
  realcargo=CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,false,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],false,cargotype.PerCrateMass,nil,subcat)
66939
+ local map=cargotype:GetStaticResourceMap()
66940
+ realcargo:SetStaticResourceMap(map)
66073
66941
  end
66074
66942
  table.insert(self.Spawned_Cargo,realcargo)
66075
66943
  end
@@ -66111,14 +66979,17 @@ if isstatic then
66111
66979
  basetype=cratetemplate
66112
66980
  end
66113
66981
  self.CrateCounter=self.CrateCounter+1
66114
- self.Spawned_Crates[self.CrateCounter]=SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
66982
+ local spawnstatic=SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
66115
66983
  :InitCargoMass(cgomass)
66116
66984
  :InitCargo(self.enableslingload)
66117
66985
  :InitCoordinate(cratecoord)
66118
- :Spawn(270,cratealias)
66986
+ if isstatic then
66987
+ local map=cargotype:GetStaticResourceMap()
66988
+ spawnstatic.TemplateStaticUnit.resourcePayload=map
66989
+ end
66990
+ self.Spawned_Crates[self.CrateCounter]=spawnstatic:Spawn(270,cratealias)
66119
66991
  local templ=cargotype:GetTemplates()
66120
66992
  local sorte=cargotype:GetType()
66121
- self.CargoCounter=self.CargoCounter+1
66122
66993
  cargotype.Positionable=self.Spawned_Crates[self.CrateCounter]
66123
66994
  table.insert(self.Spawned_Cargo,cargotype)
66124
66995
  return self
@@ -66132,8 +67003,8 @@ end
66132
67003
  function CTLD:_ListCratesNearby(_group,_unit)
66133
67004
  self:T(self.lid.." _ListCratesNearby")
66134
67005
  local finddist=self.CrateDistance or 35
66135
- local crates,number=self:_FindCratesNearby(_group,_unit,finddist,true)
66136
- if number>0 then
67006
+ local crates,number,loadedbygc,indexgc=self:_FindCratesNearby(_group,_unit,finddist,true)
67007
+ if number>0 or indexgc>0 then
66137
67008
  local text=REPORT:New("Crates Found Nearby:")
66138
67009
  text:Add("------------------------------------------------------------")
66139
67010
  for _,_entry in pairs(crates)do
@@ -66150,6 +67021,19 @@ if text:GetCount()==1 then
66150
67021
  text:Add(" N O N E")
66151
67022
  end
66152
67023
  text:Add("------------------------------------------------------------")
67024
+ if indexgc>0 then
67025
+ text:Add("Probably ground crew loaded (F8)")
67026
+ for _,_entry in pairs(loadedbygc)do
67027
+ local entry=_entry
67028
+ local name=entry:GetName()
67029
+ local dropped=entry:WasDropped()
67030
+ if dropped then
67031
+ text:Add(string.format("Dropped crate for %s, %dkg",name,entry.PerCrateMass))
67032
+ else
67033
+ text:Add(string.format("Crate for %s, %dkg",name,entry.PerCrateMass))
67034
+ end
67035
+ end
67036
+ end
66153
67037
  self:_SendMessage(text:Text(),30,true,_group)
66154
67038
  else
66155
67039
  self:_SendMessage(string.format("No (loadable) crates within %d meters!",finddist),10,false,_group)
@@ -66210,12 +67094,15 @@ local finddist=_dist
66210
67094
  local location=_group:GetCoordinate()
66211
67095
  local existingcrates=self.Spawned_Cargo
66212
67096
  local index=0
67097
+ local indexg=0
66213
67098
  local found={}
67099
+ local LoadedbyGC={}
66214
67100
  local loadedmass=0
66215
67101
  local unittype="none"
66216
67102
  local capabilities={}
66217
67103
  local maxmass=2000
66218
67104
  local maxloadable=2000
67105
+ local IsNoHook=not self:IsHook(_unit)
66219
67106
  if not _ignoreweight then
66220
67107
  maxloadable=self:_GetMaxLoadableMass(_unit)
66221
67108
  end
@@ -66223,20 +67110,46 @@ self:T(self.lid.." Max loadable mass: "..maxloadable)
66223
67110
  for _,_cargoobject in pairs(existingcrates)do
66224
67111
  local cargo=_cargoobject
66225
67112
  local static=cargo:GetPositionable()
66226
- local staticid=cargo:GetID()
66227
67113
  local weight=cargo:GetMass()
67114
+ local staticid=cargo:GetID()
66228
67115
  self:T(self.lid.." Found cargo mass: "..weight)
66229
- if static and static:IsAlive()then
66230
- local staticpos=static:GetCoordinate()
67116
+ local cargoalive=false
67117
+ local dcsunit=nil
67118
+ local dcsunitpos=nil
67119
+ if static and static.DCSCargoObject then
67120
+ dcsunit=Unit.getByName(static.StaticName)
67121
+ if dcsunit then
67122
+ cargoalive=dcsunit:isExist()~=nil and true or false
67123
+ end
67124
+ if cargoalive==true then
67125
+ local dcsvec3=dcsunit:getPoint()or dcsunit:getPosition().p or{x=0,y=0,z=0}
67126
+ self:T({dcsvec3=dcsunit:getPoint(),dcspos=dcsunit:getPosition().p})
67127
+ if dcsvec3 then
67128
+ dcsunitpos=COORDINATE:New(dcsvec3.x,dcsvec3.z,dcsvec3.y)
67129
+ end
67130
+ end
67131
+ end
67132
+ if static and(static:IsAlive()or cargoalive)then
67133
+ local staticpos=static:GetCoordinate()or dcsunitpos
67134
+ local landheight=staticpos:GetLandHeight()
67135
+ local agl=staticpos.y-landheight
67136
+ agl=UTILS.Round(agl,2)
67137
+ local GCloaded=agl>0 and true or false
67138
+ if IsNoHook==true then GCloaded=false end
66231
67139
  local distance=self:_GetDistance(location,staticpos)
66232
- if distance<=finddist and static and(weight<=maxloadable or _ignoreweight)then
67140
+ self:T({name=static:GetName(),IsNoHook=IsNoHook,agl=agl,GCloaded=GCloaded,distance=string.format("%.2f",distance or 0)})
67141
+ if(not GCloaded)and distance<=finddist and static and(weight<=maxloadable or _ignoreweight)then
66233
67142
  index=index+1
66234
67143
  table.insert(found,staticid,cargo)
66235
67144
  maxloadable=maxloadable-weight
66236
67145
  end
67146
+ if GCloaded==true and distance<10 and static then
67147
+ indexg=indexg+1
67148
+ table.insert(LoadedbyGC,staticid,cargo)
66237
67149
  end
66238
67150
  end
66239
- return found,index
67151
+ end
67152
+ return found,index,LoadedbyGC,indexg
66240
67153
  end
66241
67154
  function CTLD:_LoadCratesNearby(Group,Unit)
66242
67155
  self:T(self.lid.." _LoadCratesNearby")
@@ -66249,6 +67162,10 @@ local cancrates=capabilities.crates
66249
67162
  local cratelimit=capabilities.cratelimit
66250
67163
  local grounded=not self:IsUnitInAir(Unit)
66251
67164
  local canhoverload=self:CanHoverLoad(Unit)
67165
+ if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen(Unit:GetName())then
67166
+ self:_SendMessage("You need to open the door(s) to load cargo!",10,false,Group)
67167
+ if not self.debug then return self end
67168
+ end
66252
67169
  if not cancrates then
66253
67170
  self:_SendMessage("Sorry this chopper cannot carry crates!",10,false,Group)
66254
67171
  elseif self.forcehoverload and not canhoverload then
@@ -66390,7 +67307,9 @@ local cratelimit=capabilities.cratelimit
66390
67307
  local loadedcargo=self.Loaded_Cargo[unitname]or{}
66391
67308
  local loadedmass=self:_GetUnitCargoMass(Unit)
66392
67309
  local maxloadable=self:_GetMaxLoadableMass(Unit)
66393
- if self.Loaded_Cargo[unitname]then
67310
+ local finddist=self.CrateDistance or 35
67311
+ local _,_,loadedgc,loadedno=self:_FindCratesNearby(Group,Unit,finddist,true)
67312
+ if self.Loaded_Cargo[unitname]or loadedno>0 then
66394
67313
  local no_troops=loadedcargo.Troopsloaded or 0
66395
67314
  local no_crates=loadedcargo.Cratesloaded or 0
66396
67315
  local cargotable=loadedcargo.Cargo or{}
@@ -66412,7 +67331,7 @@ end
66412
67331
  report:Add("------------------------------------------------------------")
66413
67332
  report:Add(" -- CRATES --")
66414
67333
  local cratecount=0
66415
- for _,_cargo in pairs(cargotable)do
67334
+ for _,_cargo in pairs(cargotable or{})do
66416
67335
  local cargo=_cargo
66417
67336
  local type=cargo:GetType()
66418
67337
  if(type~=CTLD_CARGO.Enum.TROOPS and type~=CTLD_CARGO.Enum.ENGINEERS)and(not cargo:WasDropped()or self.allowcratepickupagain)then
@@ -66423,6 +67342,18 @@ end
66423
67342
  if cratecount==0 then
66424
67343
  report:Add(" N O N E")
66425
67344
  end
67345
+ if loadedno>0 then
67346
+ report:Add("------------------------------------------------------------")
67347
+ report:Add(" -- CRATES loaded via F8 --")
67348
+ for _,_cargo in pairs(loadedgc or{})do
67349
+ local cargo=_cargo
67350
+ local type=cargo:GetType()
67351
+ if(type~=CTLD_CARGO.Enum.TROOPS and type~=CTLD_CARGO.Enum.ENGINEERS)then
67352
+ report:Add(string.format("Crate: %s size 1",cargo:GetName()))
67353
+ loadedmass=loadedmass+cargo:GetMass()
67354
+ end
67355
+ end
67356
+ end
66426
67357
  report:Add("------------------------------------------------------------")
66427
67358
  report:Add("Total Mass: "..loadedmass.." kg. Loadable: "..maxloadable.." kg.")
66428
67359
  local text=report:Text()
@@ -66522,6 +67453,13 @@ else
66522
67453
  return false
66523
67454
  end
66524
67455
  end
67456
+ function CTLD:IsHook(Unit)
67457
+ if string.find(Unit:GetTypeName(),"CH.47")then
67458
+ return true
67459
+ else
67460
+ return false
67461
+ end
67462
+ end
66525
67463
  function CTLD:_GetUnitPositions(Coordinate,Radius,Heading,Template)
66526
67464
  local Positions={}
66527
67465
  local template=_DATABASE:GetGroupTemplate(Template)
@@ -66558,7 +67496,8 @@ droppingatbase=true
66558
67496
  end
66559
67497
  local hoverunload=self:IsCorrectHover(Unit)
66560
67498
  local IsHerc=self:IsHercules(Unit)
66561
- if IsHerc then
67499
+ local IsHook=self:IsHook(Unit)
67500
+ if IsHerc and(not IsHook)then
66562
67501
  hoverunload=self:IsCorrectFlightParameters(Unit)
66563
67502
  end
66564
67503
  local grounded=not self:IsUnitInAir(Unit)
@@ -66615,7 +67554,7 @@ end
66615
67554
  end
66616
67555
  else
66617
67556
  self:_SendMessage("Troops have returned to base!",10,false,Group)
66618
- self:__TroopsRTB(1,Group,Unit)
67557
+ self:__TroopsRTB(1,Group,Unit,zonename,zone)
66619
67558
  end
66620
67559
  local loaded={}
66621
67560
  loaded.Troopsloaded=0
@@ -66666,9 +67605,14 @@ return self
66666
67605
  end
66667
67606
  end
66668
67607
  end
67608
+ if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen(Unit:GetName())then
67609
+ self:_SendMessage("You need to open the door(s) to drop cargo!",10,false,Group)
67610
+ if not self.debug then return self end
67611
+ end
66669
67612
  local hoverunload=self:IsCorrectHover(Unit)
66670
67613
  local IsHerc=self:IsHercules(Unit)
66671
- if IsHerc then
67614
+ local IsHook=self:IsHook(Unit)
67615
+ if IsHerc and(not IsHook)then
66672
67616
  hoverunload=self:IsCorrectFlightParameters(Unit)
66673
67617
  end
66674
67618
  local grounded=not self:IsUnitInAir(Unit)
@@ -66996,7 +67940,7 @@ local PlayerSet=self.PilotGroups
66996
67940
  local PlayerTable=PlayerSet:GetSetObjects()
66997
67941
  local _UnitList={}
66998
67942
  for _key,_group in pairs(PlayerTable)do
66999
- local _unit=_group:GetUnit(1)
67943
+ local _unit=_group:GetFirstUnitAlive()
67000
67944
  if _unit then
67001
67945
  if _unit:IsAlive()and _unit:IsPlayer()then
67002
67946
  if _unit:IsHelicopter()or(self:IsHercules(_unit)and self.enableHercules)then
@@ -67042,6 +67986,8 @@ local unittype=_unit:GetTypeName()
67042
67986
  local capabilities=self:_GetUnitCapabilities(_unit)
67043
67987
  local cantroops=capabilities.troops
67044
67988
  local cancrates=capabilities.crates
67989
+ local isHook=self:IsHook(_unit)
67990
+ local nohookswitch=not(isHook and self.enableChinookGCLoading)
67045
67991
  local topmenu=MENU_GROUP:New(_group,"CTLD",nil)
67046
67992
  local toptroops=nil
67047
67993
  local topcrates=nil
@@ -67095,7 +68041,9 @@ local unloadmenu1=MENU_GROUP_COMMAND:New(_group,"Drop troops",toptroops,self._Un
67095
68041
  local extractMenu1=MENU_GROUP_COMMAND:New(_group,"Extract troops",toptroops,self._ExtractTroops,self,_group,_unit):Refresh()
67096
68042
  end
67097
68043
  if cancrates then
68044
+ if nohookswitch then
67098
68045
  local loadmenu=MENU_GROUP_COMMAND:New(_group,"Load crates",topcrates,self._LoadCratesNearby,self,_group,_unit)
68046
+ end
67099
68047
  local cratesmenu=MENU_GROUP:New(_group,"Get Crates",topcrates)
67100
68048
  local packmenu=MENU_GROUP_COMMAND:New(_group,"Pack crates",topcrates,self._PackCratesNearby,self,_group,_unit)
67101
68049
  local removecratesmenu=MENU_GROUP:New(_group,"Remove crates",topcrates)
@@ -67162,11 +68110,14 @@ end
67162
68110
  end
67163
68111
  listmenu=MENU_GROUP_COMMAND:New(_group,"List crates nearby",topcrates,self._ListCratesNearby,self,_group,_unit)
67164
68112
  local removecrates=MENU_GROUP_COMMAND:New(_group,"Remove crates nearby",removecratesmenu,self._RemoveCratesNearby,self,_group,_unit)
67165
- local unloadmenu=MENU_GROUP_COMMAND:New(_group,"Drop crates",topcrates,self._UnloadCrates,self,_group,_unit)
68113
+ local unloadmenu
68114
+ if nohookswitch then
68115
+ unloadmenu=MENU_GROUP_COMMAND:New(_group,"Drop crates",topcrates,self._UnloadCrates,self,_group,_unit)
68116
+ end
67166
68117
  if not self.nobuildmenu then
67167
68118
  local buildmenu=MENU_GROUP_COMMAND:New(_group,"Build crates",topcrates,self._BuildCrates,self,_group,_unit)
67168
68119
  local repairmenu=MENU_GROUP_COMMAND:New(_group,"Repair",topcrates,self._RepairCrates,self,_group,_unit):Refresh()
67169
- else
68120
+ elseif unloadmenu then
67170
68121
  unloadmenu:Refresh()
67171
68122
  end
67172
68123
  end
@@ -67226,16 +68177,28 @@ self:T(self.lid.." AddStaticsCargo")
67226
68177
  self.CargoCounter=self.CargoCounter+1
67227
68178
  local type=CTLD_CARGO.Enum.STATIC
67228
68179
  local template=STATIC:FindByName(Name,true):GetTypeName()
68180
+ local unittemplate=_DATABASE:GetStaticUnitTemplate(Name)
68181
+ local ResourceMap=nil
68182
+ if unittemplate and unittemplate.resourcePayload then
68183
+ ResourceMap=UTILS.DeepCopy(unittemplate.resourcePayload)
68184
+ end
67229
68185
  local cargo=CTLD_CARGO:New(self.CargoCounter,Name,template,type,false,false,1,nil,nil,Mass,Stock,SubCategory,DontShowInMenu,Location)
68186
+ cargo:SetStaticResourceMap(ResourceMap)
67230
68187
  table.insert(self.Cargo_Statics,cargo)
67231
- return self
68188
+ return cargo
67232
68189
  end
67233
68190
  function CTLD:GetStaticsCargoFromTemplate(Name,Mass)
67234
68191
  self:T(self.lid.." GetStaticsCargoFromTemplate")
67235
68192
  self.CargoCounter=self.CargoCounter+1
67236
68193
  local type=CTLD_CARGO.Enum.STATIC
67237
68194
  local template=STATIC:FindByName(Name,true):GetTypeName()
68195
+ local unittemplate=_DATABASE:GetStaticUnitTemplate(Name)
68196
+ local ResourceMap=nil
68197
+ if unittemplate and unittemplate.resourcePayload then
68198
+ ResourceMap=UTILS.DeepCopy(unittemplate.resourcePayload)
68199
+ end
67238
68200
  local cargo=CTLD_CARGO:New(self.CargoCounter,Name,template,type,false,false,1,nil,nil,Mass,1)
68201
+ cargo:SetStaticResourceMap(ResourceMap)
67239
68202
  return cargo
67240
68203
  end
67241
68204
  function CTLD:AddCratesRepair(Name,Template,Type,NoCrates,PerCrateMass,Stock,SubCategory,DontShowInMenu,Location)
@@ -68208,6 +69171,8 @@ end
68208
69171
  self:HandleEvent(EVENTS.PlayerEnterAircraft,self._EventHandler)
68209
69172
  self:HandleEvent(EVENTS.PlayerEnterUnit,self._EventHandler)
68210
69173
  self:HandleEvent(EVENTS.PlayerLeaveUnit,self._EventHandler)
69174
+ self:HandleEvent(EVENTS.UnitLost,self._EventHandler)
69175
+ self:HandleEvent(EVENTS.Birth,self._EventHandler)
68211
69176
  self:__Status(-5)
68212
69177
  if self.enableLoadSave then
68213
69178
  local interval=self.saveinterval
@@ -68347,7 +69312,7 @@ self:_MoveGroupToZone(Vehicle)
68347
69312
  end
68348
69313
  return self
68349
69314
  end
68350
- function CTLD:onbeforeTroopsRTB(From,Event,To,Group,Unit)
69315
+ function CTLD:onbeforeTroopsRTB(From,Event,To,Group,Unit,ZoneName,ZoneObject)
68351
69316
  self:T({From,Event,To})
68352
69317
  return self
68353
69318
  end
@@ -68597,6 +69562,8 @@ cargotemplates=UTILS.Split(cargotemplates,";")
68597
69562
  injectstatic=CTLD_CARGO:New(nil,cargoname,cargotemplates,cargotype,true,true,size,nil,true,mass)
68598
69563
  elseif cargotype==CTLD_CARGO.Enum.STATIC or cargotype==CTLD_CARGO.Enum.REPAIR then
68599
69564
  injectstatic=CTLD_CARGO:New(nil,cargoname,cargotemplates,cargotype,true,true,size,nil,true,mass)
69565
+ local map=cargotype:GetStaticResourceMap()
69566
+ injectstatic:SetStaticResourceMap(map)
68600
69567
  end
68601
69568
  if injectstatic then
68602
69569
  self:InjectStatics(dropzone,injectstatic)
@@ -68799,6 +69766,8 @@ local theStatic=SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
68799
69766
  :Spawn(270,_name.."-Container-"..math.random(1,100000))
68800
69767
  self.CTLD.Spawned_Crates[self.CTLD.CrateCounter]=theStatic
68801
69768
  local newCargo=CTLD_CARGO:New(self.CTLD.CargoCounter,theCargo.Name,theCargo.Templates,theCargo.CargoType,true,false,theCargo.CratesNeeded,self.CTLD.Spawned_Crates[self.CTLD.CrateCounter],true,theCargo.PerCrateMass,nil,theCargo.Subcategory)
69769
+ local map=theCargo:GetStaticResourceMap()
69770
+ newCargo:SetStaticResourceMap(map)
68802
69771
  table.insert(self.CTLD.Spawned_Cargo,newCargo)
68803
69772
  newCargo:SetWasDropped(true)
68804
69773
  newCargo:SetHasMoved(true)
@@ -69069,7 +70038,8 @@ CSAR.AircraftType["Bronco-OV-10A"]=2
69069
70038
  CSAR.AircraftType["MH-60R"]=10
69070
70039
  CSAR.AircraftType["OH-6A"]=2
69071
70040
  CSAR.AircraftType["OH-58D"]=2
69072
- CSAR.version="1.0.24"
70041
+ CSAR.AircraftType["CH-47Fbl1"]=31
70042
+ CSAR.version="1.0.26"
69073
70043
  function CSAR:New(Coalition,Template,Alias)
69074
70044
  local self=BASE:Inherit(self,FSM:New())
69075
70045
  BASE:T({Coalition,Template,Alias})
@@ -70234,7 +71204,7 @@ local allheligroupset=self.allheligroupset
70234
71204
  local _allHeliGroups=allheligroupset:GetSetObjects()
70235
71205
  local _UnitList={}
70236
71206
  for _key,_group in pairs(_allHeliGroups)do
70237
- local _unit=_group:GetUnit(1)
71207
+ local _unit=_group:GetFirstUnitAlive()
70238
71208
  if _unit then
70239
71209
  if _unit:IsAlive()and _unit:IsPlayer()then
70240
71210
  local unitName=_unit:GetName()
@@ -80295,6 +81265,9 @@ function SOUNDFILE:GetFileName()
80295
81265
  return self.filename
80296
81266
  end
80297
81267
  function SOUNDFILE:SetDuration(Duration)
81268
+ if Duration and type(Duration)=="string"then
81269
+ Duration=tonumber(Duration)
81270
+ end
80298
81271
  self.duration=Duration or 3
80299
81272
  return self
80300
81273
  end
@@ -80325,7 +81298,7 @@ ClassName="SOUNDTEXT",
80325
81298
  function SOUNDTEXT:New(Text,Duration)
80326
81299
  local self=BASE:Inherit(self,BASE:New())
80327
81300
  self:SetText(Text)
80328
- self:SetDuration(Duration or STTS.getSpeechTime(Text))
81301
+ self:SetDuration(Duration or MSRS.getSpeechTime(Text))
80329
81302
  self:T(string.format("New SOUNDTEXT: text=%s, duration=%.1f sec",self.text,self.duration))
80330
81303
  return self
80331
81304
  end
@@ -80360,6 +81333,7 @@ SubtitleDuration=0,
80360
81333
  Power=100,
80361
81334
  Loop=false,
80362
81335
  alias=nil,
81336
+ moduhasbeenset=false,
80363
81337
  }
80364
81338
  function RADIO:New(Positionable)
80365
81339
  local self=BASE:Inherit(self,BASE:New())
@@ -80395,12 +81369,13 @@ end
80395
81369
  function RADIO:SetFrequency(Frequency)
80396
81370
  self:F2(Frequency)
80397
81371
  if type(Frequency)=="number"then
80398
- self.Frequency=Frequency*1000000
81372
+ self.Frequency=Frequency
81373
+ self.HertzFrequency=Frequency*1000000
80399
81374
  if self.Positionable.ClassName=="UNIT"or self.Positionable.ClassName=="GROUP"then
80400
81375
  local commandSetFrequency={
80401
81376
  id="SetFrequency",
80402
81377
  params={
80403
- frequency=self.Frequency,
81378
+ frequency=self.HertzFrequency,
80404
81379
  modulation=self.Modulation,
80405
81380
  }
80406
81381
  }
@@ -80417,6 +81392,10 @@ self:F2(Modulation)
80417
81392
  if type(Modulation)=="number"then
80418
81393
  if Modulation==radio.modulation.AM or Modulation==radio.modulation.FM then
80419
81394
  self.Modulation=Modulation
81395
+ if self.moduhasbeenset==false and Modulation==radio.modulation.FM then
81396
+ self:SetFrequency(self.Frequency)
81397
+ end
81398
+ self.moduhasbeenset=true
80420
81399
  return self
80421
81400
  end
80422
81401
  end
@@ -80622,7 +81601,7 @@ self:E(self.lid.."ERROR: No duration of transmission specified.")
80622
81601
  return nil
80623
81602
  end
80624
81603
  if type(duration)~="number"then
80625
- self:E(self.lid.."ERROR: Duration specified is NOT a number.")
81604
+ self:E(self.lid..string.format("ERROR: Duration specified is NOT a number but type=%s. Filename=%s, duration=%s",type(duration),tostring(filename),tostring(duration)))
80626
81605
  return nil
80627
81606
  end
80628
81607
  local transmission={}
@@ -80666,6 +81645,7 @@ end
80666
81645
  return wait
80667
81646
  end
80668
81647
  function RADIOQUEUE:Broadcast(transmission)
81648
+ self:T("Broadcast")
80669
81649
  if((transmission.soundfile and transmission.soundfile.useSRS)or transmission.soundtext)and self.msrs then
80670
81650
  self:_BroadcastSRS(transmission)
80671
81651
  return
@@ -80704,7 +81684,7 @@ local text=string.format("file=%s, freq=%.2f MHz, duration=%.2f sec, subtitle=%s
80704
81684
  MESSAGE:New(text,2,"RADIOQUEUE "..self.alias):ToAll()
80705
81685
  end
80706
81686
  else
80707
- self:T(self.lid..string.format("Broadcasting via trigger.action.radioTransmission()."))
81687
+ self:T(self.lid..string.format("Broadcasting via trigger.action.radioTransmission()"))
80708
81688
  local vec3=nil
80709
81689
  if self.sendername then
80710
81690
  vec3=self:_GetRadioSenderCoord()
@@ -80720,6 +81700,8 @@ if self.Debugmode then
80720
81700
  local text=string.format("file=%s, freq=%.2f MHz, duration=%.2f sec, subtitle=%s",filename,self.frequency/1000000,transmission.duration,transmission.subtitle or"")
80721
81701
  MESSAGE:New(string.format(text,filename,transmission.duration,transmission.subtitle or""),5,"RADIOQUEUE "..self.alias):ToAll()
80722
81702
  end
81703
+ else
81704
+ self:E("ERROR: Could not get vec3 to determine transmission origin! Did you specify a sender and is it still alive?")
80723
81705
  end
80724
81706
  end
80725
81707
  end