mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Updates
This commit is contained in:
@@ -205,7 +205,7 @@
|
||||
-- @field Core.Set#SET_GROUP excludesetAI AI groups in this set will be explicitly excluded from handling by the airboss and not forced into the Marshal pattern.
|
||||
-- @field #boolean menusingle If true, menu is optimized for a single carrier.
|
||||
-- @field #number collisiondist Distance up to which collision checks are done.
|
||||
-- @field #nubmer holdtimestamp Timestamp when the carrier first came to an unexpected hold.
|
||||
-- @field #number holdtimestamp Timestamp when the carrier first came to an unexpected hold.
|
||||
-- @field #number Tmessage Default duration in seconds messages are displayed to players.
|
||||
-- @field #string soundfolder Folder within the mission (miz) file where airboss sound files are located.
|
||||
-- @field #string soundfolderLSO Folder withing the mission (miz) file where LSO sound files are stored.
|
||||
@@ -1559,7 +1559,7 @@ AIRBOSS.Difficulty={
|
||||
-- @field #number Time Time in seconds.
|
||||
-- @field #number Rho Distance in meters.
|
||||
-- @field #number X Distance in meters.
|
||||
-- @field #nubmer Z Distance in meters.
|
||||
-- @field #number Z Distance in meters.
|
||||
-- @field #number AoA Angle of Attack.
|
||||
-- @field #number Alt Altitude in meters.
|
||||
-- @field #number GSE Glideslope error in degrees.
|
||||
@@ -1681,7 +1681,7 @@ AIRBOSS.MenuF10Root=nil
|
||||
|
||||
--- Airboss class version.
|
||||
-- @field #string version
|
||||
AIRBOSS.version="1.0.4"
|
||||
AIRBOSS.version="1.0.5"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@@ -2128,6 +2128,13 @@ function AIRBOSS:New(carriername, alias)
|
||||
-- @param #AIRBOSS self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- On after "RecoveryStop" user function. Called when recovery of aircraft is stopped.
|
||||
-- @function [parent=#AIRBOSS] OnAfterRecoveryStop
|
||||
-- @param #AIRBOSS self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
|
||||
|
||||
--- Triggers the FSM event "RecoveryPause" that pauses the recovery of aircraft.
|
||||
-- @function [parent=#AIRBOSS] RecoveryPause
|
||||
@@ -3063,6 +3070,15 @@ function AIRBOSS:SetRecoveryTanker(recoverytanker)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Define an AWACS associated with the carrier.
|
||||
-- @param #AIRBOSS self
|
||||
-- @param Ops.RecoveryTanker#RECOVERYTANKER awacs AWACS (recovery tanker) object.
|
||||
-- @return #AIRBOSS self
|
||||
function AIRBOSS:SetAWACS(awacs)
|
||||
self.awacs=awacs
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set default player skill. New players will be initialized with this skill.
|
||||
--
|
||||
-- * "Flight Student" = @{#AIRBOSS.Difficulty.Easy}
|
||||
@@ -5914,38 +5930,48 @@ function AIRBOSS:_ScanCarrierZone()
|
||||
-- Debug info.
|
||||
self:T3(self.lid..string.format("Known AI flight group %s closed in by %.1f NM", knownflight.groupname, UTILS.MetersToNM(closein)))
|
||||
|
||||
-- Send AI flight to marshal stack if group closes in more than 5 and has initial flag value.
|
||||
if closein>UTILS.NMToMeters(5) and knownflight.flag==-100 and iscarriersquad then
|
||||
-- Is this group the tanker?
|
||||
local istanker=self.tanker and self.tanker.tanker:GetName()==groupname
|
||||
|
||||
-- Check that we do not add a recovery tanker for marshaling.
|
||||
if self.tanker and self.tanker.tanker:GetName()==groupname then
|
||||
-- Is this group the AWACS?
|
||||
local isawacs=self.awacs and self.awacs.tanker:GetName()==groupname
|
||||
|
||||
-- Send tanker to marshal stack?
|
||||
local tanker2marshal = istanker and self.tanker:IsReturning() and self.tanker.airbase:GetName()==self.airbase:GetName() and knownflight.flag==-100
|
||||
|
||||
-- Send AWACS to marhsal stack?
|
||||
local awacs2marshal = isawacs and self.awacs:IsReturning() and self.awacs.airbase:GetName()==self.airbase:GetName() and knownflight.flag==-100
|
||||
|
||||
-- Put flight into Marshal.
|
||||
local putintomarshal=closein>UTILS.NMToMeters(5) and knownflight.flag==-100 and iscarriersquad and istanker==false and isawacs==false
|
||||
|
||||
-- Send AI flight to marshal stack if group closes in more than 5 and has initial flag value.
|
||||
if putintomarshal or tanker2marshal or awacs2marshal then
|
||||
|
||||
-- Get the next free stack for current recovery case.
|
||||
local stack=self:_GetFreeStack(knownflight.ai)
|
||||
|
||||
-- Repawn.
|
||||
local respawn=self.respawnAI --or tanker2marshal
|
||||
|
||||
-- Don't touch the recovery tanker!
|
||||
if stack then
|
||||
|
||||
-- Send AI to marshal stack. We respawn the group to clean possible departure and destination airbases.
|
||||
self:_MarshalAI(knownflight, stack, respawn)
|
||||
|
||||
else
|
||||
|
||||
-- Get the next free stack for current recovery case.
|
||||
local stack=self:_GetFreeStack(knownflight.ai)
|
||||
|
||||
if stack then
|
||||
|
||||
-- Send AI to marshal stack. We respawn the group to clean possible departure and destination airbases.
|
||||
self:_MarshalAI(knownflight, stack, self.respawnAI)
|
||||
|
||||
else
|
||||
|
||||
-- Send AI to orbit outside 10 NM zone and wait until the next Marshal stack is available.
|
||||
if not self:_InQueue(self.Qwaiting, knownflight.group) then
|
||||
self:_WaitAI(knownflight, self.respawnAI) -- Group is respawned to clear any attached airfields.
|
||||
end
|
||||
|
||||
-- Send AI to orbit outside 10 NM zone and wait until the next Marshal stack is available.
|
||||
if not self:_InQueue(self.Qwaiting, knownflight.group) then
|
||||
self:_WaitAI(knownflight, respawn) -- Group is respawned to clear any attached airfields.
|
||||
end
|
||||
|
||||
-- Break the loop to not have all flights at once! Spams the message screen.
|
||||
break
|
||||
|
||||
end -- Tanker
|
||||
end -- Closed in
|
||||
|
||||
end
|
||||
|
||||
-- Break the loop to not have all flights at once! Spams the message screen.
|
||||
break
|
||||
|
||||
end -- Closed in or tanker/AWACS
|
||||
end -- AI
|
||||
|
||||
else
|
||||
@@ -14329,7 +14355,7 @@ end
|
||||
-- @param #number delay Delay in seconds, before the message is broadcasted.
|
||||
-- @param #number interval Interval in seconds after the last sound has been played.
|
||||
-- @param #boolean click If true, play radio click at the end.
|
||||
-- @param #booelan pilotcall If true, it's a pilot call.
|
||||
-- @param #boolean pilotcall If true, it's a pilot call.
|
||||
function AIRBOSS:RadioTransmission(radio, call, loud, delay, interval, click, pilotcall)
|
||||
self:F2({radio=radio, call=call, loud=loud, delay=delay, interval=interval, click=click})
|
||||
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
-- @field #number callsignname Number for the callsign name.
|
||||
-- @field #number callsignnumber Number of the callsign name.
|
||||
-- @field #string modex Tail number of the tanker.
|
||||
-- @field #boolean eplrs If true, enable data link, e.g. if used as AWACS.
|
||||
-- @field #boolean recovery If true, tanker will recover using the AIRBOSS marshal pattern.
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
--- Recovery Tanker.
|
||||
@@ -295,15 +297,16 @@ RECOVERYTANKER = {
|
||||
callsignnumber = nil,
|
||||
modex = nil,
|
||||
eplrs = nil,
|
||||
recovery = nil,
|
||||
}
|
||||
|
||||
--- Unique ID (global).
|
||||
-- @field #number UID Unique ID (global).
|
||||
RECOVERYTANKER.UID=0
|
||||
_RECOVERYTANKERID=0
|
||||
|
||||
--- Class version.
|
||||
-- @field #string version
|
||||
RECOVERYTANKER.version="1.0.7"
|
||||
RECOVERYTANKER.version="1.0.8"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@@ -349,16 +352,16 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
|
||||
self.tankergroupname=tankergroupname
|
||||
|
||||
-- Increase unique ID.
|
||||
RECOVERYTANKER.UID=RECOVERYTANKER.UID+1
|
||||
_RECOVERYTANKERID=_RECOVERYTANKERID+1
|
||||
|
||||
-- Unique ID of this tanker.
|
||||
self.uid=RECOVERYTANKER.UID
|
||||
self.uid=_RECOVERYTANKERID
|
||||
|
||||
-- Save self in static object. Easier to retrieve later.
|
||||
self.carrier:SetState(self.carrier, string.format("RECOVERYTANKER_%d", self.uid) , self)
|
||||
|
||||
-- Set unique spawn alias.
|
||||
self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.tankergroupname, RECOVERYTANKER.UID)
|
||||
self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.tankergroupname, _RECOVERYTANKERID)
|
||||
|
||||
-- Log ID.
|
||||
self.lid=string.format("RECOVERYTANKER %s | ", self.alias)
|
||||
@@ -377,6 +380,7 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
|
||||
self:SetPatternUpdateHeading()
|
||||
self:SetPatternUpdateInterval()
|
||||
self:SetAWACS(false)
|
||||
self:SetRecoveryAirboss(false)
|
||||
|
||||
-- Debug trace.
|
||||
if false then
|
||||
@@ -399,6 +403,7 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
|
||||
self:AddTransition("*", "RefuelStop", "Running") -- Tanker starts to refuel.
|
||||
self:AddTransition("*", "Run", "Running") -- Tanker starts normal operation again.
|
||||
self:AddTransition("Running", "RTB", "Returning") -- Tanker is returning to base (for fuel).
|
||||
self:AddTransition("Returning", "Returned", "Returned") -- Tanker has returned to its airbase (i.e. landed).
|
||||
self:AddTransition("*", "Status", "*") -- Status update.
|
||||
self:AddTransition("Running", "PatternUpdate", "*") -- Update pattern wrt to carrier.
|
||||
self:AddTransition("*", "Stop", "Stopped") -- Stop the FSM.
|
||||
@@ -472,6 +477,26 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase where the tanker should return to.
|
||||
|
||||
|
||||
--- Triggers the FSM event "Returned" after the tanker has landed.
|
||||
-- @function [parent=#RECOVERYTANKER] Returned
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the tanker has landed.
|
||||
|
||||
--- Triggers the delayed FSM event "Returned" after the tanker has landed.
|
||||
-- @function [parent=#RECOVERYTANKER] __Returned
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param #number delay Delay in seconds.
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the tanker has landed.
|
||||
|
||||
--- On after "Returned" event user function. Called when a the the tanker has landed at an airbase.
|
||||
-- @function [parent=#RECOVERYTANKER] OnAfterReturned
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the tanker has landed.
|
||||
|
||||
|
||||
--- Triggers the FSM event "Status" that updates the tanker status.
|
||||
-- @function [parent=#RECOVERYTANKER] Status
|
||||
-- @param #RECOVERYTANKER self
|
||||
@@ -596,6 +621,19 @@ function RECOVERYTANKER:SetHomeBase(airbase)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Activate recovery by the AIRBOSS class. Tanker will get a Marshal stack and perform a CASE I, II or III recovery when RTB.
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param #boolean switch If true or nil, recovery is done by AIRBOSS.
|
||||
-- @return #RECOVERYTANKER self
|
||||
function RECOVERYTANKER:SetRecoveryAirboss(switch)
|
||||
if switch==true or switch==nil then
|
||||
self.recovery=true
|
||||
else
|
||||
self.recovery=false
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set that the group takes the roll of an AWACS instead of a refueling tanker.
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param #boolean switch If true or nil, set roll AWACS.
|
||||
@@ -830,6 +868,7 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
|
||||
|
||||
-- Handle events.
|
||||
self:HandleEvent(EVENTS.EngineShutdown)
|
||||
self:HandleEvent(EVENTS.Land)
|
||||
self:HandleEvent(EVENTS.Refueling, self._RefuelingStart) --Need explicit functions since OnEventRefueling and OnEventRefuelingStop did not hook!
|
||||
self:HandleEvent(EVENTS.RefuelingStop, self._RefuelingStop)
|
||||
self:HandleEvent(EVENTS.Crash, self._OnEventCrashOrDead)
|
||||
@@ -865,7 +904,7 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
|
||||
else
|
||||
|
||||
-- Check if an uncontrolled tanker group was requested.
|
||||
if self.useuncontrolled then
|
||||
if self.uncontrolledac then
|
||||
|
||||
-- Use an uncontrolled aircraft group.
|
||||
self.tanker=GROUP:FindByName(self.tankergroupname)
|
||||
@@ -884,14 +923,14 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
|
||||
else
|
||||
|
||||
-- Spawn tanker at airbase.
|
||||
self.tanker=Spawn:SpawnAtAirbase(self.airbase, self.takeoff)
|
||||
self.tanker=Spawn:SpawnAtAirbase(self.airbase, self.takeoff, nil, AIRBASE.TerminalType.OpenMedOrBig)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Initialize route. self.distStern<0!
|
||||
SCHEDULER:New(nil, self._InitRoute, {self, -self.distStern+UTILS.NMToMeters(3)}, 1)
|
||||
self:ScheduleOnce(1, self._InitRoute, self, -self.distStern+UTILS.NMToMeters(3))
|
||||
|
||||
-- Create tanker beacon.
|
||||
if self.TACANon then
|
||||
@@ -929,7 +968,7 @@ function RECOVERYTANKER:onafterStatus(From, Event, To)
|
||||
-- Get current time.
|
||||
local time=timer.getTime()
|
||||
|
||||
if self.tanker:IsAlive() then
|
||||
if self.tanker and self.tanker:IsAlive() then
|
||||
|
||||
---------------------
|
||||
-- TANKER is ALIVE --
|
||||
@@ -937,8 +976,14 @@ function RECOVERYTANKER:onafterStatus(From, Event, To)
|
||||
|
||||
-- Get fuel of tanker.
|
||||
local fuel=self.tanker:GetFuel()*100
|
||||
local text=string.format("Recovery tanker %s: state=%s fuel=%.1f", self.tanker:GetName(), self:GetState(), fuel)
|
||||
local life=self.tanker:GetUnit(1):GetLife()
|
||||
local life0=self.tanker:GetUnit(1):GetLife0()
|
||||
local lifeR=self.tanker:GetUnit(1):GetLifeRelative()
|
||||
|
||||
-- Report fuel and life.
|
||||
local text=string.format("Recovery tanker %s: state=%s fuel=%.1f, life=%.1f/%.1f=%d", self.tanker:GetName(), self:GetState(), fuel, life, life0, lifeR*100)
|
||||
self:T(self.lid..text)
|
||||
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||
|
||||
-- Check if tanker is running and not RTBing or refueling.
|
||||
if self:IsRunning() then
|
||||
@@ -947,7 +992,7 @@ function RECOVERYTANKER:onafterStatus(From, Event, To)
|
||||
if fuel<self.lowfuel then
|
||||
|
||||
-- Check if spawn in air is activated.
|
||||
if self.takeoff==SPAWN.Takeoff.Air or self.respawninair then
|
||||
if (self.takeoff==SPAWN.Takeoff.Air or self.respawninair) and not self.recovery then
|
||||
|
||||
-- Check that respawn should happen.
|
||||
if self.respawn then
|
||||
@@ -1028,6 +1073,8 @@ function RECOVERYTANKER:onafterStatus(From, Event, To)
|
||||
|
||||
if not self:IsStopped() then
|
||||
|
||||
self:E(self.lid.."Recovery tanker is NOT alive (and not stopped)!")
|
||||
|
||||
-- Stop FSM.
|
||||
self:Stop()
|
||||
|
||||
@@ -1133,7 +1180,14 @@ function RECOVERYTANKER:onafterRTB(From, Event, To, airbase)
|
||||
|
||||
-- Set landing waypoint.
|
||||
wp[1]=self.tanker:GetCoordinate():WaypointAirTurningPoint(nil, speed, {}, "Current Position")
|
||||
wp[2]=airbase:GetCoordinate():SetAltitude(500):WaypointAirLanding(speed, airbase, nil, "Land at airbase")
|
||||
|
||||
|
||||
if self.recovery then
|
||||
-- Fly a bit until the airboss takes over.
|
||||
wp[2]=self.tanker:GetCoordinate():Translate(UTILS.NMToMeters(10), self.tanker:GetHeading(), true):WaypointAirTurningPoint(nil, speed, {}, "WP")
|
||||
else
|
||||
wp[2]=airbase:GetCoordinate():SetAltitude(500):WaypointAirLanding(speed, airbase, nil, "Land at airbase")
|
||||
end
|
||||
|
||||
-- Initialize WP and route tanker.
|
||||
self.tanker:WayPointInitialize(wp)
|
||||
@@ -1142,6 +1196,25 @@ function RECOVERYTANKER:onafterRTB(From, Event, To, airbase)
|
||||
self.tanker:Route(wp, 1)
|
||||
end
|
||||
|
||||
|
||||
--- On after Returned event. The tanker has landed.
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The base at which the tanker landed.
|
||||
function RECOVERYTANKER:onafterReturned(From, Event, To, airbase)
|
||||
|
||||
if airbase then
|
||||
local airbasename=airbase:GetName()
|
||||
self:I(self.lid..string.format("Tanker returned to airbase %s", tostring(airbasename)))
|
||||
else
|
||||
self:E(self.lid..string.format("WARNING: Tanker landed but airbase (EventData.Place) is nil!"))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- On after Stop event. Unhandle events and stop status updates.
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param #string From From state.
|
||||
@@ -1150,14 +1223,18 @@ end
|
||||
function RECOVERYTANKER:onafterStop(From, Event, To)
|
||||
|
||||
-- Unhandle events.
|
||||
self:UnHandleEvent(EVENTS.Land)
|
||||
self:UnHandleEvent(EVENTS.EngineShutdown)
|
||||
self:UnHandleEvent(EVENTS.Refueling)
|
||||
self:UnHandleEvent(EVENTS.RefuelingStop)
|
||||
self:UnHandleEvent(EVENTS.Dead)
|
||||
self:UnHandleEvent(EVENTS.Crash)
|
||||
|
||||
-- Clear all pending FSM events.
|
||||
self.CallScheduler:Clear()
|
||||
|
||||
-- If tanker is alive, despawn it.
|
||||
if self.helo and self.helo:IsAlive() then
|
||||
if self.tanker and self.tanker:IsAlive() then
|
||||
self:I(self.lid.."Stopping FSM and despawning tanker.")
|
||||
self.tanker:Destroy()
|
||||
else
|
||||
@@ -1170,6 +1247,42 @@ end
|
||||
-- EVENT functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Event handler for landing of recovery tanker.
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param Core.Event#EVENTDATA EventData Event data.
|
||||
function RECOVERYTANKER:OnEventLand(EventData)
|
||||
|
||||
-- Group that shut down the engine.
|
||||
local group=EventData.IniGroup --Wrapper.Group#GROUP
|
||||
|
||||
-- Check if group is alive.
|
||||
if group and group:IsAlive() then
|
||||
|
||||
-- Group name. When spawning it will have #001 attached.
|
||||
local groupname=group:GetName()
|
||||
|
||||
-- Check that we have the right group and that it should be respawned.
|
||||
if groupname==self.tanker:GetName() then
|
||||
|
||||
local airbase=nil --Wrapper.Airbase#AIRBASE
|
||||
local airbasename="unknown"
|
||||
if EventData.Place then
|
||||
airbase=EventData.Plase
|
||||
airbasename=airbase:GetName()
|
||||
end
|
||||
|
||||
-- Debug info.
|
||||
local text=string.format("Recovery tanker group %s landed at airbase %s.", group:GetName(), airbasename)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
-- Trigger returned event.
|
||||
self:__Returned(1, airbase)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Event handler for engine shutdown of recovery tanker.
|
||||
-- Respawn tanker group once it landed because it was out of fuel.
|
||||
-- @param #RECOVERYTANKER self
|
||||
@@ -1180,7 +1293,7 @@ function RECOVERYTANKER:OnEventEngineShutdown(EventData)
|
||||
local group=EventData.IniGroup --Wrapper.Group#GROUP
|
||||
|
||||
-- Check if group is alive.
|
||||
if group:IsAlive() then
|
||||
if group and group:IsAlive() then
|
||||
|
||||
-- Group name. When spawning it will have #001 attached.
|
||||
local groupname=group:GetName()
|
||||
@@ -1219,8 +1332,7 @@ function RECOVERYTANKER:OnEventEngineShutdown(EventData)
|
||||
end
|
||||
|
||||
-- Initial route.
|
||||
SCHEDULER:New(nil, self._InitRoute, {self, -self.distStern+UTILS.NMToMeters(3)}, 2)
|
||||
|
||||
SCHEDULER:New(nil, self._InitRoute, {self, -self.distStern+UTILS.NMToMeters(3)}, 2)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1503,7 +1615,7 @@ function RECOVERYTANKER:_ActivateTACAN(delay)
|
||||
self.beacon:ActivateTACAN(self.TACANchannel, self.TACANmode, self.TACANmorse, true)
|
||||
|
||||
else
|
||||
self:E("ERROR: Recovery tanker is not alive!")
|
||||
self:E(self.lid.."ERROR: Recovery tanker is not alive!")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -231,11 +231,11 @@ RESCUEHELO = {
|
||||
|
||||
--- Unique ID (global).
|
||||
-- @field #number uid Unique ID (global).
|
||||
RESCUEHELO.UID=0
|
||||
_RESCUEHELOID=0
|
||||
|
||||
--- Class version.
|
||||
-- @field #string version
|
||||
RESCUEHELO.version="1.0.7"
|
||||
RESCUEHELO.version="1.0.8"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@@ -277,16 +277,16 @@ function RESCUEHELO:New(carrierunit, helogroupname)
|
||||
self.helogroupname=helogroupname
|
||||
|
||||
-- Increase ID.
|
||||
RESCUEHELO.UID=RESCUEHELO.UID+1
|
||||
_RESCUEHELOID=_RESCUEHELOID+1
|
||||
|
||||
-- Unique ID of this helo.
|
||||
self.uid=RESCUEHELO.UID
|
||||
self.uid=_RESCUEHELOID
|
||||
|
||||
-- Save self in static object. Easier to retrieve later.
|
||||
self.carrier:SetState(self.carrier, string.format("RESCUEHELO_%d", self.uid) , self)
|
||||
|
||||
-- Set unique spawn alias.
|
||||
self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.helogroupname, RESCUEHELO.UID)
|
||||
self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.helogroupname, _RESCUEHELOID)
|
||||
|
||||
-- Log ID.
|
||||
self.lid=string.format("RESCUEHELO %s | ", self.alias)
|
||||
@@ -386,6 +386,7 @@ function RESCUEHELO:New(carrierunit, helogroupname)
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase to return to. Default is the home base.
|
||||
|
||||
|
||||
--- Triggers the FSM event "Returned" after the helo has landed.
|
||||
-- @function [parent=#RESCUEHELO] Returned
|
||||
-- @param #RESCUEHELO self
|
||||
@@ -719,7 +720,7 @@ end
|
||||
function RESCUEHELO:OnEventLand(EventData)
|
||||
local group=EventData.IniGroup --Wrapper.Group#GROUP
|
||||
|
||||
if group:IsAlive() then
|
||||
if group and group:IsAlive() then
|
||||
|
||||
-- Group name that landed.
|
||||
local groupname=group:GetName()
|
||||
@@ -727,8 +728,15 @@ function RESCUEHELO:OnEventLand(EventData)
|
||||
-- Check that it was our helo that landed.
|
||||
if groupname==self.helo:GetName() then
|
||||
|
||||
local airbase=nil --Wrapper.Airbase#AIRBASE
|
||||
local airbasename="unknown"
|
||||
if EventData.Place then
|
||||
airbase=EventData.Place
|
||||
airbasename=airbase:GetName()
|
||||
end
|
||||
|
||||
-- Respawn the Helo.
|
||||
local text=string.format("Respawning rescue helo group %s at home base.", groupname)
|
||||
local text=string.format("Rescue helo group %s landed at airbase %s.", groupname, airbasename)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
@@ -749,7 +757,7 @@ function RESCUEHELO:OnEventLand(EventData)
|
||||
end
|
||||
|
||||
-- Trigger returned event. Respawn at current airbase.
|
||||
self:__Returned(3, EventData.Place)
|
||||
self:__Returned(3, airbase)
|
||||
|
||||
end
|
||||
end
|
||||
@@ -839,7 +847,6 @@ function RESCUEHELO:onafterStart(From, Event, To)
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Handle events.
|
||||
--self:HandleEvent(EVENTS.Birth)
|
||||
self:HandleEvent(EVENTS.Land)
|
||||
self:HandleEvent(EVENTS.Crash, self._OnEventCrashOrEject)
|
||||
self:HandleEvent(EVENTS.Ejection, self._OnEventCrashOrEject)
|
||||
@@ -899,7 +906,7 @@ function RESCUEHELO:onafterStart(From, Event, To)
|
||||
else
|
||||
|
||||
-- Spawn at airbase.
|
||||
self.helo=Spawn:SpawnAtAirbase(self.airbase, self.takeoff)
|
||||
self.helo=Spawn:SpawnAtAirbase(self.airbase, self.takeoff, nil, AIRBASE.TerminalType.HelicopterUsable)
|
||||
|
||||
-- Delay before formation is started.
|
||||
if self.takeoff==SPAWN.Takeoff.Runway then
|
||||
@@ -948,7 +955,7 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
||||
local time=timer.getTime()
|
||||
|
||||
-- Check if helo is running and not RTBing already or rescuing.
|
||||
if self.helo:IsAlive() then
|
||||
if self.helo and self.helo:IsAlive() then
|
||||
|
||||
-------------------
|
||||
-- HELO is ALIVE --
|
||||
@@ -959,9 +966,10 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
||||
local fuelrel=fuel/self.HeloFuel0
|
||||
local life=self.helo:GetUnit(1):GetLife()
|
||||
local life0=self.helo:GetUnit(1):GetLife0()
|
||||
local lifeR=self.helo:GetUnit(1):GetLifeRelative()
|
||||
|
||||
-- Report current fuel.
|
||||
local text=string.format("Rescue Helo %s: state=%s fuel=%.1f, rel.fuel=%.1f, life=%.1f/%.1f", self.helo:GetName(), self:GetState(), fuel, fuelrel, life, life0)
|
||||
local text=string.format("Rescue Helo %s: state=%s fuel=%.1f, rel.fuel=%.1f, life=%.1f/%.1f=%d", self.helo:GetName(), self:GetState(), fuel, fuelrel, life, life0, lifeR*100)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
@@ -982,7 +990,7 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
||||
-- Respawn helo in air.
|
||||
self.helo=self.helo:Respawn(nil, true)
|
||||
|
||||
-- XXX: ATTENTION: if helo automatically RTBs on low fuel, it goes a bit cazy. The formation is not stopped and he partially dives into the water.
|
||||
-- XXX: ATTENTION: if helo automatically RTBs on low fuel, it goes a bit crazy. The formation is not stopped and he partially dives into the water.
|
||||
-- Also trying to find a ship to land on he flies right through it.
|
||||
--self.helo:OptionRTBBingoFuel(false)
|
||||
|
||||
@@ -1016,6 +1024,8 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
||||
|
||||
if not self:IsStopped() then
|
||||
|
||||
self:E(self.lid.."Rescue helo is NOT alive (and not stopped)!")
|
||||
|
||||
-- Stop FSM.
|
||||
self:Stop()
|
||||
|
||||
@@ -1047,18 +1057,6 @@ function RESCUEHELO:onafterRun(From, Event, To)
|
||||
self.formation:Start()
|
||||
end
|
||||
|
||||
-- Restart route of carrier if it was stopped.
|
||||
if self.carrierstop then
|
||||
-- Debug info.
|
||||
local text="Carrier resuming route after rescue operation."
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
-- Resume route of carrier.
|
||||
self.carrier:RouteResume()
|
||||
self.carrierstop=false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -1143,15 +1141,6 @@ function RESCUEHELO:onafterRescue(From, Event, To, RescueCoord)
|
||||
-- Stop formation.
|
||||
self.formation:Stop()
|
||||
|
||||
-- Stop carrier.
|
||||
if self.rescuestopboat then
|
||||
local text="Stopping carrier for rescue operation."
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
self.carrier:RouteStop()
|
||||
self.carrierstop=true
|
||||
end
|
||||
end
|
||||
|
||||
--- On after RTB event. Send helo back to carrier.
|
||||
@@ -1170,21 +1159,6 @@ function RESCUEHELO:onafterRTB(From, Event, To, airbase)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
--[[
|
||||
-- Waypoint array.
|
||||
local wp={}
|
||||
|
||||
-- Set landing waypoint at home base.
|
||||
wp[1]=self.helo:GetCoordinate():WaypointAirTurningPoint(nil, 300, {}, "Current Position")
|
||||
wp[2]=self.airbase:GetCoordinate():SetAltitude(70):WaypointAirLanding(300, self.airbase, {}, "Landing at Home Base")
|
||||
|
||||
-- Initialize WP and route helo.
|
||||
self.helo:WayPointInitialize(wp)
|
||||
|
||||
-- Set task.
|
||||
self.helo:Route(wp, 1)
|
||||
]]
|
||||
|
||||
-- Stop formation.
|
||||
if From=="Running" then
|
||||
self.formation:Stop()
|
||||
@@ -1238,6 +1212,9 @@ function RESCUEHELO:onafterStop(From, Event, To)
|
||||
self:UnHandleEvent(EVENTS.Land)
|
||||
self:UnHandleEvent(EVENTS.Crash)
|
||||
self:UnHandleEvent(EVENTS.Ejection)
|
||||
|
||||
-- Clear all pending FSM events.
|
||||
self.CallScheduler:Clear()
|
||||
|
||||
-- If helo is alive, despawn it.
|
||||
if self.helo and self.helo:IsAlive() then
|
||||
@@ -1245,7 +1222,8 @@ function RESCUEHELO:onafterStop(From, Event, To)
|
||||
self.helo:Destroy()
|
||||
else
|
||||
self:I(self.lid.."Stopping FSM. Helo was not alive.")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -1260,13 +1238,13 @@ function RESCUEHELO:RouteRTB(RTBAirbase, Speed)
|
||||
|
||||
-- Curent (from) waypoint.
|
||||
local coord=self.helo:GetCoordinate()
|
||||
local PointFrom=coord:WaypointAirTurningPoint(nil, Speed)
|
||||
local PointFrom=coord:WaypointAirTurningPoint(nil, Speed, {}, "Current")
|
||||
|
||||
-- Airbase coordinate.
|
||||
local PointAirbase=RTBAirbase:GetCoordinate():SetAltitude(100):WaypointAirTurningPoint(nil ,Speed)
|
||||
--local PointAirbase=RTBAirbase:GetCoordinate():SetAltitude(100):WaypointAirTurningPoint(nil ,Speed)
|
||||
|
||||
-- Landing waypoint. More general than prev version since it should also work with FAPRS and ships.
|
||||
local PointLanding=RTBAirbase:GetCoordinate():SetAltitude(20):WaypointAirLanding(Speed, RTBAirbase)
|
||||
local PointLanding=RTBAirbase:GetCoordinate():SetAltitude(20):WaypointAirLanding(Speed, RTBAirbase, {}, "Landing")
|
||||
|
||||
-- Waypoint table.
|
||||
local Points={PointFrom, PointLanding}
|
||||
@@ -1283,6 +1261,9 @@ function RESCUEHELO:RouteRTB(RTBAirbase, Speed)
|
||||
-- Respawn the group.
|
||||
self.helo=self.helo:Respawn(Template, true)
|
||||
|
||||
-- Route the group or this will not work.
|
||||
self.helo:Route(Points, 1)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user