mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Ops
This commit is contained in:
parent
3f39ec0ae0
commit
06600b2a94
@ -1591,10 +1591,9 @@ function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request)
|
|||||||
-- Get the SQUADRON of the asset.
|
-- Get the SQUADRON of the asset.
|
||||||
local squadron=self:GetSquadronOfAsset(asset)
|
local squadron=self:GetSquadronOfAsset(asset)
|
||||||
|
|
||||||
-- Set default TACAN channel.
|
-- Get TACAN channel.
|
||||||
local Tacan=squadron:FetchTacan()
|
local Tacan=squadron:FetchTacan()
|
||||||
if Tacan then
|
if Tacan then
|
||||||
flightgroup:SwitchTACAN(Tacan, Morse, UnitName, Band)
|
|
||||||
asset.tacan=Tacan
|
asset.tacan=Tacan
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1617,14 +1616,27 @@ function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request)
|
|||||||
|
|
||||||
-- Add mission to flightgroup queue.
|
-- Add mission to flightgroup queue.
|
||||||
if mission then
|
if mission then
|
||||||
|
|
||||||
|
if Tacan then
|
||||||
|
mission:SetTACAN(Tacan, Morse, UnitName, Band)
|
||||||
|
end
|
||||||
|
|
||||||
-- Add mission to flightgroup queue.
|
-- Add mission to flightgroup queue.
|
||||||
asset.flightgroup:AddMission(mission)
|
asset.flightgroup:AddMission(mission)
|
||||||
|
|
||||||
-- Trigger event.
|
-- Trigger event.
|
||||||
self:FlightOnMission(flightgroup, mission)
|
self:FlightOnMission(flightgroup, mission)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if Tacan then
|
||||||
|
flightgroup:SwitchTACAN(Tacan, Morse, UnitName, Band)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Add group to the detection set of the WINGCOMMANDER.
|
-- Add group to the detection set of the WINGCOMMANDER.
|
||||||
if self.wingcommander and self.wingcommander.chief then
|
if self.wingcommander and self.wingcommander.chief then
|
||||||
self.wingcommander.chief.detectionset:AddGroup(asset.flightgroup.group)
|
self.wingcommander.chief.detectionset:AddGroup(asset.flightgroup.group)
|
||||||
|
|||||||
@ -150,8 +150,6 @@ function CHIEF:New(AgentSet, Coalition)
|
|||||||
BASE:TraceClass(self.ClassName)
|
BASE:TraceClass(self.ClassName)
|
||||||
BASE:TraceLevel(1)
|
BASE:TraceLevel(1)
|
||||||
end
|
end
|
||||||
self.Debug=true
|
|
||||||
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -427,7 +425,7 @@ function CHIEF:onafterStatus(From, Event, To)
|
|||||||
mission.nassets=1
|
mission.nassets=1
|
||||||
|
|
||||||
-- Missons are repeated max 3 times on failure.
|
-- Missons are repeated max 3 times on failure.
|
||||||
mission.missionRepeatMax=3
|
mission.NrepeatFailure=3
|
||||||
|
|
||||||
-- Set mission contact.
|
-- Set mission contact.
|
||||||
contact.mission=mission
|
contact.mission=mission
|
||||||
|
|||||||
@ -18,13 +18,17 @@
|
|||||||
-- @field #string lid Class id string for output to DCS log file.
|
-- @field #string lid Class id string for output to DCS log file.
|
||||||
-- @field #number coalition Coalition side number, e.g. `coalition.side.RED`.
|
-- @field #number coalition Coalition side number, e.g. `coalition.side.RED`.
|
||||||
-- @field #string alias Name of the agency.
|
-- @field #string alias Name of the agency.
|
||||||
-- @field #table filterCategory Category filters.
|
-- @field Core.Set#SET_GROUP detectionset Set of detection groups, aka agents.
|
||||||
|
-- @field #table filterCategory Filter for unit categories.
|
||||||
|
-- @field #table filterCategoryGroup Filter for group categories.
|
||||||
-- @field Core.Set#SET_ZONE acceptzoneset Set of accept zones. If defined, only contacts in these zones are considered.
|
-- @field Core.Set#SET_ZONE acceptzoneset Set of accept zones. If defined, only contacts in these zones are considered.
|
||||||
-- @field Core.Set#SET_ZONE rejectzoneset Set of reject zones. Contacts in these zones are not considered, even if they are in accept zones.
|
-- @field Core.Set#SET_ZONE rejectzoneset Set of reject zones. Contacts in these zones are not considered, even if they are in accept zones.
|
||||||
-- @field #table Contacts Table of detected items.
|
-- @field #table Contacts Table of detected items.
|
||||||
-- @field #table ContactsLost Table of lost detected items.
|
-- @field #table ContactsLost Table of lost detected items.
|
||||||
-- @field #table ContactsUnknown Table of new detected items.
|
-- @field #table ContactsUnknown Table of new detected items.
|
||||||
-- @field #table Clusters Clusters of detected groups.
|
-- @field #table Clusters Clusters of detected groups.
|
||||||
|
-- @field #boolean clusteranalysis If true, create clusters of detected targets.
|
||||||
|
-- @field #boolean clustermarkers If true, create cluster markers on F10 map.
|
||||||
-- @field #number clustercounter Running number of clusters.
|
-- @field #number clustercounter Running number of clusters.
|
||||||
-- @field #number dTforget Time interval in seconds before a known contact which is not detected any more is forgotten.
|
-- @field #number dTforget Time interval in seconds before a known contact which is not detected any more is forgotten.
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
@ -188,7 +192,6 @@ function INTEL:New(DetectionSet, Coalition)
|
|||||||
BASE:TraceClass(self.ClassName)
|
BASE:TraceClass(self.ClassName)
|
||||||
BASE:TraceLevel(1)
|
BASE:TraceLevel(1)
|
||||||
end
|
end
|
||||||
self.Debug=true
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -241,6 +244,7 @@ function INTEL:SetFilterCategory(Categories)
|
|||||||
if type(Categories)~="table" then
|
if type(Categories)~="table" then
|
||||||
Categories={Categories}
|
Categories={Categories}
|
||||||
end
|
end
|
||||||
|
|
||||||
self.filterCategory=Categories
|
self.filterCategory=Categories
|
||||||
|
|
||||||
local text="Filter categories: "
|
local text="Filter categories: "
|
||||||
@ -261,7 +265,7 @@ end
|
|||||||
-- * Group.Category.TRAIN
|
-- * Group.Category.TRAIN
|
||||||
--
|
--
|
||||||
-- @param #INTEL self
|
-- @param #INTEL self
|
||||||
-- @param #table Categories Filter categories, e.g. {Group.Category.AIRPLANE, Group.Category.HELICOPTER}.
|
-- @param #table GroupCategories Filter categories, e.g. `{Group.Category.AIRPLANE, Group.Category.HELICOPTER}`.
|
||||||
-- @return #INTEL self
|
-- @return #INTEL self
|
||||||
function INTEL:FilterCategoryGroup(GroupCategories)
|
function INTEL:FilterCategoryGroup(GroupCategories)
|
||||||
if type(GroupCategories)~="table" then
|
if type(GroupCategories)~="table" then
|
||||||
@ -279,6 +283,17 @@ function INTEL:FilterCategoryGroup(GroupCategories)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Enable or disable cluster analysis of detected targets.
|
||||||
|
-- Targets will be grouped in coupled clusters.
|
||||||
|
-- @param #INTEL self
|
||||||
|
-- @param #boolean Switch If true, enable cluster analysis.
|
||||||
|
-- @param #boolean Markers If true, place markers on F10 map.
|
||||||
|
-- @return #INTEL self
|
||||||
|
function INTEL:SetClusterAnalysis(Switch, Markers)
|
||||||
|
self.clusteranalysis=Switch
|
||||||
|
self.clustermarkers=Markers
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Start & Status
|
-- Start & Status
|
||||||
@ -320,12 +335,14 @@ function INTEL:onafterStatus(From, Event, To)
|
|||||||
local Ncontacts=#self.Contacts
|
local Ncontacts=#self.Contacts
|
||||||
|
|
||||||
-- Short info.
|
-- Short info.
|
||||||
local text=string.format("Status %s [Agents=%s]: Contacts=%d, New=%d, Lost=%d", fsmstate, self.detectionset:CountAlive(), Ncontacts, #self.ContactsUnknown, #self.ContactsLost)
|
if self.verbose>=1 then
|
||||||
self:I(self.lid..text)
|
local text=string.format("Status %s [Agents=%s]: Contacts=%d, New=%d, Lost=%d", fsmstate, self.detectionset:CountAlive(), Ncontacts, #self.ContactsUnknown, #self.ContactsLost)
|
||||||
|
self:I(self.lid..text)
|
||||||
|
end
|
||||||
|
|
||||||
-- Detailed info.
|
-- Detailed info.
|
||||||
if Ncontacts>0 then
|
if self.verbose>=2 and Ncontacts>0 then
|
||||||
text="Detected Contacts:"
|
local text="Detected Contacts:"
|
||||||
for _,_contact in pairs(self.Contacts) do
|
for _,_contact in pairs(self.Contacts) do
|
||||||
local contact=_contact --#INTEL.Contact
|
local contact=_contact --#INTEL.Contact
|
||||||
local dT=timer.getAbsTime()-contact.Tdetected
|
local dT=timer.getAbsTime()-contact.Tdetected
|
||||||
@ -347,28 +364,29 @@ end
|
|||||||
function INTEL:UpdateIntel()
|
function INTEL:UpdateIntel()
|
||||||
|
|
||||||
-- Set of all detected units.
|
-- Set of all detected units.
|
||||||
local DetectedSet=SET_UNIT:New()
|
local DetectedUnits={}
|
||||||
|
|
||||||
-- Loop over all units providing intel.
|
-- Loop over all units providing intel.
|
||||||
for _,_group in pairs(self.detectionset:GetSet()) do
|
for _,_group in pairs(self.detectionset.Set or {}) do
|
||||||
local group=_group --Wrapper.Group#GROUP
|
local group=_group --Wrapper.Group#GROUP
|
||||||
|
|
||||||
if group and group:IsAlive() then
|
if group and group:IsAlive() then
|
||||||
|
|
||||||
for _,_recce in pairs(group:GetUnits()) do
|
for _,_recce in pairs(group:GetUnits()) do
|
||||||
local recce=_recce --Wrapper.Unit#UNIT
|
local recce=_recce --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
-- Get set of detected units.
|
-- Get detected units.
|
||||||
local detectedunitset=recce:GetDetectedUnitSet()
|
self:GetDetectedUnits(recce, DetectedUnits)
|
||||||
|
|
||||||
-- Add detected units to all set.
|
|
||||||
DetectedSet=DetectedSet:GetSetUnion(detectedunitset)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Filter units from reject zones.
|
-- TODO: Filter units from reject zones.
|
||||||
-- TODO: Filter detection methods?
|
-- TODO: Filter detection methods?
|
||||||
local remove={}
|
local remove={}
|
||||||
for _,_unit in pairs(DetectedSet.Set) do
|
for unitname,_unit in pairs(DetectedUnits) do
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
-- Check if unit is in any of the accept zones.
|
-- Check if unit is in any of the accept zones.
|
||||||
@ -384,7 +402,7 @@ function INTEL:UpdateIntel()
|
|||||||
|
|
||||||
-- Unit is not in accept zone ==> remove!
|
-- Unit is not in accept zone ==> remove!
|
||||||
if not inzone then
|
if not inzone then
|
||||||
table.insert(remove, unit:GetName())
|
table.insert(remove, unitname)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -399,8 +417,8 @@ function INTEL:UpdateIntel()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not keepit then
|
if not keepit then
|
||||||
self:I(self.lid..string.format("Removing unit %s category=%d", unit:GetName(), unit:GetCategory()))
|
self:I(self.lid..string.format("Removing unit %s category=%d", unitname, unit:GetCategory()))
|
||||||
table.insert(remove, unit:GetName())
|
table.insert(remove, unitname)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -408,14 +426,26 @@ function INTEL:UpdateIntel()
|
|||||||
|
|
||||||
-- Remove filtered units.
|
-- Remove filtered units.
|
||||||
for _,unitname in pairs(remove) do
|
for _,unitname in pairs(remove) do
|
||||||
DetectedSet:Remove(unitname, true)
|
DetectedUnits[unitname]=nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create detected groups.
|
||||||
|
local DetectedGroups={}
|
||||||
|
for unitname,_unit in pairs(DetectedUnits) do
|
||||||
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
local group=unit:GetGroup()
|
||||||
|
if group then
|
||||||
|
DetectedGroups[group:GetName()]=group
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Create detected contacts.
|
-- Create detected contacts.
|
||||||
self:CreateDetectedItems(DetectedSet)
|
self:CreateDetectedItems(DetectedGroups)
|
||||||
|
|
||||||
-- Paint a picture of the battlefield.
|
-- Paint a picture of the battlefield.
|
||||||
self:PaintPicture()
|
if self.clusteranalysis then
|
||||||
|
self:PaintPicture()
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -425,32 +455,15 @@ end
|
|||||||
|
|
||||||
--- Create detected items.
|
--- Create detected items.
|
||||||
-- @param #INTEL self
|
-- @param #INTEL self
|
||||||
-- @param Core.Set#SET_UNIT detectedunitset Set of detected units.
|
-- @param #table DetectedGroups Table of detected Groups
|
||||||
function INTEL:CreateDetectedItems(detectedunitset)
|
function INTEL:CreateDetectedItems(DetectedGroups)
|
||||||
|
|
||||||
local detectedgroupset=SET_GROUP:New()
|
|
||||||
|
|
||||||
-- Convert detected UNIT set to detected GROUP set.
|
|
||||||
for _,_unit in pairs(detectedunitset:GetSet()) do
|
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
local group=unit:GetGroup()
|
|
||||||
|
|
||||||
if group and group:IsAlive() then
|
|
||||||
local groupname=group:GetName()
|
|
||||||
detectedgroupset:Add(groupname, group)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Current time.
|
-- Current time.
|
||||||
local Tnow=timer.getAbsTime()
|
local Tnow=timer.getAbsTime()
|
||||||
|
|
||||||
for _,_group in pairs(detectedgroupset.Set) do
|
for groupname,_group in pairs(DetectedGroups) do
|
||||||
local group=_group --Wrapper.Group#GROUP
|
local group=_group --Wrapper.Group#GROUP
|
||||||
|
|
||||||
-- Group name.
|
|
||||||
local groupname=group:GetName()
|
|
||||||
|
|
||||||
-- Get contact if already known.
|
-- Get contact if already known.
|
||||||
local detecteditem=self:GetContactByName(groupname)
|
local detecteditem=self:GetContactByName(groupname)
|
||||||
@ -498,8 +511,6 @@ function INTEL:CreateDetectedItems(detectedunitset)
|
|||||||
for i=#self.Contacts,1,-1 do
|
for i=#self.Contacts,1,-1 do
|
||||||
local item=self.Contacts[i] --#INTEL.Contact
|
local item=self.Contacts[i] --#INTEL.Contact
|
||||||
|
|
||||||
local group=detectedgroupset:FindGroup(item.groupname)
|
|
||||||
|
|
||||||
-- Check if deltaT>Tforget. We dont want quick oscillations between detected and undetected states.
|
-- Check if deltaT>Tforget. We dont want quick oscillations between detected and undetected states.
|
||||||
if self:_CheckContactLost(item) then
|
if self:_CheckContactLost(item) then
|
||||||
|
|
||||||
@ -514,6 +525,41 @@ function INTEL:CreateDetectedItems(detectedunitset)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Return the detected target groups of the controllable as a @{SET_GROUP}.
|
||||||
|
-- The optional parametes specify the detection methods that can be applied.
|
||||||
|
-- If no detection method is given, the detection will use all the available methods by default.
|
||||||
|
-- @param #INTEL self
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The unit detecting.
|
||||||
|
-- @param #boolean DetectVisual (Optional) If *false*, do not include visually detected targets.
|
||||||
|
-- @param #boolean DetectOptical (Optional) If *false*, do not include optically detected targets.
|
||||||
|
-- @param #boolean DetectRadar (Optional) If *false*, do not include targets detected by radar.
|
||||||
|
-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST.
|
||||||
|
-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR.
|
||||||
|
-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link.
|
||||||
|
function INTEL:GetDetectedUnits(Unit, DetectedUnits, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK)
|
||||||
|
|
||||||
|
-- Get detected DCS units.
|
||||||
|
local detectedtargets=Unit:GetDetectedTargets(DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK)
|
||||||
|
|
||||||
|
for DetectionObjectID, Detection in pairs(detectedtargets or {}) do
|
||||||
|
local DetectedObject=Detection.object -- DCS#Object
|
||||||
|
|
||||||
|
if DetectedObject and DetectedObject:isExist() and DetectedObject.id_<50000000 then
|
||||||
|
|
||||||
|
local unit=UNIT:Find(DetectedObject)
|
||||||
|
|
||||||
|
if unit and unit:IsAlive() then
|
||||||
|
|
||||||
|
local unitname=unit:GetName()
|
||||||
|
|
||||||
|
DetectedUnits[unitname]=unit
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- FSM Events
|
-- FSM Events
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -960,7 +1006,7 @@ end
|
|||||||
-- @param #INTEL self
|
-- @param #INTEL self
|
||||||
-- @param #INTEL.Cluster cluster The cluster.
|
-- @param #INTEL.Cluster cluster The cluster.
|
||||||
-- @return #INTEL self
|
-- @return #INTEL self
|
||||||
function INTEL:UpdateClusterMarker(cluster, newcoordinate)
|
function INTEL:UpdateClusterMarker(cluster)
|
||||||
|
|
||||||
-- Create a marker.
|
-- Create a marker.
|
||||||
local text=string.format("Cluster #%d. Size %d, TLsum=%d", cluster.index, cluster.size, cluster.threatlevelSum)
|
local text=string.format("Cluster #%d. Size %d, TLsum=%d", cluster.index, cluster.size, cluster.threatlevelSum)
|
||||||
|
|||||||
@ -449,7 +449,9 @@ AIRBASE.TerminalType = {
|
|||||||
-- @field Core.Point#COORDINATE position Position of runway start.
|
-- @field Core.Point#COORDINATE position Position of runway start.
|
||||||
-- @field Core.Point#COORDINATE endpoint End point of runway.
|
-- @field Core.Point#COORDINATE endpoint End point of runway.
|
||||||
|
|
||||||
-- Registration.
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Registration
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Create a new AIRBASE from DCSAirbase.
|
--- Create a new AIRBASE from DCSAirbase.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
@ -491,6 +493,7 @@ function AIRBASE:Register(AirbaseName)
|
|||||||
self:GetCoordinate()
|
self:GetCoordinate()
|
||||||
|
|
||||||
if vec2 then
|
if vec2 then
|
||||||
|
-- TODO: For ships we need a moving zone.
|
||||||
self.AirbaseZone=ZONE_RADIUS:New( AirbaseName, vec2, 2500 )
|
self.AirbaseZone=ZONE_RADIUS:New( AirbaseName, vec2, 2500 )
|
||||||
else
|
else
|
||||||
self:E(string.format("ERROR: Cound not get position Vec2 of airbase %s", AirbaseName))
|
self:E(string.format("ERROR: Cound not get position Vec2 of airbase %s", AirbaseName))
|
||||||
@ -499,7 +502,9 @@ function AIRBASE:Register(AirbaseName)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reference methods.
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Reference methods
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Finds a AIRBASE from the _DATABASE using a DCSAirbase object.
|
--- Finds a AIRBASE from the _DATABASE using a DCSAirbase object.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
@ -622,6 +627,38 @@ function AIRBASE:GetID(unique)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get category of airbase.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @return #number Category of airbase from GetDesc().category.
|
||||||
|
function AIRBASE:GetAirbaseCategory()
|
||||||
|
return self.category
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if airbase is an airdrome.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @return #boolean If true, airbase is an airdrome.
|
||||||
|
function AIRBASE:IsAirdrome()
|
||||||
|
return self.isAirdrome
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if airbase is a helipad.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @return #boolean If true, airbase is a helipad.
|
||||||
|
function AIRBASE:IsHelipad()
|
||||||
|
return self.isHelipad
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if airbase is a ship.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @return #boolean If true, airbase is a ship.
|
||||||
|
function AIRBASE:IsShip()
|
||||||
|
return self.isShip
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Parking
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Returns a table of parking data for a given airbase. If the optional parameter *available* is true only available parking will be returned, otherwise all parking at the base is returned. Term types have the following enumerated values:
|
--- Returns a table of parking data for a given airbase. If the optional parameter *available* is true only available parking will be returned, otherwise all parking at the base is returned. Term types have the following enumerated values:
|
||||||
--
|
--
|
||||||
-- * 16 : Valid spawn points on runway
|
-- * 16 : Valid spawn points on runway
|
||||||
@ -765,8 +802,10 @@ function AIRBASE:_InitParkingSpots()
|
|||||||
self.parkingByID={}
|
self.parkingByID={}
|
||||||
|
|
||||||
self.NparkingTotal=0
|
self.NparkingTotal=0
|
||||||
self.NparkingX=0
|
self.NparkingTerminal={}
|
||||||
self.NparkingY=0
|
for _,terminalType in pairs(AIRBASE.TerminalType) do
|
||||||
|
self.NparkingTerminal[terminalType]=0
|
||||||
|
end
|
||||||
|
|
||||||
-- Put coordinates of parking spots into table.
|
-- Put coordinates of parking spots into table.
|
||||||
for _,spot in pairs(parkingdata) do
|
for _,spot in pairs(parkingdata) do
|
||||||
@ -782,24 +821,11 @@ function AIRBASE:_InitParkingSpots()
|
|||||||
park.TerminalType=spot.Term_Type
|
park.TerminalType=spot.Term_Type
|
||||||
park.TOAC=spot.TO_AC
|
park.TOAC=spot.TO_AC
|
||||||
|
|
||||||
if park.TerminalID==AIRBASE.TerminalType.FighterAircraft then
|
for _,terminalType in pairs(AIRBASE.TerminalType) do
|
||||||
|
if self._CheckTerminalType(terminalType, park.TerminalType) then
|
||||||
elseif park.TerminalID==AIRBASE.TerminalType.HelicopterOnly then
|
self.NparkingTerminal[terminalType]=self.NparkingTerminal[terminalType]+1
|
||||||
|
end
|
||||||
elseif park.TerminalID==AIRBASE.TerminalType.HelicopterUsable then
|
end
|
||||||
|
|
||||||
elseif park.TerminalID==AIRBASE.TerminalType.OpenBig then
|
|
||||||
|
|
||||||
elseif park.TerminalID==AIRBASE.TerminalType.OpenMed then
|
|
||||||
|
|
||||||
elseif park.TerminalID==AIRBASE.TerminalType.OpenMedOrBig then
|
|
||||||
|
|
||||||
elseif park.TerminalID==AIRBASE.TerminalType.Runway then
|
|
||||||
|
|
||||||
elseif park.TerminalID==AIRBASE.TerminalType.Shelter then
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
self.parkingByID[park.TerminalID]=park
|
self.parkingByID[park.TerminalID]=park
|
||||||
table.insert(self.parking, park)
|
table.insert(self.parking, park)
|
||||||
@ -1134,104 +1160,6 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
|
|||||||
return validspots
|
return validspots
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Function that checks if at leat one unit of a group has been spawned close to a spawn point on the runway.
|
|
||||||
-- @param #AIRBASE self
|
|
||||||
-- @param Wrapper.Group#GROUP group Group to be checked.
|
|
||||||
-- @param #number radius Radius around the spawn point to be checked. Default is 50 m.
|
|
||||||
-- @param #boolean despawn If true, the group is destroyed.
|
|
||||||
-- @return #boolean True if group is within radius around spawn points on runway.
|
|
||||||
function AIRBASE:CheckOnRunWay(group, radius, despawn)
|
|
||||||
|
|
||||||
-- Default radius.
|
|
||||||
radius=radius or 50
|
|
||||||
|
|
||||||
-- We only check at real airbases (not FARPS or ships).
|
|
||||||
if self:GetAirbaseCategory()~=Airbase.Category.AIRDROME then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
if group and group:IsAlive() then
|
|
||||||
|
|
||||||
-- Debug.
|
|
||||||
self:T(string.format("%s, checking if group %s is on runway?",self:GetName(), group:GetName()))
|
|
||||||
|
|
||||||
-- Get coordinates on runway.
|
|
||||||
local runwaypoints=self:GetParkingSpotsCoordinates(AIRBASE.TerminalType.Runway)
|
|
||||||
|
|
||||||
-- Get units of group.
|
|
||||||
local units=group:GetUnits()
|
|
||||||
|
|
||||||
-- Loop over units.
|
|
||||||
for _,_unit in pairs(units) do
|
|
||||||
|
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
-- Check if unit is alive and not in air.
|
|
||||||
if unit and unit:IsAlive() and not unit:InAir() then
|
|
||||||
self:T(string.format("%s, checking if unit %s is on runway?",self:GetName(), unit:GetName()))
|
|
||||||
|
|
||||||
-- Loop over runway spawn points.
|
|
||||||
for _i,_coord in pairs(runwaypoints) do
|
|
||||||
|
|
||||||
-- Distance between unit and spawn pos.
|
|
||||||
local dist=unit:GetCoordinate():Get2DDistance(_coord)
|
|
||||||
|
|
||||||
-- Mark unit spawn points for debugging.
|
|
||||||
--unit:GetCoordinate():MarkToAll(string.format("unit %s distance to rwy %d = %d",unit:GetName(),_i, dist))
|
|
||||||
|
|
||||||
-- Check if unit is withing radius.
|
|
||||||
if dist<radius then
|
|
||||||
self:E(string.format("%s, unit %s of group %s was spawned on runway #%d. Distance %.1f < radius %.1f m. Despawn = %s.", self:GetName(), unit:GetName(), group:GetName(),_i, dist, radius, tostring(despawn)))
|
|
||||||
--unit:FlareRed()
|
|
||||||
if despawn then
|
|
||||||
group:Destroy(true)
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
self:T(string.format("%s, unit %s of group %s was NOT spawned on runway #%d. Distance %.1f > radius %.1f m. Despawn = %s.", self:GetName(), unit:GetName(), group:GetName(),_i, dist, radius, tostring(despawn)))
|
|
||||||
--unit:FlareGreen()
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self:T(string.format("%s, checking if unit %s of group %s is on runway. Unit is NOT alive.",self:GetName(), unit:GetName(), group:GetName()))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self:T(string.format("%s, checking if group %s is on runway. Group is NOT alive.",self:GetName(), group:GetName()))
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Check if airbase is an airdrome.
|
|
||||||
-- @param #AIRBASE self
|
|
||||||
-- @return #boolean If true, airbase is an airdrome.
|
|
||||||
function AIRBASE:IsAirdrome()
|
|
||||||
return self.isAirdrome
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Check if airbase is a helipad.
|
|
||||||
-- @param #AIRBASE self
|
|
||||||
-- @return #boolean If true, airbase is a helipad.
|
|
||||||
function AIRBASE:IsHelipad()
|
|
||||||
return self.isHelipad
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Check if airbase is a ship.
|
|
||||||
-- @param #AIRBASE self
|
|
||||||
-- @return #boolean If true, airbase is a ship.
|
|
||||||
function AIRBASE:IsShip()
|
|
||||||
return self.isShip
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get category of airbase.
|
|
||||||
-- @param #AIRBASE self
|
|
||||||
-- @return #number Category of airbase from GetDesc().category.
|
|
||||||
function AIRBASE:GetAirbaseCategory()
|
|
||||||
return self.category
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Helper function to check for the correct terminal type including "artificial" ones.
|
--- Helper function to check for the correct terminal type including "artificial" ones.
|
||||||
-- @param #number Term_Type Termial type from getParking routine.
|
-- @param #number Term_Type Termial type from getParking routine.
|
||||||
-- @param #AIRBASE.TerminalType termtype Terminal type from AIRBASE.TerminalType enumerator.
|
-- @param #AIRBASE.TerminalType termtype Terminal type from AIRBASE.TerminalType enumerator.
|
||||||
@ -1278,6 +1206,10 @@ function AIRBASE._CheckTerminalType(Term_Type, termtype)
|
|||||||
return match
|
return match
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Runway
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Get runways data. Only for airdromes!
|
--- Get runways data. Only for airdromes!
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
-- @param #number magvar (Optional) Magnetic variation in degrees.
|
-- @param #number magvar (Optional) Magnetic variation in degrees.
|
||||||
@ -1507,3 +1439,73 @@ function AIRBASE:GetActiveRunway(magvar)
|
|||||||
|
|
||||||
return runways[iact]
|
return runways[iact]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Function that checks if at leat one unit of a group has been spawned close to a spawn point on the runway.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param Wrapper.Group#GROUP group Group to be checked.
|
||||||
|
-- @param #number radius Radius around the spawn point to be checked. Default is 50 m.
|
||||||
|
-- @param #boolean despawn If true, the group is destroyed.
|
||||||
|
-- @return #boolean True if group is within radius around spawn points on runway.
|
||||||
|
function AIRBASE:CheckOnRunWay(group, radius, despawn)
|
||||||
|
|
||||||
|
-- Default radius.
|
||||||
|
radius=radius or 50
|
||||||
|
|
||||||
|
-- We only check at real airbases (not FARPS or ships).
|
||||||
|
if self:GetAirbaseCategory()~=Airbase.Category.AIRDROME then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if group and group:IsAlive() then
|
||||||
|
|
||||||
|
-- Debug.
|
||||||
|
self:T(string.format("%s, checking if group %s is on runway?",self:GetName(), group:GetName()))
|
||||||
|
|
||||||
|
-- Get coordinates on runway.
|
||||||
|
local runwaypoints=self:GetParkingSpotsCoordinates(AIRBASE.TerminalType.Runway)
|
||||||
|
|
||||||
|
-- Get units of group.
|
||||||
|
local units=group:GetUnits()
|
||||||
|
|
||||||
|
-- Loop over units.
|
||||||
|
for _,_unit in pairs(units) do
|
||||||
|
|
||||||
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
-- Check if unit is alive and not in air.
|
||||||
|
if unit and unit:IsAlive() and not unit:InAir() then
|
||||||
|
self:T(string.format("%s, checking if unit %s is on runway?",self:GetName(), unit:GetName()))
|
||||||
|
|
||||||
|
-- Loop over runway spawn points.
|
||||||
|
for _i,_coord in pairs(runwaypoints) do
|
||||||
|
|
||||||
|
-- Distance between unit and spawn pos.
|
||||||
|
local dist=unit:GetCoordinate():Get2DDistance(_coord)
|
||||||
|
|
||||||
|
-- Mark unit spawn points for debugging.
|
||||||
|
--unit:GetCoordinate():MarkToAll(string.format("unit %s distance to rwy %d = %d",unit:GetName(),_i, dist))
|
||||||
|
|
||||||
|
-- Check if unit is withing radius.
|
||||||
|
if dist<radius then
|
||||||
|
self:E(string.format("%s, unit %s of group %s was spawned on runway #%d. Distance %.1f < radius %.1f m. Despawn = %s.", self:GetName(), unit:GetName(), group:GetName(),_i, dist, radius, tostring(despawn)))
|
||||||
|
--unit:FlareRed()
|
||||||
|
if despawn then
|
||||||
|
group:Destroy(true)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
self:T(string.format("%s, unit %s of group %s was NOT spawned on runway #%d. Distance %.1f > radius %.1f m. Despawn = %s.", self:GetName(), unit:GetName(), group:GetName(),_i, dist, radius, tostring(despawn)))
|
||||||
|
--unit:FlareGreen()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:T(string.format("%s, checking if unit %s of group %s is on runway. Unit is NOT alive.",self:GetName(), unit:GetName(), group:GetName()))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:T(string.format("%s, checking if group %s is on runway. Group is NOT alive.",self:GetName(), group:GetName()))
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user