AIRBOSS v1.0.8
- Fixed bug that status reset after wave off causes a unitcorn grade.
- Optimized radio scheduler calls ==> leads to less mem consumtion according to collectgarbage("count").

RESCUEHELO v1.0.9
- Adjusted default follow time interval to 1.0 sec.
- Added SetFollowTimeInterval() function.
- Respawn after returned delayed by 5 sec.

GROUP
- Added nil check in RespawnAtCurrentAirbase() function.
This commit is contained in:
Frank 2019-08-18 22:21:41 +02:00
parent 97e1a65b52
commit ec85b42a38
3 changed files with 250 additions and 141 deletions

View File

@ -48,12 +48,16 @@
-- --
-- Heatblur's mighty F-14B Tomcat has been added (March 13th 2019) as well. -- Heatblur's mighty F-14B Tomcat has been added (March 13th 2019) as well.
-- --
--
-- ## Discussion -- ## Discussion
-- --
-- If you have questions or suggestions, please visit the [MOOSE Discord](https://discord.gg/AeYAkHP) #ops-airboss channel. -- If you have questions or suggestions, please visit the [MOOSE Discord](https://discord.gg/AeYAkHP) #ops-airboss channel.
-- There you also find an example mission and the necessary voice over sound files. Check out the **pinned messages**. -- There you also find an example mission and the necessary voice over sound files. Check out the **pinned messages**.
-- --
-- ## Example Missions
--
-- Example missions can be found [here](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/OPS%20-%20Airboss).
-- They contain the latest development Moose.lua file.
--
-- ## IMPORTANT -- ## IMPORTANT
-- --
-- Some important restrictions (of DCS) you should be aware of: -- Some important restrictions (of DCS) you should be aware of:
@ -1671,6 +1675,7 @@ AIRBOSS.Difficulty={
-- @field #boolean showhints If true, show step hints. -- @field #boolean showhints If true, show step hints.
-- @field #table trapsheet Groove data table recorded every 0.5 seconds. -- @field #table trapsheet Groove data table recorded every 0.5 seconds.
-- @field #boolean trapon If true, save trap sheets. -- @field #boolean trapon If true, save trap sheets.
-- @field #string debriefschedulerID Debrief scheduler ID.
-- @extends #AIRBOSS.FlightGroup -- @extends #AIRBOSS.FlightGroup
--- Main group level radio menu: F10 Other/Airboss. --- Main group level radio menu: F10 Other/Airboss.
@ -1683,7 +1688,7 @@ AIRBOSS.MenuF10Root=nil
--- Airboss class version. --- Airboss class version.
-- @field #string version -- @field #string version
AIRBOSS.version="1.0.7" AIRBOSS.version="1.0.8"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -1944,7 +1949,7 @@ function AIRBOSS:New(carriername, alias)
self.Debug=true self.Debug=true
BASE:TraceOnOff(true) BASE:TraceOnOff(true)
BASE:TraceClass(self.ClassName) BASE:TraceClass(self.ClassName)
BASE:TraceLevel(1) BASE:TraceLevel(3)
--self.dTstatus=0.1 --self.dTstatus=0.1
end end
@ -2265,6 +2270,29 @@ function AIRBOSS:New(carriername, alias)
-- @param #AIRBOSS.LSOgrade grade LSO grade. -- @param #AIRBOSS.LSOgrade grade LSO grade.
--- Triggers the FSM event "LSOGrade". Called when the LSO grades a player
-- @function [parent=#AIRBOSS] LSOGrade
-- @param #AIRBOSS self
-- @param #AIRBOSS.PlayerData playerData Player Data.
-- @param #AIRBOSS.LSOgrade grade LSO grade.
--- Triggers the FSM event "LSOGrade". Delayed called when the LSO grades a player.
-- @function [parent=#AIRBOSS] __LSOGrade
-- @param #AIRBOSS self
-- @param #number delay Delay in seconds.
-- @param #AIRBOSS.PlayerData playerData Player Data.
-- @param #AIRBOSS.LSOgrade grade LSO grade.
--- On after "LSOGrade" user function. Called when the carrier passes a waypoint of its route.
-- @function [parent=#AIRBOSS] OnAfterLSOGrade
-- @param #AIRBOSS self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #AIRBOSS.PlayerData playerData Player Data.
-- @param #AIRBOSS.LSOgrade grade LSO grade.
--- Triggers the FSM event "Stop" that stops the airboss. Event handlers are stopped. --- Triggers the FSM event "Stop" that stops the airboss. Event handlers are stopped.
-- @function [parent=#AIRBOSS] Stop -- @function [parent=#AIRBOSS] Stop
-- @param #AIRBOSS self -- @param #AIRBOSS self
@ -2494,7 +2522,8 @@ end
function AIRBOSS:CloseCurrentRecoveryWindow(delay) function AIRBOSS:CloseCurrentRecoveryWindow(delay)
if delay and delay>0 then if delay and delay>0 then
SCHEDULER:New(nil, self.CloseCurrentRecoveryWindow, {self}, delay) --SCHEDULER:New(nil, self.CloseCurrentRecoveryWindow, {self}, delay)
self:ScheduleOnce(delay, self.CloseCurrentRecoveryWindow, self)
else else
if self:IsRecovering() and self.recoverywindow and self.recoverywindow.OPEN then if self:IsRecovering() and self.recoverywindow and self.recoverywindow.OPEN then
self:RecoveryStop() self:RecoveryStop()
@ -2544,7 +2573,8 @@ function AIRBOSS:DeleteRecoveryWindow(window, delay)
if delay and delay>0 then if delay and delay>0 then
-- Delayed call. -- Delayed call.
SCHEDULER:New(nil, self.DeleteRecoveryWindow, {self, window}, delay) --SCHEDULER:New(nil, self.DeleteRecoveryWindow, {self, window}, delay)
self:ScheduleOnce(delay, self.DeleteRecoveryWindow, self, window)
else else
for i,_recovery in pairs(self.recoverytimes) do for i,_recovery in pairs(self.recoverytimes) do
@ -2964,7 +2994,8 @@ function AIRBOSS:SoundCheckLSO(delay)
if delay and delay>0 then if delay and delay>0 then
-- Delayed call. -- Delayed call.
SCHEDULER:New(nil, AIRBOSS.SoundCheckLSO, {self}, delay) --SCHEDULER:New(nil, AIRBOSS.SoundCheckLSO, {self}, delay)
self:ScheduleOnce(delay, AIRBOSS.SoundCheckLSO, self)
else else
@ -2999,7 +3030,8 @@ function AIRBOSS:SoundCheckMarshal(delay)
if delay and delay>0 then if delay and delay>0 then
-- Delayed call. -- Delayed call.
SCHEDULER:New(nil, AIRBOSS.SoundCheckMarshal, {self}, delay) --SCHEDULER:New(nil, AIRBOSS.SoundCheckMarshal, {self}, delay)
self:ScheduleOnce(delay, AIRBOSS.SoundCheckMarshal, self)
else else
@ -3249,8 +3281,12 @@ function AIRBOSS:onafterStart(From, Event, To)
self:_ActivateBeacons() self:_ActivateBeacons()
-- Schedule radio queue checks. -- Schedule radio queue checks.
self.RQLid=self.radiotimer:Schedule(self, self._CheckRadioQueue, {self.RQLSO, "LSO"}, 1, 0.01) --self.RQLid=self.radiotimer:Schedule(nil, AIRBOSS._CheckRadioQueue, {self, self.RQLSO, "LSO"}, 1, 0.1)
self.RQMid=self.radiotimer:Schedule(self, self._CheckRadioQueue, {self.RQMarshal, "MARSHAL"}, 1, 0.01) --self.RQMid=self.radiotimer:Schedule(nil, AIRBOSS._CheckRadioQueue, {self, self.RQMarshal, "MARSHAL"}, 1, 0.1)
--self:I("FF: starting timer.scheduleFunction")
--timer.scheduleFunction(AIRBOSS._CheckRadioQueueT, {airboss=self, radioqueue=self.RQLSO, name="LSO"}, timer.getTime()+1)
--timer.scheduleFunction(AIRBOSS._CheckRadioQueueT, {airboss=self, radioqueue=self.RQMarshal, name="MARSHAL"}, timer.getTime()+1)
-- Initial carrier position and orientation. -- Initial carrier position and orientation.
self.Cposition=self:GetCoordinate() self.Cposition=self:GetCoordinate()
@ -4023,6 +4059,8 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function AIRBOSS:onafterStop(From, Event, To) function AIRBOSS:onafterStop(From, Event, To)
self:I(self.lid..string.format("Stopping airboss script."))
-- Unhandle events. -- Unhandle events.
self:UnHandleEvent(EVENTS.Birth) self:UnHandleEvent(EVENTS.Birth)
self:UnHandleEvent(EVENTS.Land) self:UnHandleEvent(EVENTS.Land)
@ -4032,6 +4070,8 @@ function AIRBOSS:onafterStop(From, Event, To)
self:UnHandleEvent(EVENTS.Ejection) self:UnHandleEvent(EVENTS.Ejection)
self:UnHandleEvent(EVENTS.PlayerLeaveUnit) self:UnHandleEvent(EVENTS.PlayerLeaveUnit)
self:UnHandleEvent(EVENTS.MissionEnd) self:UnHandleEvent(EVENTS.MissionEnd)
self.CallScheduler:Clear()
end end
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -5848,7 +5888,8 @@ function AIRBOSS:_SetPlayerStep(playerData, step, delay)
if delay and delay>0 then if delay and delay>0 then
-- Delayed call. -- Delayed call.
SCHEDULER:New(nil, self._SetPlayerStep, {self, playerData, step}, delay) --SCHEDULER:New(nil, self._SetPlayerStep, {self, playerData, step}, delay)
self:ScheduleOnce(delay, self._SetPlayerStep, self, playerData, step)
else else
-- Check if player still exists after possible delay. -- Check if player still exists after possible delay.
@ -7316,6 +7357,7 @@ function AIRBOSS:_InitPlayer(playerData, step)
playerData.TIG0=nil playerData.TIG0=nil
playerData.wire=nil playerData.wire=nil
playerData.flag=-100 playerData.flag=-100
playerData.debriefschedulerID=nil
-- Set us up on final if group name contains "Groove". But only for the first pass. -- Set us up on final if group name contains "Groove". But only for the first pass.
if playerData.group:GetName():match("Groove") and playerData.passes==0 then if playerData.group:GetName():match("Groove") and playerData.passes==0 then
@ -7797,15 +7839,6 @@ function AIRBOSS:_RemoveFlight(flight, completely)
else else
-- Check if flight should be completely removed, e.g. after the player died or simply left the slot.
if completely then
-- Update flight section. Remove flight from section or find new section leader if flight was the lead.
self:_UpdateFlightSection(flight)
-- Remove completely.
self:_RemoveFlightFromQueue(self.flights, flight)
-- Remove all grades until a final grade is reached. -- Remove all grades until a final grade is reached.
local grades=self.playerscores[flight.name] local grades=self.playerscores[flight.name]
if grades and #grades>0 then if grades and #grades>0 then
@ -7814,6 +7847,14 @@ function AIRBOSS:_RemoveFlight(flight, completely)
end end
end end
-- Check if flight should be completely removed, e.g. after the player died or simply left the slot.
if completely then
-- Update flight section. Remove flight from section or find new section leader if flight was the lead.
self:_UpdateFlightSection(flight)
-- Remove completely.
self:_RemoveFlightFromQueue(self.flights, flight)
-- Remove player from players table. -- Remove player from players table.
local playerdata=self.players[flight.name] local playerdata=self.players[flight.name]
@ -8005,7 +8046,8 @@ function AIRBOSS:_CheckPlayerStatus()
elseif playerData.step==AIRBOSS.PatternStep.DEBRIEF then elseif playerData.step==AIRBOSS.PatternStep.DEBRIEF then
-- Debriefing in 5 seconds. -- Debriefing in 5 seconds.
SCHEDULER:New(nil, self._Debrief, {self, playerData}, 5) --SCHEDULER:New(nil, self._Debrief, {self, playerData}, 5)
playerData.debriefschedulerID=self:ScheduleOnce(5, self._Debrief, self, playerData)
-- Undefined status. -- Undefined status.
playerData.step=AIRBOSS.PatternStep.UNDEFINED playerData.step=AIRBOSS.PatternStep.UNDEFINED
@ -8186,7 +8228,8 @@ function AIRBOSS:OnEventBirth(EventData)
self:_AddF10Commands(_unitName) self:_AddF10Commands(_unitName)
-- Delaying the new player for a second, because AI units of the flight would not be registered correctly. -- Delaying the new player for a second, because AI units of the flight would not be registered correctly.
SCHEDULER:New(nil, self._NewPlayer, {self, _unitName}, 1) --SCHEDULER:New(nil, self._NewPlayer, {self, _unitName}, 1)
self:ScheduleOnce(1, self._NewPlayer, self, _unitName)
end end
end end
@ -8339,7 +8382,8 @@ function AIRBOSS:OnEventLand(EventData)
self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.UNDEFINED) self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.UNDEFINED)
-- Call trapped function in 1 second to make sure we did not bolter. -- Call trapped function in 1 second to make sure we did not bolter.
SCHEDULER:New(nil, self._Trapped, {self, playerData}, 1) --SCHEDULER:New(nil, self._Trapped, {self, playerData}, 1)
self:ScheduleOnce(1, self._Trapped, self, playerData)
end end
@ -10233,7 +10277,8 @@ function AIRBOSS:_Trapped(playerData)
end end
-- Call function again and check if converged or back in air. -- Call function again and check if converged or back in air.
SCHEDULER:New(nil, self._Trapped, {self, playerData}, 0.1) --SCHEDULER:New(nil, self._Trapped, {self, playerData}, 0.1)
self:ScheduleOnce(0.1, self._Trapped, self, playerData)
return return
end end
@ -12673,6 +12718,9 @@ end
function AIRBOSS:_Debrief(playerData) function AIRBOSS:_Debrief(playerData)
self:F(self.lid..string.format("Debriefing of player %s.", playerData.name)) self:F(self.lid..string.format("Debriefing of player %s.", playerData.name))
-- Delete scheduler ID.
playerData.debriefschedulerID=nil
-- Switch attitude monitor off if on. -- Switch attitude monitor off if on.
playerData.attitudemonitor=false playerData.attitudemonitor=false
@ -14299,6 +14347,14 @@ end
-- RADIO MESSAGE Functions -- RADIO MESSAGE Functions
----------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Function called by DCS timer. Unused.
-- @param #table param Parameters.
-- @param #number time Time.
function AIRBOSS._CheckRadioQueueT(param, time)
AIRBOSS._CheckRadioQueue(param.airboss, param.radioqueue, param.name)
return time+0.05
end
--- Radio queue item. --- Radio queue item.
-- @type AIRBOSS.Radioitem -- @type AIRBOSS.Radioitem
-- @field #number Tplay Abs time when transmission should be played. -- @field #number Tplay Abs time when transmission should be played.
@ -14315,37 +14371,50 @@ end
-- @param #string name Name of the queue. -- @param #string name Name of the queue.
function AIRBOSS:_CheckRadioQueue(radioqueue, name) function AIRBOSS:_CheckRadioQueue(radioqueue, name)
--env.info(string.format("FF %s #radioqueue %d", name, #radioqueue))
-- Check if queue is empty. -- Check if queue is empty.
if #radioqueue==0 then if #radioqueue==0 then
if name=="LSO" then
self:T(self.lid..string.format("Stopping LSO radio queue."))
self.radiotimer:Stop(self.RQLid)
self.RQLid=nil
elseif name=="MARSHAL" then
self:T(self.lid..string.format("Stopping Marshal radio queue."))
self.radiotimer:Stop(self.RQMid)
self.RQMid=nil
end
return return
end end
-- Get current abs time. -- Get current abs time.
local time=timer.getAbsTime() local _time=timer.getAbsTime()
local playing=false local playing=false
local next=nil --#AIRBOSS.Radioitem local next=nil --#AIRBOSS.Radioitem
local remove=nil local _remove=nil
for i,_transmission in ipairs(radioqueue) do for i,_transmission in ipairs(radioqueue) do
local transmission=_transmission --#AIRBOSS.Radioitem local transmission=_transmission --#AIRBOSS.Radioitem
-- Check if transmission time has passed. -- Check if transmission time has passed.
if time>=transmission.Tplay then if _time>=transmission.Tplay then
-- Check if transmission is currently playing. -- Check if transmission is currently playing.
if transmission.isplaying then if transmission.isplaying then
-- Check if transmission is finished. -- Check if transmission is finished.
if time>=transmission.Tstarted+transmission.call.duration then if _time>=transmission.Tstarted+transmission.call.duration then
-- Transmission over. -- Transmission over.
transmission.isplaying=false transmission.isplaying=false
remove=i _remove=i
if transmission.radio.alias=="LSO" then if transmission.radio.alias=="LSO" then
self.TQLSO=time self.TQLSO=_time
elseif transmission.radio.alias=="MARSHAL" then elseif transmission.radio.alias=="MARSHAL" then
self.TQMarshal=time self.TQMarshal=_time
end end
else -- still playing else -- still playing
@ -14375,7 +14444,7 @@ function AIRBOSS:_CheckRadioQueue(radioqueue, name)
else else
if time-Tlast>=transmission.interval then if _time-Tlast>=transmission.interval then
next=transmission next=transmission
else else
@ -14400,14 +14469,15 @@ function AIRBOSS:_CheckRadioQueue(radioqueue, name)
if next~=nil and not playing then if next~=nil and not playing then
self:Broadcast(next.radio, next.call, next.loud) self:Broadcast(next.radio, next.call, next.loud)
next.isplaying=true next.isplaying=true
next.Tstarted=time next.Tstarted=_time
end end
-- Remove completed calls from queue. -- Remove completed calls from queue.
if remove then if _remove then
table.remove(radioqueue, remove) table.remove(radioqueue, _remove)
end end
return
end end
--- Add Radio transmission to radio queue. --- Add Radio transmission to radio queue.
@ -14456,12 +14526,23 @@ function AIRBOSS:RadioTransmission(radio, call, loud, delay, interval, click, pi
caller="LSOCall" caller="LSOCall"
-- Schedule radio queue checks.
if not self.RQLid then
self:T(self.lid..string.format("Starting LSO radio queue."))
self.RQLid=self.radiotimer:Schedule(nil, AIRBOSS._CheckRadioQueue, {self, self.RQLSO, "LSO"}, 0.02, 0.05)
end
elseif radio.alias=="MARSHAL" then elseif radio.alias=="MARSHAL" then
table.insert(self.RQMarshal, transmission) table.insert(self.RQMarshal, transmission)
caller="MarshalCall" caller="MarshalCall"
if not self.RQMid then
self:T(self.lid..string.format("Starting Marhal radio queue."))
self.RQMid=self.radiotimer:Schedule(nil, AIRBOSS._CheckRadioQueue, {self, self.RQMarshal, "MARSHAL"}, 0.02, 0.05)
end
end end
-- Append radio click sound at the end of the transmission. -- Append radio click sound at the end of the transmission.
@ -14743,7 +14824,8 @@ function AIRBOSS:MessageToPlayer(playerData, message, sender, receiver, duration
if delay and delay>0 then if delay and delay>0 then
-- Delayed call. -- Delayed call.
SCHEDULER:New(nil, self.MessageToPlayer, {self, playerData, message, sender, receiver, duration, clear}, delay) --SCHEDULER:New(nil, self.MessageToPlayer, {self, playerData, message, sender, receiver, duration, clear}, delay)
self:ScheduleOnce(delay, self.MessageToPlayer, self, playerData, message, sender, receiver, duration, clear)
else else
-- Wait until previous sound finished. -- Wait until previous sound finished.
@ -15798,6 +15880,11 @@ function AIRBOSS:_ResetPlayerStatus(_unitName)
-- Section members are removed from the Spinning queue. If flight is member, he is removed from the section. -- Section members are removed from the Spinning queue. If flight is member, he is removed from the section.
self:_RemoveFlight(playerData) self:_RemoveFlight(playerData)
-- Stop pending debrief scheduler.
if playerData.debriefschedulerID and self.Scheduler then
self.Scheduler:Stop(playerData.debriefschedulerID)
end
-- Initialize player data. -- Initialize player data.
self:_InitPlayer(playerData) self:_InitPlayer(playerData)

View File

@ -57,6 +57,7 @@
-- @field #string alias Alias of the spawn group. -- @field #string alias Alias of the spawn group.
-- @field #number uid Unique ID of this helo. -- @field #number uid Unique ID of this helo.
-- @field #number modex Tail number of the helo. -- @field #number modex Tail number of the helo.
-- @field #number dtFollow Follow time update interval in seconds. Default 1.0 sec.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- Rescue Helo --- Rescue Helo
@ -227,6 +228,7 @@ RESCUEHELO = {
alias = nil, alias = nil,
uid = 0, uid = 0,
modex = nil, modex = nil,
dtFollow = nil,
} }
--- Unique ID (global). --- Unique ID (global).
@ -235,7 +237,7 @@ _RESCUEHELOID=0
--- Class version. --- Class version.
-- @field #string version -- @field #string version
RESCUEHELO.version="1.0.8" RESCUEHELO.version="1.0.9"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -303,6 +305,7 @@ function RESCUEHELO:New(carrierunit, helogroupname)
self:SetRescueZone() self:SetRescueZone()
self:SetRescueHoverSpeed() self:SetRescueHoverSpeed()
self:SetRescueDuration() self:SetRescueDuration()
self:SetFollowTimeInterval()
self:SetRescueStopBoatOff() self:SetRescueStopBoatOff()
-- Some more. -- Some more.
@ -644,6 +647,15 @@ function RESCUEHELO:SetModex(modex)
return self return self
end end
--- Set follow time update interval.
-- @param #RESCUEHELO self
-- @param #number dt Time interval in seconds. Default 1.0 sec.
-- @return #RESCUEHELO self
function RESCUEHELO:SetFollowTimeInterval(dt)
self.dtFollow=dt or 1.0
return self
end
--- Use an uncontrolled aircraft already present in the mission rather than spawning a new helo as initial rescue helo. --- Use an uncontrolled aircraft already present in the mission rather than spawning a new helo as initial rescue helo.
-- This can be useful when interfaced with, e.g., a warehouse. -- This can be useful when interfaced with, e.g., a warehouse.
-- The group name is the one specified in the @{#RESCUEHELO.New} function. -- The group name is the one specified in the @{#RESCUEHELO.New} function.
@ -895,7 +907,7 @@ function RESCUEHELO:onafterStart(From, Event, To)
-- Use an uncontrolled aircraft group. -- Use an uncontrolled aircraft group.
self.helo=GROUP:FindByName(self.helogroupname) self.helo=GROUP:FindByName(self.helogroupname)
if self.helo:IsAlive() then if self.helo and self.helo:IsAlive() then
-- Start uncontrolled group. -- Start uncontrolled group.
self.helo:StartUncontrolled() self.helo:StartUncontrolled()
@ -940,6 +952,9 @@ function RESCUEHELO:onafterStart(From, Event, To)
-- Formation parameters. -- Formation parameters.
self.formation:FormationCenterWing(-self.offsetX, 50, math.abs(self.altitude), 50, self.offsetZ, 50) self.formation:FormationCenterWing(-self.offsetX, 50, math.abs(self.altitude), 50, self.offsetZ, 50)
-- Set follow time interval.
self.formation:SetFollowTimeInterval(self.dtFollow)
-- Formation mode. -- Formation mode.
self.formation:SetFlightModeFormation(self.helo) self.formation:SetFlightModeFormation(self.helo)
@ -1005,7 +1020,7 @@ function RESCUEHELO:onafterStatus(From, Event, To)
else else
-- Send helo back to base. -- Send helo back to base.
self:RTB() self:RTB(self.airbase)
end end
@ -1196,7 +1211,9 @@ function RESCUEHELO:onafterReturned(From, Event, To, airbase)
self.helo:InitModex(self.modex) self.helo:InitModex(self.modex)
-- Respawn helo at current airbase. -- Respawn helo at current airbase.
self.helo:RespawnAtCurrentAirbase() if self.helo and self.helo:IsAlive() then
self:ScheduleOnce(5, self.helo.RespawnAtCurrentAirbase, self.helo)
end
-- Restart the formation. -- Restart the formation.
self:__Run(10) self:__Run(10)

View File

@ -1773,6 +1773,8 @@ end
function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) -- R2.4 function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) -- R2.4
self:F2( { SpawnTemplate, Takeoff, Uncontrolled} ) self:F2( { SpawnTemplate, Takeoff, Uncontrolled} )
if self and self:IsAlive() then
-- Get closest airbase. Should be the one we are currently on. -- Get closest airbase. Should be the one we are currently on.
local airbase=self:GetCoordinate():GetClosestAirbase() local airbase=self:GetCoordinate():GetClosestAirbase()
@ -1878,6 +1880,9 @@ function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) --
return self return self
end end
else
self:E("WARNING: GROUP is not alive!")
end
return nil return nil
end end