Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Applevangelist 2024-04-27 17:29:15 +02:00
commit bbae343b0e
11 changed files with 1982 additions and 1674 deletions

View File

@ -57,6 +57,7 @@ jobs:
- name: Update apt-get (needed for act docker image) - name: Update apt-get (needed for act docker image)
run: | run: |
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get -qq update sudo apt-get -qq update
- name: Install tree - name: Install tree

View File

@ -1157,6 +1157,15 @@ function BASE:_Serialize(Arguments)
return text return text
end end
----- (Internal) Serialize arguments
---- @param #BASE self
---- @param #table Arguments
---- @return #string Text
--function BASE:_Serialize(Arguments)
-- local text=UTILS.BasicSerialize(Arguments)
-- return text
--end
--- Trace a function call. This function is private. --- Trace a function call. This function is private.
-- @param #BASE self -- @param #BASE self
-- @param Arguments A #table or any field. -- @param Arguments A #table or any field.

View File

@ -395,7 +395,8 @@ end
--- Sends a MESSAGE to all players. --- Sends a MESSAGE to all players.
-- @param #MESSAGE self -- @param #MESSAGE self
-- @param Core.Settings#Settings Settings (Optional) Settings for message display. -- @param Core.Settings#Settings Settings (Optional) Settings for message display.
-- @return #MESSAGE -- @param #number Delay (Optional) Delay in seconds before the message is send. Default instantly (`nil`).
-- @return #MESSAGE self
-- @usage -- @usage
-- --
-- -- Send a message created to all players. -- -- Send a message created to all players.
@ -406,9 +407,13 @@ end
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 ) -- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 )
-- MessageAll:ToAll() -- MessageAll:ToAll()
-- --
function MESSAGE:ToAll( Settings ) function MESSAGE:ToAll( Settings, Delay )
self:F() self:F()
if Delay and Delay>0 then
self:ScheduleOnce(Delay, MESSAGE.ToAll, self, Settings, 0)
else
if self.MessageType then if self.MessageType then
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
self.MessageDuration = Settings:GetMessageTime( self.MessageType ) self.MessageDuration = Settings:GetMessageTime( self.MessageType )
@ -420,6 +425,8 @@ function MESSAGE:ToAll( Settings )
trigger.action.outText( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen ) trigger.action.outText( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
end end
end
return self return self
end end

View File

@ -292,9 +292,10 @@ SPAWN = {
--- Enumerator for spawns at airbases --- Enumerator for spawns at airbases
-- @type SPAWN.Takeoff -- @type SPAWN.Takeoff
-- @extends Wrapper.Group#GROUP.Takeoff -- @field #number Air Take off happens in air.
-- @field #number Runway Spawn on runway. Does not work in MP!
-- @field #SPAWN.Takeoff Takeoff -- @field #number Hot Spawn at parking with engines on.
-- @field #number Cold Spawn at parking with engines off.
SPAWN.Takeoff = { SPAWN.Takeoff = {
Air = 1, Air = 1,
Runway = 2, Runway = 2,
@ -3275,7 +3276,7 @@ end
--- Get the index from a given group. --- Get the index from a given group.
-- The function will search the name of the group for a #, and will return the number behind the #-mark. -- The function will search the name of the group for a #, and will return the number behind the #-mark.
function SPAWN:GetSpawnIndexFromGroup( SpawnGroup ) function SPAWN:GetSpawnIndexFromGroup( SpawnGroup )
self:F2( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnGroup } ) self:F3( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnGroup } )
local IndexString = string.match( SpawnGroup:GetName(), "#(%d*)$" ):sub( 2 ) local IndexString = string.match( SpawnGroup:GetName(), "#(%d*)$" ):sub( 2 )
local Index = tonumber( IndexString ) local Index = tonumber( IndexString )
@ -3287,7 +3288,7 @@ end
--- Return the last maximum index that can be used. --- Return the last maximum index that can be used.
function SPAWN:_GetLastIndex() function SPAWN:_GetLastIndex()
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } ) self:F3( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
return self.SpawnMaxGroups return self.SpawnMaxGroups
end end

File diff suppressed because it is too large Load Diff

View File

@ -976,7 +976,10 @@ function ARMYGROUP:onafterSpawned(From, Event, To)
-- Update route. -- Update route.
if Nwp>1 and self.isMobile then if Nwp>1 and self.isMobile then
self:T(self.lid..string.format("Got %d waypoints on spawn ==> Cruise in -1.0 sec!", Nwp)) self:T(self.lid..string.format("Got %d waypoints on spawn ==> Cruise in -1.0 sec!", Nwp))
self:__Cruise(-1, nil, self.option.Formation) local wp=self:GetWaypointNext()
self.option.Formation=wp.action
--self:__Cruise(-1, nil, self.option.Formation)
self:__Cruise(-1)
else else
self:T(self.lid.."No waypoints on spawn ==> Full Stop!") self:T(self.lid.."No waypoints on spawn ==> Full Stop!")
self:FullStop() self:FullStop()
@ -1287,6 +1290,7 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, N, Speed, Formation)
-- Current set speed in m/s. -- Current set speed in m/s.
self.speedWp=wp.speed self.speedWp=wp.speed
self:T(self.lid..string.format("Expected/waypoint speed=%.1f m/s", self.speedWp))
-- Debug output. -- Debug output.
if self.verbose>=10 then --or self.attribute==GROUP.Attribute.GROUND_APC then if self.verbose>=10 then --or self.attribute==GROUP.Attribute.GROUND_APC then
@ -1950,7 +1954,7 @@ function ARMYGROUP:onafterCruise(From, Event, To, Speed, Formation)
self.dTwait=nil self.dTwait=nil
-- Debug info. -- Debug info.
self:T(self.lid.."Cruise ==> Update route in 0.01 sec") self:T(self.lid..string.format("Cruise ==> Update route in 0.01 sec (speed=%s, formation=%s)", tostring(Speed), tostring(Formation)))
-- Update route. -- Update route.
self:__UpdateRoute(-0.01, nil, nil, Speed, Formation) self:__UpdateRoute(-0.01, nil, nil, Speed, Formation)
@ -2045,8 +2049,11 @@ end
-- @param #ARMYGROUP self -- @param #ARMYGROUP self
-- @param #table Template Template used to init the group. Default is `self.template`. -- @param #table Template Template used to init the group. Default is `self.template`.
-- @return #ARMYGROUP self -- @return #ARMYGROUP self
function ARMYGROUP:_InitGroup(Template) function ARMYGROUP:_InitGroup(Template, Delay)
if Delay and Delay>0 then
self:ScheduleOnce(Delay, ARMYGROUP._InitGroup, self, Template, 0)
else
-- First check if group was already initialized. -- First check if group was already initialized.
if self.groupinitialized then if self.groupinitialized then
self:T(self.lid.."WARNING: Group was already initialized! Will NOT do it again!") self:T(self.lid.."WARNING: Group was already initialized! Will NOT do it again!")
@ -2093,6 +2100,56 @@ function ARMYGROUP:_InitGroup(Template)
-- Get current formation from first waypoint. -- Get current formation from first waypoint.
self.option.Formation=template.route.points[1].action self.option.Formation=template.route.points[1].action
-- Set default formation to "on road".
self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad
-- First check if group was already initialized.
if self.groupinitialized then
self:T(self.lid.."WARNING: Group was already initialized! Will NOT do it again!")
return
end
self:I(self.lid.."FF Initializing Group")
-- Get template of group.
local template=Template or self:_GetTemplate()
-- Ground are always AI.
self.isAI=true
-- Is (template) group late activated.
self.isLateActivated=template.lateActivation
-- Ground groups cannot be uncontrolled.
self.isUncontrolled=false
-- Max speed in km/h.
self.speedMax=self.group:GetSpeedMax()
-- Is group mobile?
if self.speedMax>3.6 then
self.isMobile=true
else
self.isMobile=false
end
-- Cruise speed in km/h
self.speedCruise=self.speedMax*0.7
-- Group ammo.
self.ammo=self:GetAmmoTot()
-- Radio parameters from template.
self.radio.On=false -- Radio is always OFF for ground.
self.radio.Freq=133
self.radio.Modu=radio.modulation.AM
-- Set default radio.
self:SetDefaultRadio(self.radio.Freq, self.radio.Modu, self.radio.On)
-- Get current formation from first waypoint.
self.option.Formation=template.route.points[1].action
-- Set default formation to "on road". -- Set default formation to "on road".
self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad
@ -2106,10 +2163,11 @@ function ARMYGROUP:_InitGroup(Template)
-- DCS group. -- DCS group.
local dcsgroup=Group.getByName(self.groupname) local dcsgroup=Group.getByName(self.groupname)
local size0=dcsgroup:getInitialSize() local size0=dcsgroup:getInitialSize()
local u=dcsgroup:getUnits()
-- Quick check. -- Quick check.
if #units~=size0 then if #units~=size0 then
self:T(self.lid..string.format("ERROR: Got #units=%d but group consists of %d units!", #units, size0)) self:T(self.lid..string.format("ERROR: Got #units=%d but group consists of %d units! u=%d", #units, size0, #u))
end end
-- Add elemets. -- Add elemets.
@ -2121,6 +2179,7 @@ function ARMYGROUP:_InitGroup(Template)
-- Init done. -- Init done.
self.groupinitialized=true self.groupinitialized=true
end
return self return self
end end

View File

@ -1063,9 +1063,10 @@ function FLIGHTCONTROL:onafterStatusUpdate()
-- Check if runway was repaired. -- Check if runway was repaired.
if self:IsRunwayOperational()==false then if self:IsRunwayOperational()==false then
local Trepair=self:GetRunwayRepairtime() local Trepair=self:GetRunwayRepairtime()
self:I(self.lid..string.format("Runway still destroyed! Will be repaired in %d sec", Trepair))
if Trepair==0 then if Trepair==0 then
self:RunwayRepaired() self:RunwayRepaired()
else
self:I(self.lid..string.format("Runway still destroyed! Will be repaired in %d sec", Trepair))
end end
end end
@ -1835,7 +1836,7 @@ function FLIGHTCONTROL:_GetNextFightParking()
local text="Parking flights:" local text="Parking flights:"
for i,_flight in pairs(Qparking) do for i,_flight in pairs(Qparking) do
local flight=_flight --Ops.FlightGroup#FLIGHTGROUP local flight=_flight --Ops.FlightGroup#FLIGHTGROUP
text=text..string.format("\n[%d] %s [%s], state=%s [%s]: Tparking=%.1f sec", i, flight.groupname, flight.actype, flight:GetState(), self:GetFlightStatus(flight), flight:GetParkingTime()) text=text..string.format("\n[%d] %s [%s], state=%s [%s]: Tparking=%.1f sec", i, flight.groupname, tostring(flight.actype), flight:GetState(), self:GetFlightStatus(flight), flight:GetParkingTime())
end end
self:I(self.lid..text) self:I(self.lid..text)
end end
@ -2131,7 +2132,7 @@ function FLIGHTCONTROL:_InitParkingSpots()
local isalive=unit:IsAlive() local isalive=unit:IsAlive()
--env.info(string.format("FF parking spot %d is occupied by unit %s alive=%s", spot.TerminalID, unitname, tostring(isalive))) self:T2(self.lid..string.format("FF parking spot %d is occupied by unit %s alive=%s", spot.TerminalID, unitname, tostring(isalive)))
if isalive then if isalive then

View File

@ -59,6 +59,7 @@
-- @field #boolean prohibitAB Disallow (true) or allow (false) AI to use the afterburner. -- @field #boolean prohibitAB Disallow (true) or allow (false) AI to use the afterburner.
-- @field #boolean jettisonEmptyTanks Allow (true) or disallow (false) AI to jettison empty fuel tanks. -- @field #boolean jettisonEmptyTanks Allow (true) or disallow (false) AI to jettison empty fuel tanks.
-- @field #boolean jettisonWeapons Allow (true) or disallow (false) AI to jettison weapons if in danger. -- @field #boolean jettisonWeapons Allow (true) or disallow (false) AI to jettison weapons if in danger.
-- @field #number holdtime Time [s] flight is holding before going on final. Set to nil for indefinitely.
-- --
-- @extends Ops.OpsGroup#OPSGROUP -- @extends Ops.OpsGroup#OPSGROUP
@ -273,6 +274,7 @@ function FLIGHTGROUP:New(group)
-- Holding flag. -- Holding flag.
self.flaghold=USERFLAG:New(string.format("%s_FlagHold", self.groupname)) self.flaghold=USERFLAG:New(string.format("%s_FlagHold", self.groupname))
self.flaghold:Set(0) self.flaghold:Set(0)
self.holdtime=2*60
-- Add FSM transitions. -- Add FSM transitions.
-- From State --> Event --> To State -- From State --> Event --> To State
@ -786,6 +788,7 @@ function FLIGHTGROUP:SetReadyForTakeoff(ReadyTO, Delay)
if Delay and Delay>0 then if Delay and Delay>0 then
self:ScheduleOnce(Delay, FLIGHTGROUP.SetReadyForTakeoff, self, ReadyTO, 0) self:ScheduleOnce(Delay, FLIGHTGROUP.SetReadyForTakeoff, self, ReadyTO, 0)
else else
self:T(self.lid.."Set Ready for Takeoff switch for flightcontrol")
self.isReadyTO=ReadyTO self.isReadyTO=ReadyTO
end end
return self return self
@ -1257,6 +1260,9 @@ function FLIGHTGROUP:Status()
-- Check damage. -- Check damage.
self:_CheckDamage() self:_CheckDamage()
-- Check if stuck while taxiing.
self:_CheckStuck()
-- Get current mission (if any). -- Get current mission (if any).
local mission=self:GetMissionCurrent() local mission=self:GetMissionCurrent()
@ -1624,6 +1630,9 @@ function FLIGHTGROUP:Status()
if not mission then if not mission then
self.Twaiting=nil self.Twaiting=nil
self.dTwait=nil self.dTwait=nil
-- Check if group is done.
-- TODO: Not sure why I introduced this here.
self:_CheckGroupDone() self:_CheckGroupDone()
end end
@ -2097,7 +2106,7 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
-- Debug info. -- Debug info.
if self.verbose>=1 then if self.verbose>=1 then
local text=string.format("Initialized Flight Group %s:\n", self.groupname) local text=string.format("Initialized Flight Group %s:\n", self.groupname)
text=text..string.format("Unit type = %s\n", self.actype) text=text..string.format("Unit type = %s\n", tostring(self.actype))
text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedMax)) text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedMax))
text=text..string.format("Range max = %.1f km\n", self.rangemax/1000) text=text..string.format("Range max = %.1f km\n", self.rangemax/1000)
text=text..string.format("Ceiling = %.1f feet\n", UTILS.MetersToFeet(self.ceiling)) text=text..string.format("Ceiling = %.1f feet\n", UTILS.MetersToFeet(self.ceiling))
@ -2137,6 +2146,10 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
if self.isAI then if self.isAI then
-- TODO: Could be that element is spawned UNCONTROLLED.
-- In that case, the commands are not yet used.
-- This should be shifted to something like after ACTIVATED
-- Set ROE. -- Set ROE.
self:SwitchROE(self.option.ROE) self:SwitchROE(self.option.ROE)
@ -2737,6 +2750,7 @@ function FLIGHTGROUP:onafterOutOfMissilesAA(From, Event, To)
if self.outofAAMrtb then if self.outofAAMrtb then
-- Back to destination or home. -- Back to destination or home.
local airbase=self.destbase or self.homebase local airbase=self.destbase or self.homebase
self:T(self.lid.."Calling RTB in onafterOutOfMissilesAA")
self:__RTB(-5, airbase) self:__RTB(-5, airbase)
end end
end end
@ -2751,6 +2765,7 @@ function FLIGHTGROUP:onafterOutOfMissilesAG(From, Event, To)
if self.outofAGMrtb then if self.outofAGMrtb then
-- Back to destination or home. -- Back to destination or home.
local airbase=self.destbase or self.homebase local airbase=self.destbase or self.homebase
self:T(self.lid.."Calling RTB in onafterOutOfMissilesAG")
self:__RTB(-5, airbase) self:__RTB(-5, airbase)
end end
end end
@ -2840,8 +2855,8 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime)
-- Number of remaining tasks/missions? -- Number of remaining tasks/missions?
if nTasks==0 and nMissions==0 and nTransports==0 then if nTasks==0 and nMissions==0 and nTransports==0 then
local destbase=self.destbase or self.homebase local destbase=self.destbase or self.homebase --Wrapper.Airbase#AIRBASE
local destzone=self.destzone or self.homezone local destzone=self.destzone or self.homezone --Wrapper.Airbase#AIRBASE
-- Send flight to destination. -- Send flight to destination.
if waittime then if waittime then
@ -2852,9 +2867,12 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime)
self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports AND parking at destination airbase ==> Arrived!") self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports AND parking at destination airbase ==> Arrived!")
self:Arrived() self:Arrived()
else else
-- Only send RTB if current base is not yet the destination
if self.currbase==nil or self.currbase.AirbaseName~=destbase.AirbaseName then
self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports ==> RTB!") self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports ==> RTB!")
self:__RTB(-0.1, destbase) self:__RTB(-0.1, destbase)
end end
end
elseif destzone then elseif destzone then
self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports ==> RTZ!") self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports ==> RTZ!")
self:__RTZ(-0.1, destzone) self:__RTZ(-0.1, destzone)
@ -2981,6 +2999,7 @@ function FLIGHTGROUP:onbeforeRTB(From, Event, To, airbase, SpeedTo, SpeedHold)
end end
if Tsuspend and not allowed then if Tsuspend and not allowed then
self:T(self.lid.."Calling RTB in onbeforeRTB")
self:__RTB(Tsuspend, airbase, SpeedTo, SpeedHold) self:__RTB(Tsuspend, airbase, SpeedTo, SpeedHold)
end end
@ -3198,7 +3217,7 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
self.flaghold:Set(0) self.flaghold:Set(0)
-- Set holding time. -- Set holding time.
local holdtime=2*60 local holdtime=self.holdtime
if fc or self.airboss then if fc or self.airboss then
holdtime=nil holdtime=nil
end end
@ -3361,7 +3380,7 @@ function FLIGHTGROUP:onafterWait(From, Event, To, Duration, Altitude, Speed)
-- Set time stamp. -- Set time stamp.
self.Twaiting=timer.getAbsTime() self.Twaiting=timer.getAbsTime()
-- Max waiting -- Max waiting time in seconds.
self.dTwait=Duration self.dTwait=Duration
end end
@ -3661,6 +3680,7 @@ function FLIGHTGROUP:onafterFuelLow(From, Event, To)
-- Send back to airbase. -- Send back to airbase.
if airbase and self.fuellowrtb then if airbase and self.fuellowrtb then
self:T(self.lid.."Calling RTB in onafterFuelLow")
self:RTB(airbase) self:RTB(airbase)
--TODO: RTZ --TODO: RTZ
end end
@ -3685,6 +3705,7 @@ function FLIGHTGROUP:onafterFuelCritical(From, Event, To)
local airbase=self.destbase or self.homebase local airbase=self.destbase or self.homebase
if airbase and self.fuelcriticalrtb and not self:IsGoing4Fuel() then if airbase and self.fuelcriticalrtb and not self:IsGoing4Fuel() then
self:T(self.lid.."Calling RTB in onafterFuelCritical")
self:RTB(airbase) self:RTB(airbase)
--TODO: RTZ --TODO: RTZ
end end
@ -4832,6 +4853,87 @@ function FLIGHTGROUP:_GetTerminal(_attribute, _category)
return _terminal return _terminal
end end
--- Check if group got stuck. This overwrites the OPSGROUP function.
-- Here we only check if stuck whilst taxiing.
-- @param #FLIGHTGROUP self
-- @param #boolean Despawn If `true`, despawn group if stuck.
-- @return #number Time in seconds the group got stuck or nil if not stuck.
function FLIGHTGROUP:_CheckStuck(Despawn)
-- Cases we are not stuck.
if not self:IsTaxiing() then
return nil
end
-- Current time.
local Tnow=timer.getTime()
-- Expected speed in m/s.
local ExpectedSpeed=5
-- Current speed in m/s.
local speed=self:GetVelocity()
-- Check speed.
if speed<0.1 then
if ExpectedSpeed>0 and not self.stuckTimestamp then
self:T2(self.lid..string.format("WARNING: Group came to an unexpected standstill. Speed=%.1f<%.1f m/s expected", speed, ExpectedSpeed))
self.stuckTimestamp=Tnow
self.stuckVec3=self:GetVec3()
end
else
-- Moving (again).
self.stuckTimestamp=nil
end
local holdtime=nil
-- Somehow we are not moving...
if self.stuckTimestamp then
-- Time we are holding.
holdtime=Tnow-self.stuckTimestamp
-- Trigger stuck event.
self:Stuck(holdtime)
if holdtime>=5*60 and holdtime<15*60 then
-- Debug warning.
self:T(self.lid..string.format("WARNING: Group came to an unexpected standstill. Speed=%.1f<%.1f m/s expected for %d sec", speed, ExpectedSpeed, holdtime))
elseif holdtime>=15*60 then
-- Debug warning.
self:T(self.lid..string.format("WARNING: Group came to an unexpected standstill. Speed=%.1f<%.1f m/s expected for %d sec", speed, ExpectedSpeed, holdtime))
-- Look for a current mission and cancel it as we do not seem to be able to perform it.
local mission=self:GetMissionCurrent()
if mission then
self:T(self.lid..string.format("WARNING: Cancelling mission %s [%s] due to being stuck", mission:GetName(), mission:GetType()))
self:MissionCancel(mission)
end
if self.stuckDespawn then
if self.legion then
self:T(self.lid..string.format("Asset is returned to its legion after being stuck!"))
self:ReturnToLegion()
else
self:T(self.lid..string.format("Despawning group after being stuck!"))
self:Despawn()
end
end
end
end
return holdtime
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- OPTION FUNCTIONS -- OPTION FUNCTIONS
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -118,6 +118,10 @@
-- --
-- @field #OPSGROUP.Spot spot Laser and IR spot. -- @field #OPSGROUP.Spot spot Laser and IR spot.
-- --
-- @field DCS#Vec3 stuckVec3 Position where the group got stuck.
-- @field #number stuckTimestamp Time stamp [sec], when the group got stuck.
-- @field #boolean stuckDespawn If `true`, group gets despawned after beeing stuck for a certain time.
--
-- @field #OPSGROUP.Ammo ammo Initial ammount of ammo. -- @field #OPSGROUP.Ammo ammo Initial ammount of ammo.
-- @field #OPSGROUP.WeaponData weaponData Weapon data table with key=BitType. -- @field #OPSGROUP.WeaponData weaponData Weapon data table with key=BitType.
-- --
@ -680,6 +684,7 @@ function OPSGROUP:New(group)
self:AddTransition("*", "GotoWaypoint", "*") -- Group switches to a specific waypoint. self:AddTransition("*", "GotoWaypoint", "*") -- Group switches to a specific waypoint.
self:AddTransition("*", "Wait", "*") -- Group will wait for further orders. self:AddTransition("*", "Wait", "*") -- Group will wait for further orders.
self:AddTransition("*", "Stuck", "*") -- Group got stuck.
self:AddTransition("*", "DetectedUnit", "*") -- Unit was detected (again) in this detection cycle. self:AddTransition("*", "DetectedUnit", "*") -- Unit was detected (again) in this detection cycle.
self:AddTransition("*", "DetectedUnitNew", "*") -- Add a newly detected unit to the detected units set. self:AddTransition("*", "DetectedUnitNew", "*") -- Add a newly detected unit to the detected units set.
@ -1774,6 +1779,8 @@ function OPSGROUP:GetDCSUnit(UnitNumber)
if DCSGroup then if DCSGroup then
local unit=DCSGroup:getUnit(UnitNumber or 1) local unit=DCSGroup:getUnit(UnitNumber or 1)
return unit return unit
else
self:E(self.lid..string.format("ERROR: DCS group does not exist! Cannot get unit"))
end end
return nil return nil
@ -1887,7 +1894,7 @@ end
--- Get current velocity of the group. --- Get current velocity of the group.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param #string UnitName (Optional) Get heading of a specific unit of the group. Default is from the first existing unit in the group. -- @param #string UnitName (Optional) Get velocity of a specific unit of the group. Default is from the first existing unit in the group.
-- @return #number Velocity in m/s. -- @return #number Velocity in m/s.
function OPSGROUP:GetVelocity(UnitName) function OPSGROUP:GetVelocity(UnitName)
@ -2204,6 +2211,8 @@ function OPSGROUP:Destroy(Delay)
self:ScheduleOnce(Delay, OPSGROUP.Destroy, self, 0) self:ScheduleOnce(Delay, OPSGROUP.Destroy, self, 0)
else else
self:T(self.lid.."Destroying group!")
-- Get all units. -- Get all units.
local units=self:GetDCSUnits() local units=self:GetDCSUnits()
@ -3533,6 +3542,8 @@ function OPSGROUP:OnEventBirth(EventData)
-- Debug info. -- Debug info.
self:T(self.lid..string.format("EVENT: Element %s born ==> spawned", unitname)) self:T(self.lid..string.format("EVENT: Element %s born ==> spawned", unitname))
self:T2(self.lid..string.format("DCS unit=%s isExist=%s", tostring(EventData.IniDCSUnit:getName()), tostring(EventData.IniDCSUnit:isExist()) ))
-- Set element to spawned state. -- Set element to spawned state.
self:ElementSpawned(element) self:ElementSpawned(element)
@ -6673,6 +6684,7 @@ function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
local wpnext=self:GetWaypointNext() local wpnext=self:GetWaypointNext()
if wpnext then if wpnext then
self.speedWp=wpnext.speed self.speedWp=wpnext.speed
self:T(self.lid..string.format("Expected/waypoint speed=%.1f m/s", self.speedWp))
end end
end end
@ -11388,6 +11400,7 @@ function OPSGROUP:_InitWaypoints(WpIndexMin, WpIndexMax)
-- Expected speed to the first waypoint. -- Expected speed to the first waypoint.
if i<=2 then if i<=2 then
self.speedWp=wp.speed self.speedWp=wp.speed
self:T(self.lid..string.format("Expected/waypoint speed=%.1f m/s", self.speedWp))
end end
-- Speed in knots. -- Speed in knots.
@ -12020,7 +12033,7 @@ function OPSGROUP:GetEPLRS()
return self.option.EPLRS or self.optionDefault.EPLRS return self.option.EPLRS or self.optionDefault.EPLRS
end end
--- Set the default EPLRS for the group. --- Set the default emission state for the group.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param #boolean OnOffSwitch If `true`, EPLRS is on by default. If `false` default EPLRS setting is off. If `nil`, default is on if group has EPLRS and off if it does not have a datalink. -- @param #boolean OnOffSwitch If `true`, EPLRS is on by default. If `false` default EPLRS setting is off. If `nil`, default is on if group has EPLRS and off if it does not have a datalink.
-- @return #OPSGROUP self -- @return #OPSGROUP self
@ -12029,7 +12042,7 @@ function OPSGROUP:SetDefaultEmission(OnOffSwitch)
if OnOffSwitch==nil then if OnOffSwitch==nil then
self.optionDefault.Emission=true self.optionDefault.Emission=true
else else
self.optionDefault.EPLRS=OnOffSwitch self.optionDefault.Emission=OnOffSwitch
end end
return self return self

