mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-08-11 03:43:38 +00:00
CVW
This commit is contained in:
@@ -69,6 +69,7 @@ __Moose.Include( 'Scripts/Moose/Ops/RecoveryTanker.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Ops/RescueHelo.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Ops/FlightControl.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Ops/Skipper.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/Ops/CarrierAirWing.lua' )
|
||||
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_Balancer.lua' )
|
||||
__Moose.Include( 'Scripts/Moose/AI/AI_Air.lua' )
|
||||
|
||||
@@ -13588,7 +13588,7 @@ function AIRBOSS._PassingWaypoint(group, airboss, i, final)
|
||||
|
||||
-- If final waypoint reached, do route all over again.
|
||||
if i==final and final>1 and airboss.adinfinitum then
|
||||
airboss:_PatrolRoute(i)
|
||||
airboss:_PatrolRoute()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,536 @@
|
||||
--- **CVW** - (R2.5) - Carrier Air Wing (CVW) Warehouse.
|
||||
--
|
||||
-- **Main Features:**
|
||||
--
|
||||
-- * Nice stuff.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **funkyfranky**
|
||||
-- @module Ops.CVW
|
||||
-- @image OPS_CarrierAirWing.png
|
||||
|
||||
|
||||
--- CVW class.
|
||||
-- @type CVW
|
||||
-- @field #string ClassName Name of the class.
|
||||
-- @field #boolean Debug Debug mode. Messages to all about status.
|
||||
-- @field #string cid Class id string for output to DCS log file.
|
||||
-- @field #string carriername The name of the carrier unit.
|
||||
-- @field Wrapper.Group#GROUP group The carrier strike group.
|
||||
-- @field #table menu Table of menu items.
|
||||
-- @extends Functional.Warehouse#WAREHOUSE
|
||||
|
||||
--- Be surprised!
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- # The CVW Concept
|
||||
--
|
||||
--
|
||||
--
|
||||
-- @field #CVW
|
||||
CVW = {
|
||||
ClassName = "CVW",
|
||||
sid = nil,
|
||||
carriername = nil,
|
||||
group = nil,
|
||||
menu = nil,
|
||||
}
|
||||
|
||||
--- Squadron
|
||||
-- @type CVW.Squadron
|
||||
-- @field Wrapper.Group#GROUP group Intruder group object.
|
||||
-- @field #string groupname Name of the intruder group.
|
||||
-- @field #number time0 Abs. mission time first detected inside CCA.
|
||||
-- @field #number dist0 Distance first detected inside CCA.
|
||||
-- @field DCS#Coalition.Side coalition Coalition side.
|
||||
-- @field #number threadlevel Thread level of intruder.
|
||||
-- @field #string threadtext Thread text.
|
||||
-- @field #number category Group category.
|
||||
-- @field #string categoryname Group category name.
|
||||
-- @field #string typename Type name of group.
|
||||
-- @field #table menu The defence menu entries.
|
||||
|
||||
--- FlightControl class version.
|
||||
-- @field #string version
|
||||
CVW.version="0.0.1"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: A lot!
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Create a new CVW class object for a specific aircraft carrier unit.
|
||||
-- @param #CVW self
|
||||
-- @param #string carriername Name of the carrier.
|
||||
-- @param #string alias Skipper alias.
|
||||
-- @return #CVW self
|
||||
function CVW:New(carriername, alias)
|
||||
|
||||
-- Inherit everything from WAREHOUSE class.
|
||||
local self=BASE:Inherit(self, WAREHOUSE:New(carriername, alias)) -- #CVW
|
||||
|
||||
if not self.carrier then
|
||||
BASE:E(string.format("ERROR: Could not find carrier %s!", carriername))
|
||||
return nil
|
||||
end
|
||||
|
||||
self.carriername=carriername
|
||||
|
||||
self.group=self.carrier:GetGroup()
|
||||
|
||||
|
||||
-- Set some string id for output to DCS.log file.
|
||||
self.sid=string.format("CVW %s |", self.carriername)
|
||||
|
||||
-- Add FSM transitions.
|
||||
-- From State --> Event --> To State
|
||||
self:AddTransition("*", "AirwingStatus", "*") -- Skipper status update.
|
||||
self:AddTransition("*", "RequestCAP", "*") -- New intruder detected.
|
||||
|
||||
------------------------
|
||||
--- Pseudo Functions ---
|
||||
------------------------
|
||||
|
||||
--- Triggers the FSM event "Start". Starts the CVW. Initializes parameters and starts event handlers.
|
||||
-- @function [parent=#CVW] Start
|
||||
-- @param #CVW self
|
||||
|
||||
--- Triggers the FSM event "Start" after a delay. Starts the CVW. Initializes parameters and starts event handlers.
|
||||
-- @function [parent=#CVW] __Start
|
||||
-- @param #CVW self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- Triggers the FSM event "Stop". Stops the CVW and all its event handlers.
|
||||
-- @param #CVW self
|
||||
|
||||
--- Triggers the FSM event "Stop" after a delay. Stops the CVW and all its event handlers.
|
||||
-- @function [parent=#CVW] __Stop
|
||||
-- @param #CVW self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- Triggers the FSM event "SkipperStatus".
|
||||
-- @function [parent=#CVW] SkipperStatus
|
||||
-- @param #CVW self
|
||||
|
||||
--- Triggers the FSM event "SkipperStatus" after a delay.
|
||||
-- @function [parent=#CVW] __SkipperStatus
|
||||
-- @param #CVW self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
|
||||
-- Debug trace.
|
||||
if true then
|
||||
self.Debug=true
|
||||
BASE:TraceOnOff(true)
|
||||
BASE:TraceClass(self.ClassName)
|
||||
BASE:TraceLevel(1)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- User Functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Optimized F10 radio menu for a single carrier. The menu entries will be stored directly under F10 Other/Skipper/ and not F10 Other/Skipper/"Carrier Alias"/.
|
||||
-- **WARNING**: If you use this with two CVW objects/carriers, the radio menu will be screwed up!
|
||||
-- @param #CVW self
|
||||
-- @param #boolean switch If true or nil single menu is enabled. If false, menu is for multiple carriers in the mission.
|
||||
-- @return #CVW self
|
||||
function CVW:SetMenuSingleCarrier(switch)
|
||||
if switch==true or switch==nil then
|
||||
self.menusingle=true
|
||||
else
|
||||
self.menusingle=false
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add squadron
|
||||
-- @param #CVW self
|
||||
-- @param #string name Name of the squadron, e.g. VFA-37.
|
||||
-- @return #CVW self
|
||||
function CVW:AddSquadron(name)
|
||||
|
||||
local squadron={} --#CVW.Squadron
|
||||
|
||||
squadron.name=name
|
||||
squadron.assets={}
|
||||
|
||||
table.insert(self.squadrons, squadron)
|
||||
end
|
||||
|
||||
--- Add squadron
|
||||
-- @param #CVW self
|
||||
-- @param #string groupname Name of the template group.
|
||||
-- @return #CVW self
|
||||
function CVW:AddFlightToSquadron(squadron, flightgroup, ngroups, livery)
|
||||
|
||||
self:AddAsset(flightgroup, ngroups, nil, nil, nil, nil, nil, {livery}, squadron.name)
|
||||
|
||||
function self:OnAfterNewAsset(From,Event,To,asset,assignment)
|
||||
if assignment==squadron.name then
|
||||
table.insert(squadron.assets, asset)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Get squadron by name
|
||||
-- @param #CVW self
|
||||
-- @param #string name Name of the squadron, e.g. VFA-37.
|
||||
-- @return #CVW self
|
||||
function CVW:GetSquadron(name)
|
||||
|
||||
for _,_squadron in pairs(self.squadrons) do
|
||||
if _squadron.name==name then
|
||||
return _squadron
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Status
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Start CVW FSM. Handle events.
|
||||
-- @param #CVW self
|
||||
function CVW:onafterStart(From, Event, To)
|
||||
|
||||
-- Start parent Warehouse.
|
||||
self:GetParent(self).onafterStart(self, From, Event, To)
|
||||
|
||||
-- Info.
|
||||
self:I(self.sid..string.format("Starting CVW v%s for carrier %s on map %s.", CVW.version, self.carriername, self.theatre))
|
||||
|
||||
-- Add F10 radio menu.
|
||||
self:_SetMenuCoalition()
|
||||
|
||||
-- Init status updates.
|
||||
self:__AirwingStatus(-1)
|
||||
end
|
||||
|
||||
--- Update status.
|
||||
-- @param #CVW self
|
||||
function CVW:onafterSkipperStatus(From, Event, To)
|
||||
|
||||
local fsmstate=self:GetState()
|
||||
|
||||
-- Check zone for flights inbound.
|
||||
self:_CheckIntruder()
|
||||
|
||||
-- Info text.
|
||||
local text=string.format("State %s", fsmstate)
|
||||
self:I(self.sid..text)
|
||||
|
||||
self:__AirwingStatus(-30)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- FSM Events
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Update status.
|
||||
-- @param #CVW self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param #CVW.Squadon squadron
|
||||
-- @param Core.Point#COORDINATE coordinate
|
||||
function CVW:onafterRequestCAP(From, Event, To, squadron, coordinate)
|
||||
|
||||
|
||||
self:__AddRequest(1, self, WAREHOUSE.Descriptor.ASSIGNMENT, squadron.name, 1, nil, nil, nil, "CAP")
|
||||
|
||||
function self:OnAfterSelfRequest(From,Event,To,Groupset,Request)
|
||||
|
||||
if Request.assignment=="CAP" then
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Misc Functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Menu Functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Patrol carrier.
|
||||
-- @param #CVW self
|
||||
-- @return #CVW self
|
||||
function CVW:_SetMenuCoalition()
|
||||
|
||||
-- Get coalition.
|
||||
local Coalition=self:GetCoalition()
|
||||
|
||||
-- Init menu table.
|
||||
self.menu=self.menu or {}
|
||||
|
||||
-- Init menu coalition table.
|
||||
self.menu[Coalition]=self.menu[Coalition] or {}
|
||||
|
||||
-- Shortcut.
|
||||
local menu=self.menu[Coalition]
|
||||
|
||||
if self.menusingle then
|
||||
-- F10/Skipper/...
|
||||
if not menu.Skipper then
|
||||
menu.Skipper=MENU_COALITION:New(Coalition, "Skipper")
|
||||
end
|
||||
else
|
||||
-- F10/Skipper/<Carrier Alias>/...
|
||||
if not menu.Root then
|
||||
menu.Root=MENU_COALITION:New(Coalition, "Skipper")
|
||||
end
|
||||
menu.Skipper=MENU_COALITION:New(Coalition, self.alias, menu.Root)
|
||||
end
|
||||
|
||||
-------------------
|
||||
-- Squadron Menu --
|
||||
-------------------
|
||||
|
||||
menu.Squadron= MENU_COALITION:New(Coalition, "Squadrons", menu.Skipper)
|
||||
|
||||
|
||||
------------------
|
||||
-- Defence Menu --
|
||||
------------------
|
||||
|
||||
menu.Defence = MENU_COALITION:New(Coalition, "Defence", menu.Skipper)
|
||||
menu.Defence_SetROE = MENU_COALITION:New(Coalition, "Set ROE", menu.Defence)
|
||||
menu.Defence_SetROE_Hold = MENU_COALITION_COMMAND:New(Coalition, "Weapon Hold", menu.Defence_SetROE, self._SetROE, self, "Hold")
|
||||
menu.Defence_SetROE_Free = MENU_COALITION_COMMAND:New(Coalition, "Weapon Free", menu.Defence_SetROE, self._SetROE, self, "Free")
|
||||
menu.Defence_SetROE_Return = MENU_COALITION_COMMAND:New(Coalition, "Return Fire", menu.Defence_SetROE, self._SetROE, self, "Return")
|
||||
|
||||
menu.Defence_Intruders = MENU_COALITION:New(Coalition, "Intruders", menu.Defence)
|
||||
menu.Defence_Ammo = MENU_COALITION_COMMAND:New(Coalition, "Report Ammo", menu.Defence, self.arty.GetAmmo, self.arty, true)
|
||||
menu.Defence_IntruderR = MENU_COALITION_COMMAND:New(Coalition, "Report Intruders", menu.Defence, self._ListIntruders, self)
|
||||
menu.Defence_LaunchCAP = MENU_COALITION_COMMAND:New(Coalition, "Lauch CAP", menu.Defence, self.LaunchCAP, self)
|
||||
|
||||
--------------------
|
||||
-- Warehouse Menu --
|
||||
--------------------
|
||||
|
||||
if self.warehouse then
|
||||
menu.Warehouse=MENU_COALITION:New(Coalition, "Warehouse", menu.Skipper)
|
||||
menu.Warehouse_Assets = MENU_COALITION_COMMAND:New(Coalition, "Reports On/Off", menu.Warehouse, self.WarehouseReportsToggle, self)
|
||||
menu.Warehouse_Assets = MENU_COALITION_COMMAND:New(Coalition, "Report Assets", menu.Warehouse, self.ReportWarehouseStock, self)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Add sub menu for this intruder.
|
||||
-- @param #CVW self
|
||||
-- @param #CVW.Squadron squadron The squadron data.
|
||||
function CVW:_AddSquadonMenu(squadron)
|
||||
|
||||
local Coalition=self:GetCoalition()
|
||||
|
||||
local root=self.menu[Coalition].Squadrons
|
||||
|
||||
local menu=MENU_COALITION:New(Coalition, squadron.name, root)
|
||||
|
||||
if intruder.category==Group.Category.GROUND then
|
||||
MENU_COALITION_COMMAND:New(Coalition, "Engage Shells", menu, self.EngageArty, self, intruder, ARTY.WeaponType.Cannon)
|
||||
MENU_COALITION_COMMAND:New(Coalition, "Engage Cruise M", menu, self.EngageArty, self, intruder, ARTY.WeaponType.CruiseMissile)
|
||||
elseif intruder.category==Group.Category.SHIP then
|
||||
MENU_COALITION_COMMAND:New(Coalition, "Engage", menu, self.EngageArty, self, intruder)
|
||||
elseif intruder.category==Group.Category.AIRPLANE or intruder.category==Group.Category.HELICOPTER then
|
||||
MENU_COALITION_COMMAND:New(Coalition, "Engage A2A", menu, self.LaunchIntercept, self, intruder)
|
||||
end
|
||||
|
||||
-- Set menu.
|
||||
intruder.menu=menu
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Warehouse reports on/off.
|
||||
-- @param #CVW self
|
||||
function CVW:WarehouseReportsToggle()
|
||||
self.warehouse.Report=not self.warehouse.Report
|
||||
MESSAGE:New(string.format("Warehouse reports are now %s", tostring(self.warehouse.Report)), 10, "CVW", true):ToCoalition(self:GetCoalition())
|
||||
end
|
||||
|
||||
|
||||
--- Report warehouse stock.
|
||||
-- @param #CVW self
|
||||
function CVW:ReportWarehouseStock()
|
||||
local text=self.warehouse:_GetStockAssetsText(false)
|
||||
MESSAGE:New(text, 10, "CVW", true):ToCoalition(self:GetCoalition())
|
||||
end
|
||||
|
||||
--- Launch a Intercept flight.
|
||||
-- @param #CVW self
|
||||
-- @param #CVW.Intruder intruder Intruder group.
|
||||
function CVW:LaunchIntercept(intruder)
|
||||
|
||||
-- Get number of aircraft.
|
||||
local n=self:GetNumberOfAssets(WAREHOUSE.Descriptor.ASSIGNMENT, "Intercept", false)
|
||||
|
||||
if n>0 then
|
||||
|
||||
self.warehouse:AddRequest(self.warehouse, WAREHOUSE.Descriptor.ASSIGNMENT, "Intercept", 1, nil, nil, nil, "Intercept")
|
||||
|
||||
local capcoord=intruder.group:GetCoordinate()
|
||||
|
||||
capcoord:MarkToAll("Intruder coord")
|
||||
|
||||
function self.warehouse.OnAfterSelfRequest(warehouse, From, Event, To, Groupset, Request)
|
||||
local request=Request --Functional.Warehouse#WAREHOUSE.Pendingitem
|
||||
local groupset=Groupset --Core.Set#SET_GROUP
|
||||
|
||||
for _,_group in pairs(groupset:GetSet()) do
|
||||
local group=_group --Wrapper.Group#GROUP
|
||||
|
||||
if request.assignment=="Intercept" then
|
||||
|
||||
-- Task orbit.
|
||||
local tasks={}
|
||||
|
||||
for _,unit in pairs(intruder.group:GetUnits()) do
|
||||
tasks[#tasks+1]=group:TaskAttackUnit(unit)
|
||||
end
|
||||
|
||||
local speed=group:GetSpeedMax()
|
||||
local altitude=intruder.group:GetAltitude()
|
||||
|
||||
-- Create waypoints.
|
||||
local wp={}
|
||||
wp[1]=self:GetCoordinate():WaypointAirTakeOffParking()
|
||||
wp[2]=self:GetCoordinate():SetAltitude(altitude):WaypointAirTurningPoint(COORDINATE.WaypointAltType.BARO, speed, {tasks}, "Attack Intruder")
|
||||
|
||||
-- Start uncontrolled group.
|
||||
group:StartUncontrolled()
|
||||
|
||||
--airboss:SetExcludeAI()
|
||||
|
||||
-- Route group
|
||||
group:Route(wp)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
MESSAGE:New("No INTERCEPT fighters currently available", 5, "CVW"):ToCoalition(self:GetCoalition())
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Launch a CAP flight.
|
||||
-- @param #CVW self
|
||||
function CVW:LaunchCAP()
|
||||
|
||||
local n=self:GetNumberOfAssets(WAREHOUSE.Descriptor.ASSIGNMENT, "CAP", false)
|
||||
|
||||
if n>0 then
|
||||
|
||||
self:AddRequest(self, WAREHOUSE.Descriptor.ATTRIBUTE, WAREHOUSE.Attribute.AIR_FIGHTER, 1, nil, nil, nil, "CAP")
|
||||
|
||||
local capcoord=self.zoneCCA:GetRandomCoordinate(self.zoneCCA:GetRadius()/2)
|
||||
|
||||
capcoord:MarkToAll("CAP coord")
|
||||
|
||||
function self:OnAfterSelfRequest(From, Event, To, Groupset, Request)
|
||||
local request=Request --Functional.Warehouse#WAREHOUSE.Pendingitem
|
||||
local groupset=Groupset --Core.Set#SET_GROUP
|
||||
|
||||
for _,_group in pairs(groupset:GetSet()) do
|
||||
local group=_group --Wrapper.Group#GROUP
|
||||
|
||||
if request.assignment=="CAP" then
|
||||
|
||||
local alt=UTILS.FeetToMeters(20000)
|
||||
|
||||
-- Task orbit.
|
||||
local taskOrbit=group:TaskOrbit(capcoord, alt, UTILS.KnotsToMps(400), capcoord:Translate(UTILS.NMToMeters(15), 0))
|
||||
|
||||
local wp={}
|
||||
wp[1]=self:GetCoordinate():WaypointAirTakeOffParking()
|
||||
wp[2]=self:GetCoordinate():SetAltitude(alt):WaypointAirTurningPoint(COORDINATE.WaypointAltType.BARO, UTILS.KnotsToKmph(350), {taskOrbit}, "CAP")
|
||||
|
||||
-- Start uncontrolled group.
|
||||
group:StartUncontrolled()
|
||||
|
||||
--airboss:SetExcludeAI()
|
||||
|
||||
-- Route group.
|
||||
group:Route(wp)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
MESSAGE:New("No CAP fighters currently available", 5, "CVW"):ToCoalition(self:GetCoalition())
|
||||
end
|
||||
end
|
||||
|
||||
--- Sort intruders table.
|
||||
-- @param #CVW self
|
||||
function CVW:_SortIntruders()
|
||||
|
||||
-- Sort potential section members wrt to distance to lead.
|
||||
local function _sort(_a,_b)
|
||||
local a=_a --#CVW.Intruder
|
||||
local b=_b --#CVW.Intruder
|
||||
return a.threadlevel>b.threadlevel
|
||||
end
|
||||
|
||||
table.sort(self.intruders, _sort)
|
||||
end
|
||||
|
||||
--- Add sub menu for this intruder.
|
||||
-- @param #CVW self
|
||||
-- @param #CVW.Intruder intruder The intruder data.
|
||||
-- @param #boolean removed If true, an intruder was removed. If false or nil, a new intruder was added.
|
||||
function CVW:_UpdateIntruderMenu()
|
||||
|
||||
for _,_intruder in ipairs(self.intruders) do
|
||||
local intruder=_intruder --#CVW.Intruder
|
||||
self:_AddIntruderMenu(intruder)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Remove sub menu for this intruder.
|
||||
-- @param #CVW self
|
||||
-- @param #CVW.Intruder intruder The intruder data.
|
||||
function CVW:_RemoveIntruderMenu(intruder)
|
||||
|
||||
if intruder.menu then
|
||||
local menu=intruder.menu --Core.Menu#MENU_COALITION
|
||||
|
||||
menu:Remove()
|
||||
|
||||
intruder.menu=nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -113,34 +113,9 @@ function SKIPPER:New(carriername, alias)
|
||||
|
||||
-- Set some string id for output to DCS.log file.
|
||||
self.sid=string.format("SKIPPER %s |", self.carriername)
|
||||
|
||||
--[[
|
||||
|
||||
-- Current map.
|
||||
self.theatre=env.mission.theatre
|
||||
|
||||
-- 30 NM zone around the airbase.
|
||||
self.zoneCCA=ZONE_UNIT:New("CCA", self.carrier, UTILS.NMToMeters(50))
|
||||
|
||||
-- Initialize ME waypoints.
|
||||
self:_InitWaypoints()
|
||||
|
||||
-- Current waypoint.
|
||||
self.currentwp=1
|
||||
|
||||
-- Patrol route.
|
||||
self:_PatrolRoute()
|
||||
|
||||
-- Start State.
|
||||
self:SetStartState("Stopped")
|
||||
|
||||
--]]
|
||||
|
||||
-- Add FSM transitions.
|
||||
-- From State --> Event --> To State
|
||||
--self:AddTransition("Stopped", "Start", "Running") -- Start FSM.
|
||||
--self:AddTransition("*", "Status", "*") -- Update status.
|
||||
|
||||
self:AddTransition("*", "SkipperStatus", "*") -- Skipper status update.
|
||||
self:AddTransition("*", "IntruderAlert", "*") -- New intruder detected.
|
||||
|
||||
@@ -165,12 +140,12 @@ function SKIPPER:New(carriername, alias)
|
||||
-- @param #SKIPPER self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- Triggers the FSM event "Status".
|
||||
-- @function [parent=#SKIPPER] Status
|
||||
--- Triggers the FSM event "SkipperStatus".
|
||||
-- @function [parent=#SKIPPER] SkipperStatus
|
||||
-- @param #SKIPPER self
|
||||
|
||||
--- Triggers the FSM event "Status" after a delay.
|
||||
-- @function [parent=#SKIPPER] __Status
|
||||
--- Triggers the FSM event "SkipperStatus" after a delay.
|
||||
-- @function [parent=#SKIPPER] __SkipperStatus
|
||||
-- @param #SKIPPER self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
@@ -199,7 +174,7 @@ function SKIPPER:New(carriername, alias)
|
||||
self.Debug=true
|
||||
BASE:TraceOnOff(true)
|
||||
BASE:TraceClass(self.ClassName)
|
||||
BASE:TraceLevel(3)
|
||||
BASE:TraceLevel(1)
|
||||
self.arty:GetAmmo(true)
|
||||
end
|
||||
|
||||
@@ -293,9 +268,6 @@ end
|
||||
-- @param #SKIPPER self
|
||||
function SKIPPER:onafterSkipperStatus(From, Event, To)
|
||||
|
||||
-- Get State of parent airboss.
|
||||
--self:GetParent(self).onafterStatus(self, From, Event, To)
|
||||
|
||||
local fsmstate=self:GetState()
|
||||
|
||||
-- Check zone for flights inbound.
|
||||
@@ -375,7 +347,11 @@ function SKIPPER:_CheckIntruder()
|
||||
|
||||
-- Intruder is gone!
|
||||
if not gotit then
|
||||
|
||||
-- Remove from table.
|
||||
table.remove(self.intruders, i)
|
||||
|
||||
-- Menu update required.
|
||||
updateintrudermenu=true
|
||||
end
|
||||
|
||||
@@ -410,12 +386,10 @@ function SKIPPER:_CheckIntruder()
|
||||
-- Add intruder to list.
|
||||
table.insert(self.intruders, intruder)
|
||||
|
||||
-- Add menu.
|
||||
--self:_AddIntruderMenu(intruder)
|
||||
|
||||
-- Trigger alert!
|
||||
self:IntruderAlert(intruder)
|
||||
|
||||
-- Menu update required.
|
||||
updateintrudermenu=true
|
||||
end
|
||||
end
|
||||
@@ -433,148 +407,6 @@ end
|
||||
-- Misc Functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--[[
|
||||
|
||||
--- Patrol carrier.
|
||||
-- @param #SKIPPER self
|
||||
-- @return #SKIPPER self
|
||||
function SKIPPER:_InitWaypoints()
|
||||
|
||||
-- Waypoints of group.
|
||||
local Waypoints=self.group:GetTemplateRoutePoints()
|
||||
|
||||
-- Init array.
|
||||
self.waypoints={}
|
||||
|
||||
-- Set waypoint table.
|
||||
for i,point in ipairs(Waypoints) do
|
||||
|
||||
-- Coordinate of the waypoint
|
||||
local coord=COORDINATE:New(point.x, point.alt, point.y)
|
||||
|
||||
-- Set velocity of the coordinate.
|
||||
coord:SetVelocity(point.speed)
|
||||
|
||||
-- Add to table.
|
||||
table.insert(self.waypoints, coord)
|
||||
|
||||
-- Debug info.
|
||||
if self.Debug then
|
||||
coord:MarkToAll(string.format("Carrier Waypoint %d, Speed=%.1f knots", i, UTILS.MpsToKnots(point.speed)))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Patrol carrier.
|
||||
-- @param #SKIPPER self
|
||||
-- @param #number n Next waypoint number.
|
||||
-- @return #SKIPPER self
|
||||
function SKIPPER:_PatrolRoute(n)
|
||||
|
||||
-- Get next waypoint coordinate and number.
|
||||
local nextWP, N=self:_GetNextWaypoint()
|
||||
|
||||
-- Default resume is to next waypoint.
|
||||
n=n or N
|
||||
|
||||
-- Get carrier group.
|
||||
local CarrierGroup=self.group
|
||||
|
||||
-- Waypoints table.
|
||||
local Waypoints={}
|
||||
|
||||
-- Create a waypoint from the current coordinate.
|
||||
local wp=self:GetCoordinate():WaypointGround(CarrierGroup:GetVelocityKMH())
|
||||
|
||||
-- Add current position as first waypoint.
|
||||
table.insert(Waypoints, wp)
|
||||
|
||||
-- Loop over waypoints.
|
||||
for i=n,#self.waypoints do
|
||||
local coord=self.waypoints[i] --Core.Point#COORDINATE
|
||||
|
||||
-- Create a waypoint from the coordinate.
|
||||
local wp=coord:WaypointGround(UTILS.MpsToKmph(coord.Velocity))
|
||||
|
||||
-- Passing waypoint taskfunction
|
||||
local TaskPassingWP=CarrierGroup:TaskFunction("SKIPPER._PassingWaypoint", self, i, #self.waypoints)
|
||||
|
||||
-- Call task function when carrier arrives at waypoint.
|
||||
CarrierGroup:SetTaskWaypoint(wp, TaskPassingWP)
|
||||
|
||||
--
|
||||
table.insert(Waypoints, wp)
|
||||
end
|
||||
|
||||
-- Route carrier group.
|
||||
CarrierGroup:Route(Waypoints)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Function called when a group is passing a waypoint.
|
||||
--@param Wrapper.Group#GROUP group Group that passed the waypoint.
|
||||
--@param #SKIPPER skipper skipper object.
|
||||
--@param #number i Waypoint number that has been reached.
|
||||
--@param #number final Final waypoint number.
|
||||
function SKIPPER._PassingWaypoint(group, skipper, i, final)
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("Group %s passing waypoint %d of %d.", group:GetName(), i, final)
|
||||
|
||||
-- Debug smoke and marker.
|
||||
if skipper.Debug and false then
|
||||
local pos=group:GetCoordinate()
|
||||
pos:SmokeRed()
|
||||
local MarkerID=pos:MarkToAll(string.format("Group %s reached waypoint %d", group:GetName(), i))
|
||||
end
|
||||
|
||||
-- Debug message.
|
||||
MESSAGE:New(text,10):ToAllIf(skipper.Debug)
|
||||
skipper:T(skipper.lid..text)
|
||||
|
||||
-- Set current waypoint.
|
||||
skipper.currentwp=i
|
||||
|
||||
-- Passing Waypoint event.
|
||||
--skipper:PassingWaypoint(i)
|
||||
|
||||
-- If final waypoint reached, do route all over again.
|
||||
if i==final and final>1 and skipper.adinfinitum then
|
||||
skipper:_PatrolRoute(i)
|
||||
end
|
||||
end
|
||||
|
||||
--- Get next waypoint of the carrier.
|
||||
-- @param #SKIPPER self
|
||||
-- @return Core.Point#COORDINATE Coordinate of the next waypoint.
|
||||
-- @return #number Number of waypoint.
|
||||
function SKIPPER:_GetNextWaypoint()
|
||||
|
||||
-- Next waypoint.
|
||||
local Nextwp=nil
|
||||
if self.currentwp==#self.waypoints then
|
||||
Nextwp=1
|
||||
else
|
||||
Nextwp=self.currentwp+1
|
||||
end
|
||||
|
||||
-- Debug output
|
||||
local text=string.format("Current WP=%d/%d, next WP=%d", self.currentwp, #self.waypoints, Nextwp)
|
||||
self:T2(self.lid..text)
|
||||
|
||||
-- Next waypoint.
|
||||
local nextwp=self.waypoints[Nextwp] --Core.Point#COORDINATE
|
||||
|
||||
return nextwp,Nextwp
|
||||
end
|
||||
|
||||
]]
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Menu Functions
|
||||
@@ -647,6 +479,7 @@ function SKIPPER:_SetMenuCoalition()
|
||||
menu.CaseI = MENU_COALITION_COMMAND:New(Coalition, "Start CASE I", menu.Recovery, self._StartCaseX, self, 1)
|
||||
menu.CaseII = MENU_COALITION_COMMAND:New(Coalition, "Start CASE II", menu.Recovery, self._StartCaseX, self, 2)
|
||||
menu.CaseIII = MENU_COALITION_COMMAND:New(Coalition, "Start CASE III", menu.Recovery, self._StartCaseX, self, 3)
|
||||
menu.Rstop = MENU_COALITION_COMMAND:New(Coalition, "Pause/Unpause", menu.Recovery, self._Rpause, self)
|
||||
menu.Rstop = MENU_COALITION_COMMAND:New(Coalition, "Stop Recovery", menu.Recovery, self._Rstop, self)
|
||||
|
||||
|
||||
@@ -692,6 +525,18 @@ function SKIPPER:ReportWarehouseStock()
|
||||
MESSAGE:New(text, 10, "SKIPPER", true):ToCoalition(self:GetCoalition())
|
||||
end
|
||||
|
||||
--- Handle self requests from carrier warehouse.
|
||||
-- @param #SKIPPER self
|
||||
-- @param Functional.Warehouse#WAREHOUSE warehouse The (carrier) warehouse object.
|
||||
-- @param Core.Set#SET_GROUP groupset Group set.
|
||||
-- @param Functional.Warehouse#WAREHOUSE.Pendingitem request Request.
|
||||
function SKIPPER:_SelfRequest(warehouse, groupset, request)
|
||||
|
||||
local assignment=request.assignment
|
||||
|
||||
env.info(string.format("FF warehouse self request assignment %s", tostring(assignment)))
|
||||
|
||||
end
|
||||
|
||||
--- Launch a Intercept flight.
|
||||
-- @param #SKIPPER self
|
||||
@@ -709,7 +554,6 @@ function SKIPPER:LaunchIntercept(intruder)
|
||||
|
||||
capcoord:MarkToAll("Intruder coord")
|
||||
|
||||
--[[
|
||||
function self.warehouse.OnAfterSelfRequest(warehouse, From, Event, To, Groupset, Request)
|
||||
local request=Request --Functional.Warehouse#WAREHOUSE.Pendingitem
|
||||
local groupset=Groupset --Core.Set#SET_GROUP
|
||||
@@ -721,7 +565,10 @@ function SKIPPER:LaunchIntercept(intruder)
|
||||
|
||||
-- Task orbit.
|
||||
local tasks={}
|
||||
local taskAttack=group:TaskAttackUnit(intruder.group:GetUnit(1))
|
||||
|
||||
for _,unit in pairs(intruder.group:GetUnits()) do
|
||||
tasks[#tasks+1]=group:TaskAttackUnit(unit)
|
||||
end
|
||||
|
||||
local speed=group:GetSpeedMax()
|
||||
local altitude=intruder.group:GetAltitude()
|
||||
@@ -729,38 +576,26 @@ function SKIPPER:LaunchIntercept(intruder)
|
||||
-- Create waypoints.
|
||||
local wp={}
|
||||
wp[1]=self:GetCoordinate():WaypointAirTakeOffParking()
|
||||
wp[2]=self:GetCoordinate():SetAltitude(altitude):WaypointAirTurningPoint(COORDINATE.WaypointAltType.BARO, speed, {taskAttack}, "Attack Intruder")
|
||||
wp[2]=self:GetCoordinate():SetAltitude(altitude):WaypointAirTurningPoint(COORDINATE.WaypointAltType.BARO, speed, {tasks}, "Attack Intruder")
|
||||
|
||||
-- Start uncontrolled group.
|
||||
group:StartUncontrolled()
|
||||
|
||||
--airboss:SetExcludeAI()
|
||||
group:Route(wp)
|
||||
|
||||
-- Route group
|
||||
group:Route(wp)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
]]
|
||||
|
||||
else
|
||||
MESSAGE:New("No INTERCEPT fighters currently available", 5, "SKIPPER"):ToCoalition(self:GetCoalition())
|
||||
end
|
||||
end
|
||||
|
||||
--- Handle self requests from carrier warehouse.
|
||||
-- @param #SKIPPER self
|
||||
-- @param Functional.Warehouse#WAREHOUSE warehouse The (carrier) warehouse object.
|
||||
-- @param Core.Set#SET_GROUP groupset Group set.
|
||||
-- @param Functional.Warehouse#WAREHOUSE.Pendingitem request Request.
|
||||
function SKIPPER:_SelfRequest(warehouse, groupset, request)
|
||||
|
||||
local assignment=request.assignment
|
||||
|
||||
env.info(string.format("FF warehouse self request assignment %s", tostring(assignment)))
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Launch a CAP flight.
|
||||
-- @param #SKIPPER self
|
||||
@@ -777,34 +612,34 @@ function SKIPPER:LaunchCAP()
|
||||
|
||||
capcoord:MarkToAll("CAP coord")
|
||||
|
||||
|
||||
--[[
|
||||
function self.warehouse.OnAfterSelfRequest(warehouse, From, Event, To, Groupset, Request)
|
||||
local request=Request --Functional.Warehouse#WAREHOUSE.Pendingitem
|
||||
local groupset=Groupset --Core.Set#SET_GROUP
|
||||
|
||||
|
||||
for _,_group in pairs(groupset:GetSet()) do
|
||||
local group=_group --Wrapper.Group#GROUP
|
||||
|
||||
|
||||
if request.assignment=="CAP" then
|
||||
|
||||
local alt=UTILS.FeetToMeters(20000)
|
||||
|
||||
-- Task orbit.
|
||||
local taskOrbit=group:TaskOrbit(capcoord, UTILS.FeetToMeters(20000), UTILS.KnotsToMps(400), capcoord:Translate(UTILS.NMToMeters(15), 0))
|
||||
local taskOrbit=group:TaskOrbit(capcoord, alt, UTILS.KnotsToMps(400), capcoord:Translate(UTILS.NMToMeters(15), 0))
|
||||
|
||||
local wp={}
|
||||
wp[1]=self:GetCoordinate():WaypointAirTakeOffParking()
|
||||
wp[2]=self:GetCoordinate():WaypointAirTurningPoint("Baro", UTILS.KnotsToKph(350), {taskOrbit}, "CAP")
|
||||
wp[2]=self:GetCoordinate():SetAltitude(alt):WaypointAirTurningPoint(COORDINATE.WaypointAltType.BARO, UTILS.KnotsToKmph(350), {taskOrbit}, "CAP")
|
||||
|
||||
-- Start uncontrolled group.
|
||||
group:StartUncontrolled()
|
||||
|
||||
--airboss:SetExcludeAI()
|
||||
group:Route(wp)
|
||||
|
||||
-- Route group.
|
||||
group:Route(wp)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
else
|
||||
MESSAGE:New("No CAP fighters currently available", 5, "SKIPPER"):ToCoalition(self:GetCoalition())
|
||||
|
||||
Reference in New Issue
Block a user