mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
bbae343b0e
1
.github/workflows/build-docs.yml
vendored
1
.github/workflows/build-docs.yml
vendored
@ -57,6 +57,7 @@ jobs:
|
||||
|
||||
- name: Update apt-get (needed for act docker image)
|
||||
run: |
|
||||
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
|
||||
sudo apt-get -qq update
|
||||
|
||||
- name: Install tree
|
||||
|
||||
@ -1157,6 +1157,15 @@ function BASE:_Serialize(Arguments)
|
||||
return text
|
||||
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.
|
||||
-- @param #BASE self
|
||||
-- @param Arguments A #table or any field.
|
||||
|
||||
@ -395,29 +395,36 @@ end
|
||||
--- Sends a MESSAGE to all players.
|
||||
-- @param #MESSAGE self
|
||||
-- @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
|
||||
--
|
||||
-- -- Send a message created to all players.
|
||||
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 ):ToAll()
|
||||
-- or
|
||||
-- MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 ):ToAll()
|
||||
-- or
|
||||
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 )
|
||||
-- MessageAll:ToAll()
|
||||
-- -- Send a message created to all players.
|
||||
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 ):ToAll()
|
||||
-- or
|
||||
-- MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 ):ToAll()
|
||||
-- or
|
||||
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 )
|
||||
-- MessageAll:ToAll()
|
||||
--
|
||||
function MESSAGE:ToAll( Settings )
|
||||
function MESSAGE:ToAll( Settings, Delay )
|
||||
self:F()
|
||||
|
||||
if self.MessageType then
|
||||
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
|
||||
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
||||
self.MessageCategory = "" -- self.MessageType .. ": "
|
||||
end
|
||||
if Delay and Delay>0 then
|
||||
self:ScheduleOnce(Delay, MESSAGE.ToAll, self, Settings, 0)
|
||||
else
|
||||
|
||||
if self.MessageType then
|
||||
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
|
||||
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
||||
self.MessageCategory = "" -- self.MessageType .. ": "
|
||||
end
|
||||
|
||||
if self.MessageDuration ~= 0 then
|
||||
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration )
|
||||
trigger.action.outText( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
|
||||
end
|
||||
|
||||
if self.MessageDuration ~= 0 then
|
||||
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration )
|
||||
trigger.action.outText( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
|
||||
end
|
||||
|
||||
return self
|
||||
|
||||
@ -292,9 +292,10 @@ SPAWN = {
|
||||
|
||||
--- Enumerator for spawns at airbases
|
||||
-- @type SPAWN.Takeoff
|
||||
-- @extends Wrapper.Group#GROUP.Takeoff
|
||||
|
||||
-- @field #SPAWN.Takeoff Takeoff
|
||||
-- @field #number Air Take off happens in air.
|
||||
-- @field #number Runway Spawn on runway. Does not work in MP!
|
||||
-- @field #number Hot Spawn at parking with engines on.
|
||||
-- @field #number Cold Spawn at parking with engines off.
|
||||
SPAWN.Takeoff = {
|
||||
Air = 1,
|
||||
Runway = 2,
|
||||
@ -3275,7 +3276,7 @@ end
|
||||
--- 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.
|
||||
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 Index = tonumber( IndexString )
|
||||
@ -3287,7 +3288,7 @@ end
|
||||
|
||||
--- Return the last maximum index that can be used.
|
||||
function SPAWN:_GetLastIndex()
|
||||
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
|
||||
self:F3( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
|
||||
|
||||
return self.SpawnMaxGroups
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -976,7 +976,10 @@ function ARMYGROUP:onafterSpawned(From, Event, To)
|
||||
-- Update route.
|
||||
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:__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
|
||||
self:T(self.lid.."No waypoints on spawn ==> Full Stop!")
|
||||
self:FullStop()
|
||||
@ -1287,6 +1290,7 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, N, Speed, Formation)
|
||||
|
||||
-- Current set speed in m/s.
|
||||
self.speedWp=wp.speed
|
||||
self:T(self.lid..string.format("Expected/waypoint speed=%.1f m/s", self.speedWp))
|
||||
|
||||
-- Debug output.
|
||||
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
|
||||
|
||||
-- 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.
|
||||
self:__UpdateRoute(-0.01, nil, nil, Speed, Formation)
|
||||
@ -2045,8 +2049,11 @@ end
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #table Template Template used to init the group. Default is `self.template`.
|
||||
-- @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.
|
||||
if self.groupinitialized then
|
||||
self:T(self.lid.."WARNING: Group was already initialized! Will NOT do it again!")
|
||||
@ -2096,32 +2103,84 @@ function ARMYGROUP:_InitGroup(Template)
|
||||
-- Set default formation to "on road".
|
||||
self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad
|
||||
|
||||
-- Default TACAN off.
|
||||
self:SetDefaultTACAN(nil, nil, nil, nil, true)
|
||||
self.tacan=UTILS.DeepCopy(self.tacanDefault)
|
||||
-- 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
|
||||
|
||||
-- Units of the group.
|
||||
local units=self.group:GetUnits()
|
||||
self:I(self.lid.."FF Initializing Group")
|
||||
|
||||
-- DCS group.
|
||||
local dcsgroup=Group.getByName(self.groupname)
|
||||
local size0=dcsgroup:getInitialSize()
|
||||
-- Get template of group.
|
||||
local template=Template or self:_GetTemplate()
|
||||
|
||||
-- Quick check.
|
||||
if #units~=size0 then
|
||||
self:T(self.lid..string.format("ERROR: Got #units=%d but group consists of %d units!", #units, size0))
|
||||
-- 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".
|
||||
self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad
|
||||
|
||||
-- Default TACAN off.
|
||||
self:SetDefaultTACAN(nil, nil, nil, nil, true)
|
||||
self.tacan=UTILS.DeepCopy(self.tacanDefault)
|
||||
|
||||
-- Units of the group.
|
||||
local units=self.group:GetUnits()
|
||||
|
||||
-- DCS group.
|
||||
local dcsgroup=Group.getByName(self.groupname)
|
||||
local size0=dcsgroup:getInitialSize()
|
||||
local u=dcsgroup:getUnits()
|
||||
|
||||
-- Quick check.
|
||||
if #units~=size0 then
|
||||
self:T(self.lid..string.format("ERROR: Got #units=%d but group consists of %d units! u=%d", #units, size0, #u))
|
||||
end
|
||||
|
||||
-- Add elemets.
|
||||
for _,unit in pairs(units) do
|
||||
local unitname=unit:GetName()
|
||||
self:_AddElementByName(unitname)
|
||||
end
|
||||
|
||||
|
||||
-- Init done.
|
||||
self.groupinitialized=true
|
||||
end
|
||||
|
||||
-- Add elemets.
|
||||
for _,unit in pairs(units) do
|
||||
local unitname=unit:GetName()
|
||||
self:_AddElementByName(unitname)
|
||||
end
|
||||
|
||||
|
||||
-- Init done.
|
||||
self.groupinitialized=true
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
@ -1063,9 +1063,10 @@ function FLIGHTCONTROL:onafterStatusUpdate()
|
||||
-- Check if runway was repaired.
|
||||
if self:IsRunwayOperational()==false then
|
||||
local Trepair=self:GetRunwayRepairtime()
|
||||
self:I(self.lid..string.format("Runway still destroyed! Will be repaired in %d sec", Trepair))
|
||||
if Trepair==0 then
|
||||
self:RunwayRepaired()
|
||||
else
|
||||
self:I(self.lid..string.format("Runway still destroyed! Will be repaired in %d sec", Trepair))
|
||||
end
|
||||
end
|
||||
|
||||
@ -1835,7 +1836,7 @@ function FLIGHTCONTROL:_GetNextFightParking()
|
||||
local text="Parking flights:"
|
||||
for i,_flight in pairs(Qparking) do
|
||||
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
|
||||
self:I(self.lid..text)
|
||||
end
|
||||
@ -2131,7 +2132,7 @@ function FLIGHTCONTROL:_InitParkingSpots()
|
||||
|
||||
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
|
||||
|
||||
|
||||
@ -59,6 +59,7 @@
|
||||
-- @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 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
|
||||
|
||||
@ -273,6 +274,7 @@ function FLIGHTGROUP:New(group)
|
||||
-- Holding flag.
|
||||
self.flaghold=USERFLAG:New(string.format("%s_FlagHold", self.groupname))
|
||||
self.flaghold:Set(0)
|
||||
self.holdtime=2*60
|
||||
|
||||
-- Add FSM transitions.
|
||||
-- From State --> Event --> To State
|
||||
@ -786,6 +788,7 @@ function FLIGHTGROUP:SetReadyForTakeoff(ReadyTO, Delay)
|
||||
if Delay and Delay>0 then
|
||||
self:ScheduleOnce(Delay, FLIGHTGROUP.SetReadyForTakeoff, self, ReadyTO, 0)
|
||||
else
|
||||
self:T(self.lid.."Set Ready for Takeoff switch for flightcontrol")
|
||||
self.isReadyTO=ReadyTO
|
||||
end
|
||||
return self
|
||||
@ -1254,9 +1257,12 @@ function FLIGHTGROUP:Status()
|
||||
-- Check ammo status.
|
||||
self:_CheckAmmoStatus()
|
||||
|
||||
-- Check damage.
|
||||
-- Check damage.
|
||||
self:_CheckDamage()
|
||||
|
||||
-- Check if stuck while taxiing.
|
||||
self:_CheckStuck()
|
||||
|
||||
-- Get current mission (if any).
|
||||
local mission=self:GetMissionCurrent()
|
||||
|
||||
@ -1624,6 +1630,9 @@ function FLIGHTGROUP:Status()
|
||||
if not mission then
|
||||
self.Twaiting=nil
|
||||
self.dTwait=nil
|
||||
|
||||
-- Check if group is done.
|
||||
-- TODO: Not sure why I introduced this here.
|
||||
self:_CheckGroupDone()
|
||||
end
|
||||
|
||||
@ -2097,7 +2106,7 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
|
||||
-- Debug info.
|
||||
if self.verbose>=1 then
|
||||
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("Range max = %.1f km\n", self.rangemax/1000)
|
||||
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
|
||||
|
||||
-- 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.
|
||||
self:SwitchROE(self.option.ROE)
|
||||
|
||||
@ -2737,6 +2750,7 @@ function FLIGHTGROUP:onafterOutOfMissilesAA(From, Event, To)
|
||||
if self.outofAAMrtb then
|
||||
-- Back to destination or home.
|
||||
local airbase=self.destbase or self.homebase
|
||||
self:T(self.lid.."Calling RTB in onafterOutOfMissilesAA")
|
||||
self:__RTB(-5, airbase)
|
||||
end
|
||||
end
|
||||
@ -2751,6 +2765,7 @@ function FLIGHTGROUP:onafterOutOfMissilesAG(From, Event, To)
|
||||
if self.outofAGMrtb then
|
||||
-- Back to destination or home.
|
||||
local airbase=self.destbase or self.homebase
|
||||
self:T(self.lid.."Calling RTB in onafterOutOfMissilesAG")
|
||||
self:__RTB(-5, airbase)
|
||||
end
|
||||
end
|
||||
@ -2840,8 +2855,8 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime)
|
||||
-- Number of remaining tasks/missions?
|
||||
if nTasks==0 and nMissions==0 and nTransports==0 then
|
||||
|
||||
local destbase=self.destbase or self.homebase
|
||||
local destzone=self.destzone or self.homezone
|
||||
local destbase=self.destbase or self.homebase --Wrapper.Airbase#AIRBASE
|
||||
local destzone=self.destzone or self.homezone --Wrapper.Airbase#AIRBASE
|
||||
|
||||
-- Send flight to destination.
|
||||
if waittime then
|
||||
@ -2852,8 +2867,11 @@ 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:Arrived()
|
||||
else
|
||||
self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports ==> RTB!")
|
||||
self:__RTB(-0.1, destbase)
|
||||
-- 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:__RTB(-0.1, destbase)
|
||||
end
|
||||
end
|
||||
elseif destzone then
|
||||
self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports ==> RTZ!")
|
||||
@ -2981,6 +2999,7 @@ function FLIGHTGROUP:onbeforeRTB(From, Event, To, airbase, SpeedTo, SpeedHold)
|
||||
end
|
||||
|
||||
if Tsuspend and not allowed then
|
||||
self:T(self.lid.."Calling RTB in onbeforeRTB")
|
||||
self:__RTB(Tsuspend, airbase, SpeedTo, SpeedHold)
|
||||
end
|
||||
|
||||
@ -3198,7 +3217,7 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
|
||||
self.flaghold:Set(0)
|
||||
|
||||
-- Set holding time.
|
||||
local holdtime=2*60
|
||||
local holdtime=self.holdtime
|
||||
if fc or self.airboss then
|
||||
holdtime=nil
|
||||
end
|
||||
@ -3361,7 +3380,7 @@ function FLIGHTGROUP:onafterWait(From, Event, To, Duration, Altitude, Speed)
|
||||
-- Set time stamp.
|
||||
self.Twaiting=timer.getAbsTime()
|
||||
|
||||
-- Max waiting
|
||||
-- Max waiting time in seconds.
|
||||
self.dTwait=Duration
|
||||
|
||||
end
|
||||
@ -3661,6 +3680,7 @@ function FLIGHTGROUP:onafterFuelLow(From, Event, To)
|
||||
|
||||
-- Send back to airbase.
|
||||
if airbase and self.fuellowrtb then
|
||||
self:T(self.lid.."Calling RTB in onafterFuelLow")
|
||||
self:RTB(airbase)
|
||||
--TODO: RTZ
|
||||
end
|
||||
@ -3685,6 +3705,7 @@ function FLIGHTGROUP:onafterFuelCritical(From, Event, To)
|
||||
local airbase=self.destbase or self.homebase
|
||||
|
||||
if airbase and self.fuelcriticalrtb and not self:IsGoing4Fuel() then
|
||||
self:T(self.lid.."Calling RTB in onafterFuelCritical")
|
||||
self:RTB(airbase)
|
||||
--TODO: RTZ
|
||||
end
|
||||
@ -4832,6 +4853,87 @@ function FLIGHTGROUP:_GetTerminal(_attribute, _category)
|
||||
return _terminal
|
||||
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
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@ -118,6 +118,10 @@
|
||||
--
|
||||
-- @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.WeaponData weaponData Weapon data table with key=BitType.
|
||||
--
|
||||
@ -676,10 +680,11 @@ function OPSGROUP:New(group)
|
||||
self:AddTransition("*", "UpdateRoute", "*") -- Update route of group.
|
||||
|
||||
self:AddTransition("*", "PassingWaypoint", "*") -- Group passed a waypoint.
|
||||
self:AddTransition("*", "PassedFinalWaypoint", "*") -- Group passed the waypoint.
|
||||
self:AddTransition("*", "PassedFinalWaypoint", "*") -- Group passed the waypoint.
|
||||
self:AddTransition("*", "GotoWaypoint", "*") -- Group switches to a specific waypoint.
|
||||
|
||||
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("*", "DetectedUnitNew", "*") -- Add a newly detected unit to the detected units set.
|
||||
@ -1774,6 +1779,8 @@ function OPSGROUP:GetDCSUnit(UnitNumber)
|
||||
if DCSGroup then
|
||||
local unit=DCSGroup:getUnit(UnitNumber or 1)
|
||||
return unit
|
||||
else
|
||||
self:E(self.lid..string.format("ERROR: DCS group does not exist! Cannot get unit"))
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -1887,7 +1894,7 @@ end
|
||||
|
||||
--- Get current velocity of the group.
|
||||
-- @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.
|
||||
function OPSGROUP:GetVelocity(UnitName)
|
||||
|
||||
@ -2204,6 +2211,8 @@ function OPSGROUP:Destroy(Delay)
|
||||
self:ScheduleOnce(Delay, OPSGROUP.Destroy, self, 0)
|
||||
else
|
||||
|
||||
self:T(self.lid.."Destroying group!")
|
||||
|
||||
-- Get all units.
|
||||
local units=self:GetDCSUnits()
|
||||
|
||||
@ -3533,6 +3542,8 @@ function OPSGROUP:OnEventBirth(EventData)
|
||||
-- Debug info.
|
||||
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.
|
||||
self:ElementSpawned(element)
|
||||
|
||||
@ -6673,6 +6684,7 @@ function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
|
||||
local wpnext=self:GetWaypointNext()
|
||||
if wpnext then
|
||||
self.speedWp=wpnext.speed
|
||||
self:T(self.lid..string.format("Expected/waypoint speed=%.1f m/s", self.speedWp))
|
||||
end
|
||||
|
||||
end
|
||||
@ -11388,6 +11400,7 @@ function OPSGROUP:_InitWaypoints(WpIndexMin, WpIndexMax)
|
||||
-- Expected speed to the first waypoint.
|
||||
if i<=2 then
|
||||
self.speedWp=wp.speed
|
||||
self:T(self.lid..string.format("Expected/waypoint speed=%.1f m/s", self.speedWp))
|
||||
end
|
||||
|
||||
-- Speed in knots.
|
||||
@ -12020,7 +12033,7 @@ function OPSGROUP:GetEPLRS()
|
||||
return self.option.EPLRS or self.optionDefault.EPLRS
|
||||
end
|
||||
|
||||
--- Set the default EPLRS for the group.
|
||||
--- Set the default emission state for the group.
|
||||
-- @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.
|
||||
-- @return #OPSGROUP self
|
||||
@ -12029,7 +12042,7 @@ function OPSGROUP:SetDefaultEmission(OnOffSwitch)
|
||||
if OnOffSwitch==nil then
|
||||
self.optionDefault.Emission=true
|
||||
else
|
||||
self.optionDefault.EPLRS=OnOffSwitch
|
||||
self.optionDefault.Emission=OnOffSwitch
|
||||
end
|
||||
|
||||
return self
|
||||
|
||||
@ -1496,7 +1496,7 @@ function AIRBASE:GetFreeParkingSpotsTable(termtype, allowTOAC)
|
||||
-- Put coordinates of free spots into table.
|
||||
local freespots={}
|
||||
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
|
||||
|
||||
local spot=self:_GetParkingSpotByID(_spot.Term_Index)
|
||||
|
||||
@ -359,12 +359,15 @@ end
|
||||
-- @param #GROUP self
|
||||
-- @return DCS#Group The DCS Group.
|
||||
function GROUP:GetDCSObject()
|
||||
|
||||
-- Get DCS group.
|
||||
local DCSGroup = Group.getByName( self.GroupName )
|
||||
|
||||
if DCSGroup then
|
||||
return DCSGroup
|
||||
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
|
||||
end
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user