View File

@ -1496,7 +1496,7 @@ function AIRBASE:GetFreeParkingSpotsTable(termtype, allowTOAC)
-- Put coordinates of free spots into table. -- Put coordinates of free spots into table.
local freespots={} local freespots={}
for _,_spot in pairs(parkingfree) do for _,_spot in pairs(parkingfree) do
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) and _spot.Term_Index>0 then if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) then -- and _spot.Term_Index>0 then --Not sure why I had this in. But caused problems now for a Gas platform where a valid spot was not included!
if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then
local spot=self:_GetParkingSpotByID(_spot.Term_Index) local spot=self:_GetParkingSpotByID(_spot.Term_Index)

View File

@ -359,12 +359,15 @@ end
-- @param #GROUP self -- @param #GROUP self
-- @return DCS#Group The DCS Group. -- @return DCS#Group The DCS Group.
function GROUP:GetDCSObject() function GROUP:GetDCSObject()
-- Get DCS group.
local DCSGroup = Group.getByName( self.GroupName ) local DCSGroup = Group.getByName( self.GroupName )
if DCSGroup then if DCSGroup then
return DCSGroup return DCSGroup
end end
self:E(string.format("ERROR: Could not get DCS group object of group %s because DCS object could not be found!", tostring(self.GroupName)))
return nil return nil
end end