mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
RESCUEHELO v1.0.5
- Added Returned event. - Fixed automatic RTB on low fuel bug.
This commit is contained in:
parent
1cb248692b
commit
c4016cfa4d
@ -11158,9 +11158,6 @@ end
|
||||
-- @param #number delay Delay in seconds, before the message is displayed.
|
||||
function AIRBOSS:MessageToPattern(message, sender, receiver, duration, clear, delay)
|
||||
|
||||
-- Local delay.
|
||||
local _delay=delay or 0
|
||||
|
||||
-- Create new (fake) radio call to show the subtitile.
|
||||
local call=self:_NewRadioCall(AIRBOSS.LSOCall.NOISE, sender or "LSO", message, duration, receiver, sender)
|
||||
|
||||
@ -11180,9 +11177,6 @@ end
|
||||
-- @param #number delay Delay in seconds, before the message is displayed.
|
||||
function AIRBOSS:MessageToMarshal(message, sender, receiver, duration, clear, delay)
|
||||
|
||||
-- Local delay.
|
||||
local _delay=delay or 0
|
||||
|
||||
-- Create new (fake) radio call to show the subtitile.
|
||||
local call=self:_NewRadioCall(AIRBOSS.MarshalCall.NOISE, sender or "MARSHAL", message, duration, receiver, sender)
|
||||
|
||||
@ -12584,7 +12578,7 @@ function AIRBOSS:_DisplayPlayerStatus(_unitName)
|
||||
local fuel=playerData.unit:GetFuel()*100
|
||||
local fuelstate=self:_GetFuelState(playerData.unit)
|
||||
|
||||
---
|
||||
-- Number of units in group.
|
||||
local _,nunitsGround=self:_GetFlightUnits(playerData, true)
|
||||
local _,nunitsAirborne=self:_GetFlightUnits(playerData, false)
|
||||
|
||||
@ -12599,8 +12593,6 @@ function AIRBOSS:_DisplayPlayerStatus(_unitName)
|
||||
text=text..string.format("Skill Level: %s\n", playerData.difficulty)
|
||||
text=text..string.format("Tail # %s (%s)\n", playerData.onboard, self:_GetACNickname(playerData.actype))
|
||||
text=text..string.format("Fuel State: %.1f lbs/1000 (%.1f %%)\n", fuelstate/1000, fuel)
|
||||
--text=text..string.format("Aircraft: %s\n", self:_GetACNickname(playerData.actype))
|
||||
--text=text..string.format("Group: %s\n", playerData.group:GetName())
|
||||
text=text..string.format("# units: %d (%d airborne)\n", nunitsGround, nunitsAirborne)
|
||||
text=text..string.format("Section Lead: %s (%d/%d)", tostring(playerData.seclead), #playerData.section+1, self.NmaxSection+1)
|
||||
for _,_sec in pairs(playerData.section) do
|
||||
|
||||
@ -821,8 +821,10 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
|
||||
|
||||
-- Handle events.
|
||||
self:HandleEvent(EVENTS.EngineShutdown)
|
||||
self:HandleEvent(EVENTS.Refueling, self._RefuelingStart) --Need explcit functions sice OnEventRefueling and OnEventRefuelingStop did not hook.
|
||||
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)
|
||||
self:HandleEvent(EVENTS.Dead, self._OnEventCrashOrDead)
|
||||
|
||||
-- Spawn tanker. We need to introduce an alias in case this class is used twice. This would confuse the spawn routine.
|
||||
local Spawn=SPAWN:NewWithAlias(self.tankergroupname, self.alias)
|
||||
@ -1004,14 +1006,17 @@ function RECOVERYTANKER:onafterStatus(From, Event, To)
|
||||
-- TANKER is DEAD --
|
||||
--------------------
|
||||
|
||||
-- Stop FSM.
|
||||
self:Stop()
|
||||
if not self:IsStopped() then
|
||||
|
||||
-- Stop FSM.
|
||||
self:Stop()
|
||||
|
||||
-- Restart FSM after 5 seconds.
|
||||
if self.respawn then
|
||||
self:__Start(5)
|
||||
end
|
||||
|
||||
-- Restart FSM after 5 seconds.
|
||||
if self.respawn then
|
||||
self:__Start(5)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@ -1116,9 +1121,22 @@ end
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function RECOVERYTANKER:onafterStop(From, Event, To)
|
||||
|
||||
-- Unhandle events.
|
||||
self:UnHandleEvent(EVENTS.EngineShutdown)
|
||||
self:UnHandleEvent(EVENTS.Refueling)
|
||||
self:UnHandleEvent(EVENTS.RefuelingStop)
|
||||
self:UnHandleEvent(EVENTS.Dead)
|
||||
self:UnHandleEvent(EVENTS.Crash)
|
||||
|
||||
-- If tanker is alive, despawn it.
|
||||
if self.helo and self.helo:IsAlive() then
|
||||
self:I(self.lid.."Stopping FSM and despawning tanker.")
|
||||
self.tanker:Destroy()
|
||||
else
|
||||
self:I(self.lid.."Stopping FSM. Tanker was not alive.")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -1235,6 +1253,37 @@ function RECOVERYTANKER:_RefuelingStop(EventData)
|
||||
|
||||
end
|
||||
|
||||
--- A unit crashed or died.
|
||||
-- @param #RECOVERYTANKER self
|
||||
-- @param Core.Event#EVENTDATA EventData Event data.
|
||||
function RECOVERYTANKER:_OnEventCrashOrDead(EventData)
|
||||
self:F2({eventdata=EventData})
|
||||
|
||||
-- Check that there is an initiating unit in the event data.
|
||||
if EventData and EventData.IniUnit then
|
||||
|
||||
-- Crashed or dead unit.
|
||||
local unit=EventData.IniUnit
|
||||
local unitname=tostring(EventData.IniUnitName)
|
||||
|
||||
-- Check that it was the tanker that crashed.
|
||||
if EventData.IniGroupName==self.tanker:GetName() then
|
||||
|
||||
-- Error message.
|
||||
self:E(self.lid..string.format("Recovery tanker %s crashed!", unitname))
|
||||
|
||||
-- Stop FSM.
|
||||
self:Stop()
|
||||
|
||||
-- Restart.
|
||||
if self.respawn then
|
||||
self:__Start(5)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- MISC functions
|
||||
|
||||
@ -11,6 +11,12 @@
|
||||
-- * Multiple helos at different carriers due to object oriented approach.
|
||||
-- * Finite State Machine (FSM) implementation.
|
||||
--
|
||||
-- ## Known (DCS) Issues
|
||||
--
|
||||
-- * CH-53E does only report 27.5% fuel even if fuel is set to 100% in the ME. See [bug report](https://forums.eagle.ru/showthread.php?t=223712)
|
||||
-- * CH-53E does not accept USS Tarawa as landing airbase (even it can be spawned on it).
|
||||
-- * Helos dont move away from their landing position on carriers.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **funkyfranky**
|
||||
@ -229,7 +235,7 @@ RESCUEHELO.UID=0
|
||||
|
||||
--- Class version.
|
||||
-- @field #string version
|
||||
RESCUEHELO.version="1.0.4"
|
||||
RESCUEHELO.version="1.0.5"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@ -319,12 +325,14 @@ function RESCUEHELO:New(carrierunit, helogroupname)
|
||||
self:SetStartState("Stopped")
|
||||
|
||||
-- Add FSM transitions.
|
||||
-- From State --> Event --> To State
|
||||
-- From State --> Event --> To State
|
||||
self:AddTransition("Stopped", "Start", "Running")
|
||||
self:AddTransition("Running", "Rescue", "Rescuing")
|
||||
self:AddTransition("Running", "RTB", "Returning")
|
||||
self:AddTransition("Rescuing", "RTB", "Returning")
|
||||
self:AddTransition("*", "Run", "Running")
|
||||
self:AddTransition("Returning", "Returned", "Returned")
|
||||
self:AddTransition("Running", "Run", "Running")
|
||||
self:AddTransition("Returned", "Run", "Running")
|
||||
self:AddTransition("*", "Status", "*")
|
||||
self:AddTransition("*", "Stop", "Stopped")
|
||||
|
||||
@ -378,6 +386,25 @@ 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
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the helo has landed.
|
||||
|
||||
--- Triggers the delayed FSM event "Returned" after the helo has landed.
|
||||
-- @function [parent=#RESCUEHELO] __Returned
|
||||
-- @param #RESCUEHELO self
|
||||
-- @param #number delay Delay in seconds.
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the helo has landed.
|
||||
|
||||
--- On after "Returned" event user function. Called when a the the helo has landed at an airbase.
|
||||
-- @function [parent=#RESCUEHELO] OnAfterReturned
|
||||
-- @param #RESCUEHELO self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the helo has landed.
|
||||
|
||||
|
||||
--- Triggers the FSM event "Run".
|
||||
-- @function [parent=#RESCUEHELO] Run
|
||||
@ -705,58 +732,24 @@ function RESCUEHELO:OnEventLand(EventData)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
-- Helo has rescued someone.
|
||||
-- TODO: Add "Rescued" event.
|
||||
if self:IsRescuing() then
|
||||
|
||||
self:T(self.lid..string.format("Rescue helo %s returned from rescue operation.", groupname))
|
||||
|
||||
end
|
||||
|
||||
-- Check if takeoff air or respawn in air is set. Landing event should not happen unless the helo was on a rescue mission.
|
||||
if self.takeoff==SPAWN.Takeoff.Air or self.respawninair then
|
||||
|
||||
if self:IsRescuing() then
|
||||
if not self:IsRescuing() then
|
||||
|
||||
self:T(self.lid..string.format("Rescue helo %s returned from rescue operation.", groupname))
|
||||
|
||||
-- Set modex for respawn.
|
||||
group:InitModex(self.modex)
|
||||
|
||||
-- Respawn helo at current airbase.
|
||||
SCHEDULER:New(nil, group.RespawnAtCurrentAirbase, {group}, 3)
|
||||
|
||||
else
|
||||
|
||||
self:T2(self.lid..string.format("WARNING: Rescue helo %s landed. This should not happen for Takeoff=Air or respawninair=true unless a rescue operation finished.", groupname))
|
||||
|
||||
-- Respawn helo at current airbase anyway.
|
||||
if self.respawn then
|
||||
|
||||
-- Set modex for respawn.
|
||||
group:InitModex(self.modex)
|
||||
|
||||
-- Respawn helo at current airbase.
|
||||
SCHEDULER:New(nil, group.RespawnAtCurrentAirbase, {group}, 3)
|
||||
|
||||
end
|
||||
self:E(self.lid..string.format("WARNING: Rescue helo %s landed. This should not happen for Takeoff=Air or respawninair=true and no rescue operation in progress.", groupname))
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
-- Respawn helo at current airbase.
|
||||
if self.respawn then
|
||||
|
||||
-- Set modex for respawn.
|
||||
group:InitModex(self.modex)
|
||||
|
||||
-- Respawn helo at current airbase.
|
||||
SCHEDULER:New(nil, group.RespawnAtCurrentAirbase, {group}, 3)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Restart the formation.
|
||||
self:__Run(10)
|
||||
-- Trigger returned event. Respawn at current airbase.
|
||||
self:__Returned(3, EventData.Place)
|
||||
|
||||
end
|
||||
end
|
||||
@ -814,6 +807,11 @@ function RESCUEHELO:_OnEventCrashOrEject(EventData)
|
||||
-- Stop FSM.
|
||||
self:Stop()
|
||||
|
||||
-- Restart.
|
||||
if self.respawn then
|
||||
self:__Start(5)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@ -838,7 +836,7 @@ function RESCUEHELO:onafterStart(From, Event, To)
|
||||
-- Handle events.
|
||||
--self:HandleEvent(EVENTS.Birth)
|
||||
self:HandleEvent(EVENTS.Land)
|
||||
self:HandleEvent(EVENTS.Crash, self._OnEventCrashOrEject)
|
||||
self:HandleEvent(EVENTS.Crash, self._OnEventCrashOrEject)
|
||||
self:HandleEvent(EVENTS.Ejection, self._OnEventCrashOrEject)
|
||||
|
||||
-- Delay before formation is started.
|
||||
@ -948,11 +946,14 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
||||
-- HELO is ALIVE --
|
||||
-------------------
|
||||
|
||||
-- Get relative fuel wrt to initial fuel of helo (DCS bug https://forums.eagle.ru/showthread.php?t=223712)
|
||||
local fuel=self.helo:GetFuel()/self.HeloFuel0*100
|
||||
-- Get (relative) fuel wrt to initial fuel of helo (DCS bug https://forums.eagle.ru/showthread.php?t=223712)
|
||||
local fuel=self.helo:GetFuel()*100
|
||||
local fuelrel=fuel/self.HeloFuel0
|
||||
local life=self.helo:GetUnit(1):GetLife()
|
||||
local life0=self.helo:GetUnit(1):GetLife0()
|
||||
|
||||
-- Report current fuel.
|
||||
local text=string.format("Rescue Helo %s: state=%s fuel=%.1f", self.helo:GetName(), self:GetState(), 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)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
@ -973,6 +974,10 @@ 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.
|
||||
-- Also trying to find a ship to land on he flies right through it.
|
||||
--self.helo:OptionRTBBingoFuel(false)
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
@ -986,15 +991,7 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
||||
|
||||
elseif self:IsRescuing() then
|
||||
|
||||
if self.rtb then
|
||||
|
||||
-- Send helo back to base.
|
||||
--self:RTB()
|
||||
|
||||
-- Switch to false.
|
||||
self.rtb=false
|
||||
|
||||
end
|
||||
-- Helo is on a rescue mission.
|
||||
|
||||
end
|
||||
|
||||
@ -1003,25 +1000,28 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
||||
self:__Status(-30)
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
|
||||
------------------
|
||||
-- HELO is DEAD --
|
||||
------------------
|
||||
|
||||
-- Stop FSM.
|
||||
self:Stop()
|
||||
if not self:IsStopped() then
|
||||
|
||||
-- Stop FSM.
|
||||
self:Stop()
|
||||
|
||||
-- Restart FSM after 5 seconds.
|
||||
if self.respawn then
|
||||
self:__Start(5)
|
||||
end
|
||||
|
||||
-- Restart FSM after 5 seconds.
|
||||
if self.respawn then
|
||||
self:__Start(5)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- On after "Run" event. FSM will go to "Running" state. If formation is topped, it will be started again.
|
||||
--- On after "Run" event. FSM will go to "Running" state. If formation is stopped, it will be started again.
|
||||
-- @param #RESCUEHELO self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
@ -1068,7 +1068,7 @@ function RESCUEHELO:_TaskRTB()
|
||||
-- Task script.
|
||||
local DCSScript = {}
|
||||
DCSScript[#DCSScript+1] = string.format('local mycarrier = UNIT:FindByName(\"%s\") ', carriername) -- The carrier unit that holds the self object.
|
||||
DCSScript[#DCSScript+1] = string.format('local myhelo = mycarrier:GetState(mycarrier, \"RESCUEHELO_%d\") ', self.uid) -- Get the RECOVERYTANKER self object.
|
||||
DCSScript[#DCSScript+1] = string.format('local myhelo = mycarrier:GetState(mycarrier, \"RESCUEHELO_%d\") ', self.uid) -- Get the RESCUEHELO self object.
|
||||
DCSScript[#DCSScript+1] = string.format('myhelo:RTB()') -- Call the function, e.g. myhelo.(self)
|
||||
|
||||
-- Create task.
|
||||
@ -1186,16 +1186,58 @@ function RESCUEHELO:onafterRTB(From, Event, To, airbase)
|
||||
self:RouteRTB(airbase)
|
||||
end
|
||||
|
||||
--- On after Stop event. Unhandle events and stop status updates.
|
||||
--- On after Returned event. Helo has landed.
|
||||
-- @param #RESCUEHELO self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The base to which the helo has returned.
|
||||
function RESCUEHELO:onafterReturned(From, Event, To, airbase)
|
||||
|
||||
if airbase then
|
||||
local airbasename=airbase:GetName()
|
||||
self:T(self.lid..string.format("Helo returned to airbase %s", tostring(airbasename)))
|
||||
else
|
||||
self:E(self.lid..string.format("WARNING: Helo landed but airbase (EventData.Place) is nil!"))
|
||||
end
|
||||
|
||||
-- Respawn helo at current airbase.
|
||||
if self.respawn then
|
||||
|
||||
-- Set modex for respawn.
|
||||
self.helo:InitModex(self.modex)
|
||||
|
||||
-- Respawn helo at current airbase.
|
||||
self.helo:RespawnAtCurrentAirbase()
|
||||
|
||||
-- Restart the formation.
|
||||
self:__Run(10)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- On after Stop event. Unhandle events and stop status updates. If helo is alive, it is despawned.
|
||||
-- @param #RESCUEHELO self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function RESCUEHELO:onafterStop(From, Event, To)
|
||||
|
||||
-- Stop formation
|
||||
self.formation:Stop()
|
||||
|
||||
-- Unhandle events.
|
||||
self:UnHandleEvent(EVENTS.Land)
|
||||
self:UnHandleEvent(EVENTS.Crash)
|
||||
self:UnHandleEvent(EVENTS.Ejection)
|
||||
|
||||
-- If helo is alive, despawn it.
|
||||
if self.helo and self.helo:IsAlive() then
|
||||
self:I(self.lid.."Stopping FSM and despawning helo.")
|
||||
self.helo:Destroy()
|
||||
else
|
||||
self:I(self.lid.."Stopping FSM. Helo was not alive.")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user