mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-08-07 14:34:23 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 92bc0389d3 | |||
| 7a5f6ad3c6 | |||
| 2a73d8d34a | |||
| e8f5214e0b | |||
| e4c7e809cb | |||
| aab16dd966 | |||
| 8b356f0913 | |||
| c3086b0265 | |||
| 599a2ba6fb |
@@ -92,6 +92,8 @@ DATABASE = {
|
|||||||
ZONES_GOAL = {},
|
ZONES_GOAL = {},
|
||||||
WAREHOUSES = {},
|
WAREHOUSES = {},
|
||||||
FLIGHTGROUPS = {},
|
FLIGHTGROUPS = {},
|
||||||
|
COHORTS={},
|
||||||
|
LEGIONS={},
|
||||||
FLIGHTCONTROLS = {},
|
FLIGHTCONTROLS = {},
|
||||||
OPSZONES = {},
|
OPSZONES = {},
|
||||||
PATHLINES = {},
|
PATHLINES = {},
|
||||||
@@ -2087,6 +2089,40 @@ function DATABASE:FindOpsGroupFromUnit(unitname)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
--- Add an OPS COHORT (SQUADRON, PLATOON, FLOTILLA) to the data base.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param Ops.Cohort#COHORT cohort The cohort added to the DB.
|
||||||
|
function DATABASE:AddCohort(cohort)
|
||||||
|
self.COHORTS[cohort.name]=cohort
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Find an OPS COHORT (SQUADRON, PLATOON, FLOTILLA) in the data base.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param #string cohortname Name of the cohort.
|
||||||
|
-- @return Ops.Cohort#COHORT Cohort object.
|
||||||
|
function DATABASE:FindCohort(cohortname)
|
||||||
|
return self.COHORTS[cohortname]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add an OPS LEGION (AIRWING, BRIGADE, FLEET) to the data base.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param Ops.Legion#LEGION legion The legion added to the DB.
|
||||||
|
function DATABASE:AddLegion(legion)
|
||||||
|
self.LEGIONS[legion.alias]=legion
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Find an OPS LEGION (AIRWING, BRIGADE, FLEET) in the data base.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param #string legionname Name of the legion.
|
||||||
|
-- @return Ops.Legion#LEGION Legion object.
|
||||||
|
function DATABASE:FindLegion(legionname)
|
||||||
|
return self.LEGIONS[legionname]
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
--- Add a flight control to the data base.
|
--- Add a flight control to the data base.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param OPS.FlightControl#FLIGHTCONTROL flightcontrol
|
-- @param OPS.FlightControl#FLIGHTCONTROL flightcontrol
|
||||||
|
|||||||
@@ -0,0 +1,292 @@
|
|||||||
|
--- **Ops** - Passive strategic territory.
|
||||||
|
--
|
||||||
|
-- **Main Features:**
|
||||||
|
--
|
||||||
|
-- * Associate a static MOOSE zone with a coalition
|
||||||
|
-- * Keep strategic territory geometry separate from OPSZONE scanning
|
||||||
|
-- * Register territories in the MOOSE database
|
||||||
|
-- * Delegate coordinate checks and F10 drawing to the underlying zone
|
||||||
|
--
|
||||||
|
-- A TERRITORY is deliberately passive. It does not scan DCS objects, evaluate
|
||||||
|
-- ownership, run a scheduler, or make tactical or strategic decisions.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module Ops.Territory
|
||||||
|
|
||||||
|
|
||||||
|
--- TERRITORY class.
|
||||||
|
-- @type TERRITORY
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #string version Class version.
|
||||||
|
-- @field #number verbose Verbosity level.
|
||||||
|
-- @field #string lid Log ID string.
|
||||||
|
-- @field #string name Unique territory name.
|
||||||
|
-- @field #string zoneName Name of the underlying MOOSE zone.
|
||||||
|
-- @field Core.Zone#ZONE_BASE zone Underlying MOOSE zone.
|
||||||
|
-- @field #number coalition Coalition associated with the territory.
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
--- A passive strategic area defined by an existing MOOSE zone.
|
||||||
|
--
|
||||||
|
-- TERRITORY contains geometry and declarative ownership only. Unlike
|
||||||
|
-- @{Ops.OpsZone#OPSZONE}, it performs no periodic object scans and has no FSM.
|
||||||
|
--
|
||||||
|
-- @field #TERRITORY
|
||||||
|
TERRITORY = {
|
||||||
|
ClassName = "TERRITORY",
|
||||||
|
verbose = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- TERRITORY class version.
|
||||||
|
-- @field #string version
|
||||||
|
TERRITORY.version = "0.1.0"
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- DATABASE extension
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Finds a TERRITORY based on its name.
|
||||||
|
-- @param Core.Database#DATABASE self
|
||||||
|
-- @param #string TerritoryName Name of the territory.
|
||||||
|
-- @return #TERRITORY The found territory or `nil`.
|
||||||
|
function DATABASE:FindTerritory(TerritoryName)
|
||||||
|
local territories = self.TERRITORIES or {}
|
||||||
|
return territories[TerritoryName]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Adds a TERRITORY to the database.
|
||||||
|
-- @param Core.Database#DATABASE self
|
||||||
|
-- @param #TERRITORY Territory Territory to add.
|
||||||
|
-- @return #TERRITORY The registered territory or `nil`.
|
||||||
|
function DATABASE:AddTerritory(Territory)
|
||||||
|
if not Territory then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
self.TERRITORIES = self.TERRITORIES or {}
|
||||||
|
|
||||||
|
local territoryName = Territory:GetName()
|
||||||
|
if not self.TERRITORIES[territoryName] then
|
||||||
|
self.TERRITORIES[territoryName] = Territory
|
||||||
|
end
|
||||||
|
|
||||||
|
return self.TERRITORIES[territoryName]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Deletes a TERRITORY from the database.
|
||||||
|
-- @param Core.Database#DATABASE self
|
||||||
|
-- @param #string TerritoryName Name of the territory.
|
||||||
|
-- @return Core.Database#DATABASE self
|
||||||
|
function DATABASE:DeleteTerritory(TerritoryName)
|
||||||
|
if self.TERRITORIES then
|
||||||
|
self.TERRITORIES[TerritoryName] = nil
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new TERRITORY class object.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @param Core.Zone#ZONE_BASE Zone The underlying MOOSE zone or its Mission Editor name.
|
||||||
|
-- @param #number Coalition (Optional) Associated coalition. Default `coalition.side.NEUTRAL`.
|
||||||
|
-- @param #string Name (Optional) Unique territory name. Default is the zone name.
|
||||||
|
-- @return #TERRITORY self
|
||||||
|
-- @usage
|
||||||
|
-- local north = TERRITORY:New("Territory North", coalition.side.BLUE)
|
||||||
|
-- local southZone = ZONE:FindByName("Territory South")
|
||||||
|
-- local south = TERRITORY:New(southZone, coalition.side.RED, "Southern Territory")
|
||||||
|
function TERRITORY:New(Zone, Coalition, Name)
|
||||||
|
|
||||||
|
-- Inherit everything from BASE class.
|
||||||
|
local self = BASE:Inherit(self, BASE:New()) -- #TERRITORY
|
||||||
|
|
||||||
|
-- Resolve a Mission Editor zone name.
|
||||||
|
if type(Zone) == "string" then
|
||||||
|
local zoneName = Zone
|
||||||
|
Zone = ZONE:FindByName(zoneName)
|
||||||
|
if not Zone then
|
||||||
|
self:E(string.format("ERROR: No ZONE found for name: %s", tostring(zoneName)))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
elseif not Zone then
|
||||||
|
self:E("ERROR: First parameter Zone is nil in TERRITORY:New(Zone) call!")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- A territory relies only on the common ZONE_BASE interface.
|
||||||
|
if type(Zone.GetName) ~= "function"
|
||||||
|
or type(Zone.GetCoordinate) ~= "function"
|
||||||
|
or type(Zone.IsCoordinateInZone) ~= "function" then
|
||||||
|
self:E("ERROR: TERRITORY requires a ZONE_BASE derived object!")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local zoneName = Zone:GetName()
|
||||||
|
local territoryName = Name or zoneName
|
||||||
|
if type(territoryName) ~= "string" or territoryName == "" then
|
||||||
|
self:E("ERROR: TERRITORY requires a non-empty name!")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
self.zone = Zone
|
||||||
|
self.zoneName = zoneName
|
||||||
|
self.name = territoryName
|
||||||
|
self.lid = string.format("TERRITORY %s | ", territoryName)
|
||||||
|
|
||||||
|
if not self:SetCoalition(Coalition or coalition.side.NEUTRAL) then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Register in the MOOSE database.
|
||||||
|
_DATABASE:AddTerritory(self)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Set functions
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Set the coalition associated with this territory.
|
||||||
|
-- This method only changes declarative ownership. It does not evaluate DCS
|
||||||
|
-- units or trigger any capture logic.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @param #number Coalition Coalition side number.
|
||||||
|
-- @return #TERRITORY self or `nil` if the coalition is invalid.
|
||||||
|
function TERRITORY:SetCoalition(Coalition)
|
||||||
|
if Coalition ~= coalition.side.NEUTRAL
|
||||||
|
and Coalition ~= coalition.side.RED
|
||||||
|
and Coalition ~= coalition.side.BLUE then
|
||||||
|
self:E(self.lid .. string.format("ERROR: Invalid coalition: %s", tostring(Coalition)))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
self.coalition = Coalition
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Get functions
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Find a TERRITORY by name.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @param #string Name Name of the territory.
|
||||||
|
-- @return #TERRITORY The found territory or `nil`.
|
||||||
|
function TERRITORY:FindByName(Name)
|
||||||
|
return _DATABASE:FindTerritory(Name)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the territory name.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @return #string Territory name.
|
||||||
|
function TERRITORY:GetName()
|
||||||
|
return self.name
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the underlying zone name.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @return #string Zone name.
|
||||||
|
function TERRITORY:GetZoneName()
|
||||||
|
return self.zoneName
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the underlying MOOSE zone.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @return Core.Zone#ZONE_BASE The underlying zone.
|
||||||
|
function TERRITORY:GetZone()
|
||||||
|
return self.zone
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the territory center coordinate.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @return Core.Point#COORDINATE Territory center coordinate.
|
||||||
|
function TERRITORY:GetCoordinate()
|
||||||
|
return self.zone:GetCoordinate()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the coalition associated with the territory.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @return #number Coalition side number.
|
||||||
|
function TERRITORY:GetCoalition()
|
||||||
|
return self.coalition
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the name of the coalition associated with the territory.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @return #string Coalition name.
|
||||||
|
function TERRITORY:GetCoalitionName()
|
||||||
|
return UTILS.GetCoalitionName(self.coalition)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the owner of the territory.
|
||||||
|
-- This is an alias for @{#TERRITORY.GetCoalition}.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @return #number Coalition side number.
|
||||||
|
function TERRITORY:GetOwner()
|
||||||
|
return self:GetCoalition()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the owner coalition name.
|
||||||
|
-- This is an alias for @{#TERRITORY.GetCoalitionName}.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @return #string Coalition name.
|
||||||
|
function TERRITORY:GetOwnerName()
|
||||||
|
return self:GetCoalitionName()
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Zone functions
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Test whether a coordinate lies inside the territory.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate Coordinate to test.
|
||||||
|
-- @return #boolean `true` if the coordinate lies inside the territory.
|
||||||
|
function TERRITORY:ContainsCoordinate(Coordinate)
|
||||||
|
return self.zone:IsCoordinateInZone(Coordinate)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Test whether a Vec2 lies inside the territory.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @param DCS#Vec2 Vec2 Vec2 to test.
|
||||||
|
-- @return #boolean `true` if the Vec2 lies inside the territory.
|
||||||
|
function TERRITORY:ContainsVec2(Vec2)
|
||||||
|
return self.zone:IsVec2InZone(Vec2)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Draw the territory on the F10 map.
|
||||||
|
-- Drawing is delegated to the underlying MOOSE zone.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @param #number Coalition (Optional) Coalition visibility. Default `-1` for all.
|
||||||
|
-- @param #table Color (Optional) RGB line color.
|
||||||
|
-- @param #number Alpha (Optional) Line alpha.
|
||||||
|
-- @param #table FillColor (Optional) RGB fill color.
|
||||||
|
-- @param #number FillAlpha (Optional) Fill alpha.
|
||||||
|
-- @param #number LineType (Optional) DCS line type.
|
||||||
|
-- @return #TERRITORY self
|
||||||
|
function TERRITORY:Draw(Coalition, Color, Alpha, FillColor, FillAlpha, LineType)
|
||||||
|
self.zone:DrawZone(Coalition, Color, Alpha, FillColor, FillAlpha, LineType)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove the territory drawing from the F10 map.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @return #TERRITORY self
|
||||||
|
function TERRITORY:Undraw()
|
||||||
|
self.zone:UndrawZone()
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove the territory from the MOOSE database.
|
||||||
|
-- The underlying zone is not deleted.
|
||||||
|
-- @param #TERRITORY self
|
||||||
|
-- @return #TERRITORY self
|
||||||
|
function TERRITORY:Remove()
|
||||||
|
_DATABASE:DeleteTerritory(self.name)
|
||||||
|
return self
|
||||||
|
end
|
||||||
@@ -79,6 +79,7 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Tiresias.lua' )
|
|||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Stratego.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Stratego.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/ClientWatch.lua')
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/ClientWatch.lua')
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Formation.lua')
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Formation.lua')
|
||||||
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Territory.lua')
|
||||||
|
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Airboss.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Airboss.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/RecoveryTanker.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/RecoveryTanker.lua' )
|
||||||
|
|||||||
@@ -290,6 +290,9 @@ function AIRWING:New(warehousename, airwingname)
|
|||||||
-- @param Ops.FlightGroup#FLIGHTGROUP FlightGroup The FLIGHTGROUP on mission.
|
-- @param Ops.FlightGroup#FLIGHTGROUP FlightGroup The FLIGHTGROUP on mission.
|
||||||
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
|
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
|
||||||
|
|
||||||
|
-- Add legion to DB
|
||||||
|
_DATABASE:AddLegion(self)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -541,6 +544,47 @@ function AIRWING:AddPayloadCapability(Payload, MissionTypes, Performance)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Filter available payloads for a given aircraft type and mission type.
|
||||||
|
-- @param #AIRWING self
|
||||||
|
-- @param #string UnitType The type of the unit.
|
||||||
|
-- @param #string MissionType The mission type.
|
||||||
|
-- @param #table Payloads Specific payloads only to be considered.
|
||||||
|
-- @return #AIRWING.Payload Payload table or *nil*.
|
||||||
|
function AIRWING:_FilterPlayloads(UnitType, MissionType, Payloads)
|
||||||
|
|
||||||
|
local function _checkPayloads(payload)
|
||||||
|
if Payloads then
|
||||||
|
for _,Payload in pairs(Payloads) do
|
||||||
|
if Payload.uid==payload.uid then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Payload was not specified.
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Pre-selection: filter out only those payloads that are valid for the airframe and mission type and are available.
|
||||||
|
local payloads={}
|
||||||
|
|
||||||
|
for _,_payload in pairs(self.payloads) do
|
||||||
|
local payload=_payload --#AIRWING.Payload
|
||||||
|
|
||||||
|
local specialpayload=_checkPayloads(payload)
|
||||||
|
local compatible=AUFTRAG.CheckMissionCapability(MissionType, payload.capabilities)
|
||||||
|
|
||||||
|
local goforit = specialpayload or (specialpayload==nil and compatible)
|
||||||
|
|
||||||
|
if payload.aircrafttype==UnitType and payload.navail>0 and goforit then
|
||||||
|
table.insert(payloads, payload)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return payloads
|
||||||
|
end
|
||||||
|
|
||||||
--- Fetch a payload from the airwing resources for a given unit and mission type.
|
--- Fetch a payload from the airwing resources for a given unit and mission type.
|
||||||
-- The payload with the highest priority is preferred.
|
-- The payload with the highest priority is preferred.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
@@ -589,34 +633,7 @@ function AIRWING:FetchPayloadFromStock(UnitType, MissionType, Payloads)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function _checkPayloads(payload)
|
local payloads=self:_FilterPlayloads(UnitType, MissionType, Payloads)
|
||||||
if Payloads then
|
|
||||||
for _,Payload in pairs(Payloads) do
|
|
||||||
if Payload.uid==payload.uid then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Payload was not specified.
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Pre-selection: filter out only those payloads that are valid for the airframe and mission type and are available.
|
|
||||||
local payloads={}
|
|
||||||
for _,_payload in pairs(self.payloads) do
|
|
||||||
local payload=_payload --#AIRWING.Payload
|
|
||||||
|
|
||||||
local specialpayload=_checkPayloads(payload)
|
|
||||||
local compatible=AUFTRAG.CheckMissionCapability(MissionType, payload.capabilities)
|
|
||||||
|
|
||||||
local goforit = specialpayload or (specialpayload==nil and compatible)
|
|
||||||
|
|
||||||
if payload.aircrafttype==UnitType and payload.navail>0 and goforit then
|
|
||||||
table.insert(payloads, payload)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Debug.
|
-- Debug.
|
||||||
if self.verbose>=4 then
|
if self.verbose>=4 then
|
||||||
|
|||||||
@@ -192,6 +192,8 @@
|
|||||||
-- @field #boolean optionInvisible Invisible is on/off.
|
-- @field #boolean optionInvisible Invisible is on/off.
|
||||||
-- @field #boolean optionImmortal Immortal is on/off.
|
-- @field #boolean optionImmortal Immortal is on/off.
|
||||||
--
|
--
|
||||||
|
-- @field #AUFTRAG.Summary summary Auftrag summary.
|
||||||
|
--
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- *A warrior's mission is to foster the success of others.* -- Morihei Ueshiba
|
--- *A warrior's mission is to foster the success of others.* -- Morihei Ueshiba
|
||||||
@@ -656,6 +658,19 @@ AUFTRAG.Category={
|
|||||||
-- @field #string DAMAGED Target was damaged.
|
-- @field #string DAMAGED Target was damaged.
|
||||||
-- @field #string DESTROYED Target was destroyed.
|
-- @field #string DESTROYED Target was destroyed.
|
||||||
|
|
||||||
|
--- Mission summary.
|
||||||
|
-- @type AUFTRAG.Summary
|
||||||
|
-- @field #boolean success If true, mission was successful.
|
||||||
|
-- @field #number Ntargets0 Number of initial targets.
|
||||||
|
-- @field #number Ntargets Number of final targets after mission is done.
|
||||||
|
-- @field #number damage Target damage in per cent.
|
||||||
|
-- @field #number Ndestroyed Number of destroyed targets.
|
||||||
|
-- @field #number Nkills Number of kills from assigned groups.
|
||||||
|
-- @field #number Nelements Number of elements assigned to mission.
|
||||||
|
-- @field #number targetLife Target life points after mission is over.
|
||||||
|
-- @field #number category Target category.
|
||||||
|
-- @field #number Ncasualties Number of own casualties.
|
||||||
|
|
||||||
--- Generic mission condition.
|
--- Generic mission condition.
|
||||||
-- @type AUFTRAG.Condition
|
-- @type AUFTRAG.Condition
|
||||||
-- @field #function func Callback function to check for a condition. Should return a #boolean.
|
-- @field #function func Callback function to check for a condition. Should return a #boolean.
|
||||||
@@ -676,7 +691,7 @@ AUFTRAG.Category={
|
|||||||
|
|
||||||
--- AUFTRAG class version.
|
--- AUFTRAG class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
AUFTRAG.version="1.4.2"
|
AUFTRAG.version="1.5.0"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@@ -776,6 +791,7 @@ function AUFTRAG:New(Type)
|
|||||||
|
|
||||||
self:AddTransition("*", "Cancel", AUFTRAG.Status.CANCELLED) -- Command to cancel the mission.
|
self:AddTransition("*", "Cancel", AUFTRAG.Status.CANCELLED) -- Command to cancel the mission.
|
||||||
|
|
||||||
|
self:AddTransition("*", "Evaluated", "*")
|
||||||
self:AddTransition("*", "Success", AUFTRAG.Status.SUCCESS)
|
self:AddTransition("*", "Success", AUFTRAG.Status.SUCCESS)
|
||||||
self:AddTransition("*", "Failed", AUFTRAG.Status.FAILED)
|
self:AddTransition("*", "Failed", AUFTRAG.Status.FAILED)
|
||||||
|
|
||||||
@@ -946,6 +962,24 @@ function AUFTRAG:New(Type)
|
|||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
|
|
||||||
|
--- Triggers the FSM event "Evaluated".
|
||||||
|
-- @function [parent=#AUFTRAG] Evaluated
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @param #AUFTRAG.Summary
|
||||||
|
|
||||||
|
--- Triggers the FSM event "Evaluated" after a delay.
|
||||||
|
-- @function [parent=#AUFTRAG] __Evaluated
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @param #number delay Delay in seconds.
|
||||||
|
-- @param #AUFTRAG.Summary Summary Mission summary.
|
||||||
|
|
||||||
|
--- On after "Evaluated" event.
|
||||||
|
-- @function [parent=#AUFTRAG] OnAfterEvaluated
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param #AUFTRAG.Summary Summary Mission summary.
|
||||||
|
|
||||||
--- Triggers the FSM event "Success".
|
--- Triggers the FSM event "Success".
|
||||||
-- @function [parent=#AUFTRAG] Success
|
-- @function [parent=#AUFTRAG] Success
|
||||||
@@ -1751,6 +1785,9 @@ function AUFTRAG:NewBAI(Target, Altitude)
|
|||||||
mission.optionROE=ENUMS.ROE.OpenFire
|
mission.optionROE=ENUMS.ROE.OpenFire
|
||||||
mission.optionROT=ENUMS.ROT.PassiveDefense
|
mission.optionROT=ENUMS.ROT.PassiveDefense
|
||||||
|
|
||||||
|
-- Evaluate result after 5 min. We might need time until the bombs have dropped and targets have been detroyed.
|
||||||
|
mission.dTevaluate=5*60
|
||||||
|
|
||||||
mission.categories={AUFTRAG.Category.AIRCRAFT}
|
mission.categories={AUFTRAG.Category.AIRCRAFT}
|
||||||
|
|
||||||
mission.DCStask=mission:GetDCSMissionTask()
|
mission.DCStask=mission:GetDCSMissionTask()
|
||||||
@@ -2304,6 +2341,9 @@ function AUFTRAG:NewARTY(Target, Nshots, Radius, Altitude)
|
|||||||
|
|
||||||
local mission=AUFTRAG:New(AUFTRAG.Type.ARTY)
|
local mission=AUFTRAG:New(AUFTRAG.Type.ARTY)
|
||||||
|
|
||||||
|
printf("FF nshots=%s", tostring(Nshots))
|
||||||
|
printf("FF radius=%s", tostring(Radius))
|
||||||
|
|
||||||
mission:_TargetFromObject(Target)
|
mission:_TargetFromObject(Target)
|
||||||
|
|
||||||
mission.artyShots=Nshots or nil
|
mission.artyShots=Nshots or nil
|
||||||
@@ -2407,7 +2447,7 @@ end
|
|||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param Ops.OpsZone#OPSZONE OpsZone The OPS zone to capture.
|
-- @param Ops.OpsZone#OPSZONE OpsZone The OPS zone to capture.
|
||||||
-- @param #number Coalition The coalition which should capture the zone for the mission to be successful.
|
-- @param #number Coalition The coalition which should capture the zone for the mission to be successful.
|
||||||
-- @param #number Speed Speed in knots.
|
-- @param #number Speed (Optional) Speed in knots.
|
||||||
-- @param #number Altitude (Optional) Altitude in feet. Only for airborne units. Default 2000 feet ASL.
|
-- @param #number Altitude (Optional) Altitude in feet. Only for airborne units. Default 2000 feet ASL.
|
||||||
-- @param #string Formation (Optional) Formation used by ground units during patrol. Default "Off Road".
|
-- @param #string Formation (Optional) Formation used by ground units during patrol. Default "Off Road".
|
||||||
-- @param #number StayInZoneTime Stay this many seconds in the zone when done, only then drive back.
|
-- @param #number StayInZoneTime Stay this many seconds in the zone when done, only then drive back.
|
||||||
@@ -4690,6 +4730,18 @@ function AUFTRAG:Evaluate()
|
|||||||
failed=false
|
failed=false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.summary={} --#AUFTRAG.Summary
|
||||||
|
self.summary.success=not failed
|
||||||
|
self.summary.damage=targetdamage
|
||||||
|
self.summary.Ntargets=Ntargets
|
||||||
|
self.summary.Ntargets0=Ntargets0
|
||||||
|
self.summary.Ncasualties=self.Ncasualties
|
||||||
|
self.summary.Ndestroyed=self.engageTarget.Ndestroyed
|
||||||
|
self.summary.Nelements=self.Nelements
|
||||||
|
self.summary.Nkills=self.Nkills
|
||||||
|
self.summary.category=self.engageTarget:GetCategory()
|
||||||
|
self.summary.targetLife=Life
|
||||||
|
|
||||||
-- Debug text.
|
-- Debug text.
|
||||||
if self.verbose > 0 then
|
if self.verbose > 0 then
|
||||||
local text=string.format("Evaluating mission:\n")
|
local text=string.format("Evaluating mission:\n")
|
||||||
@@ -4709,6 +4761,9 @@ function AUFTRAG:Evaluate()
|
|||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Trigger evaluated result and pass summary.
|
||||||
|
self:Evaluated(self.summary)
|
||||||
|
|
||||||
-- Trigger events.
|
-- Trigger events.
|
||||||
if failed then
|
if failed then
|
||||||
self:I(self.lid..string.format("Mission %d [%s] failed!", self.auftragsnummer, self.type))
|
self:I(self.lid..string.format("Mission %d [%s] failed!", self.auftragsnummer, self.type))
|
||||||
@@ -5120,7 +5175,6 @@ end
|
|||||||
-- FSM Functions
|
-- FSM Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
--- On after "Planned" event.
|
--- On after "Planned" event.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
@@ -5430,7 +5484,7 @@ function AUFTRAG:onafterSuccess(From, Event, To)
|
|||||||
|
|
||||||
-- Stop mission.
|
-- Stop mission.
|
||||||
self:T(self.lid..string.format("Mission SUCCESS! Number of max repeats %d reached ==> Stopping mission!", self.repeated+1))
|
self:T(self.lid..string.format("Mission SUCCESS! Number of max repeats %d reached ==> Stopping mission!", self.repeated+1))
|
||||||
self:Stop()
|
self:__Stop(-120)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -5472,7 +5526,7 @@ function AUFTRAG:onafterFailed(From, Event, To)
|
|||||||
|
|
||||||
-- Stop mission.
|
-- Stop mission.
|
||||||
self:T(self.lid..string.format("Mission FAILED! Number of max repeats %d reached ==> Stopping mission!", self.repeated+1))
|
self:T(self.lid..string.format("Mission FAILED! Number of max repeats %d reached ==> Stopping mission!", self.repeated+1))
|
||||||
self:Stop()
|
self:__Stop(-120)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -5585,6 +5639,7 @@ function AUFTRAG:onafterRepeat(From, Event, To)
|
|||||||
self.Ngroups=0
|
self.Ngroups=0
|
||||||
self.Nassigned=nil
|
self.Nassigned=nil
|
||||||
self.Ndead=0
|
self.Ndead=0
|
||||||
|
self.summary=nil
|
||||||
|
|
||||||
-- Update DCS mission task. Could be that the initial task (e.g. for bombing) was destroyed. Then we need to update the coordinate.
|
-- Update DCS mission task. Could be that the initial task (e.g. for bombing) was destroyed. Then we need to update the coordinate.
|
||||||
self.DCStask=self:GetDCSMissionTask()
|
self.DCStask=self:GetDCSMissionTask()
|
||||||
@@ -5636,6 +5691,8 @@ function AUFTRAG:onafterStop(From, Event, To)
|
|||||||
-- No group data.
|
-- No group data.
|
||||||
self.groupdata={}
|
self.groupdata={}
|
||||||
|
|
||||||
|
self.summary=nil
|
||||||
|
|
||||||
-- Clear pending scheduler calls.
|
-- Clear pending scheduler calls.
|
||||||
self.CallScheduler:Clear()
|
self.CallScheduler:Clear()
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,9 @@ function BRIGADE:New(WarehouseName, BrigadeName)
|
|||||||
-- @param Ops.ArmyGroup#ARMYGROUP ArmyGroup The ARMYGROUP on mission.
|
-- @param Ops.ArmyGroup#ARMYGROUP ArmyGroup The ARMYGROUP on mission.
|
||||||
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
|
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
|
||||||
|
|
||||||
|
-- Add legion to DB
|
||||||
|
_DATABASE:AddLegion(self)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1102,6 +1102,31 @@ function COHORT:CountAssets(InStock, MissionTypes, Attributes)
|
|||||||
return N
|
return N
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Count available assets in legion warehouse stock. Spawned, requested and reserved assets are not counted.
|
||||||
|
-- @param #COHORT self
|
||||||
|
-- @param #table MissionTypes (Optional) Count only assest that can perform certain mission type(s). Default is all types.
|
||||||
|
-- @param #table Attributes (Optional) Count only assest that have a certain attribute(s), e.g. `WAREHOUSE.Attribute.AIR_BOMBER`.
|
||||||
|
-- @return #number Number of assets.
|
||||||
|
function COHORT:CountAvailableAssets(MissionTypes, Attributes)
|
||||||
|
|
||||||
|
local N=0
|
||||||
|
for _,_asset in pairs(self.assets) do
|
||||||
|
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
||||||
|
|
||||||
|
if not (asset.spawned or asset.requested or asset.isReserved) then
|
||||||
|
|
||||||
|
if MissionTypes==nil or AUFTRAG.CheckMissionCapability(MissionTypes, self.missiontypes) then
|
||||||
|
if Attributes==nil or self:CheckAttribute(Attributes) then
|
||||||
|
N=N+1 --This is in stock.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return N
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get OPSGROUPs.
|
--- Get OPSGROUPs.
|
||||||
-- @param #COHORT self
|
-- @param #COHORT self
|
||||||
-- @param #table MissionTypes (Optional) Count only assest that can perform certain mission type(s). Default is all types.
|
-- @param #table MissionTypes (Optional) Count only assest that can perform certain mission type(s). Default is all types.
|
||||||
|
|||||||
@@ -2112,6 +2112,22 @@ function COMMANDER:CountAssets(InStock, MissionTypes, Attributes)
|
|||||||
return N
|
return N
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Count available assets of all assigned legions, which are in stock. Spawned and reserved assets are not counted.
|
||||||
|
-- @param #COMMANDER self
|
||||||
|
-- @param #table MissionTypes (Optional) Count only assest that can perform certain mission type(s). Default is all types.
|
||||||
|
-- @param #table Attributes (Optional) Count only assest that have a certain attribute(s), e.g. `WAREHOUSE.Attribute.AIR_BOMBER`.
|
||||||
|
-- @return #number Amount of asset groups.
|
||||||
|
function COMMANDER:CountAvailableAssets(MissionTypes, Attributes)
|
||||||
|
|
||||||
|
local N=0
|
||||||
|
for _,_legion in pairs(self.legions) do
|
||||||
|
local legion=_legion --Ops.Legion#LEGION
|
||||||
|
N=N+legion:CountAvailableAssets(MissionTypes, Attributes)
|
||||||
|
end
|
||||||
|
|
||||||
|
return N
|
||||||
|
end
|
||||||
|
|
||||||
--- Count assets of all assigned legions.
|
--- Count assets of all assigned legions.
|
||||||
-- @param #COMMANDER self
|
-- @param #COMMANDER self
|
||||||
-- @param #table MissionTypes (Optional) Count only missions of these types. Default is all types.
|
-- @param #table MissionTypes (Optional) Count only missions of these types. Default is all types.
|
||||||
|
|||||||
@@ -167,6 +167,9 @@ function FLEET:New(WarehouseName, FleetName)
|
|||||||
-- @param Ops.NavyGroup#NAVYGROUP NavyGroup The NAVYGROUP on mission.
|
-- @param Ops.NavyGroup#NAVYGROUP NavyGroup The NAVYGROUP on mission.
|
||||||
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
|
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
|
||||||
|
|
||||||
|
-- Add legion to DB
|
||||||
|
_DATABASE:AddLegion(self)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,9 @@ function FLOTILLA:New(TemplateGroupName, Ngroups, FlotillaName)
|
|||||||
-- Get initial ammo.
|
-- Get initial ammo.
|
||||||
self.ammo=self:_CheckAmmo()
|
self.ammo=self:_CheckAmmo()
|
||||||
|
|
||||||
|
-- Add cohort to DB
|
||||||
|
_DATABASE:AddCohort(self)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -350,6 +350,18 @@ INTEL.RCS_NoseOnFraction = 0.15
|
|||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Constructor
|
-- Constructor
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
--- Create a new INTEL object and start the FSM.
|
||||||
|
-- @param #INTEL self
|
||||||
|
-- @return #INTEL self
|
||||||
|
function INTEL:_UpdateAgents()
|
||||||
|
|
||||||
|
-- Filter coalition.
|
||||||
|
if self.coalition then
|
||||||
|
local coalitionname=UTILS.GetCoalitionName(self.coalition):lower()
|
||||||
|
self.detectionset:FilterCoalitions(coalitionname):FilterAlive():FilterOnce()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Create a new INTEL object and start the FSM.
|
--- Create a new INTEL object and start the FSM.
|
||||||
-- @param #INTEL self
|
-- @param #INTEL self
|
||||||
@@ -837,6 +849,18 @@ function INTEL:AddAgent(AgentGroup)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set whether the detection set, aka agents, are updated periodically. With this all alive groups of the INTEL coalition are included.
|
||||||
|
-- @param #INTEL self
|
||||||
|
-- @param #boolean switch If `true` or nil, all groups of the coalition will be added automatically to the Agent set.
|
||||||
|
-- @return #INTEL self
|
||||||
|
function INTEL:SetAgentAuto(switch)
|
||||||
|
if switch==nil then
|
||||||
|
switch=true
|
||||||
|
end
|
||||||
|
self.update_detectionset=switch
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Enable or disable cluster analysis of detected targets.
|
--- Enable or disable cluster analysis of detected targets.
|
||||||
-- Targets will be grouped in coupled clusters.
|
-- Targets will be grouped in coupled clusters.
|
||||||
-- @param #INTEL self
|
-- @param #INTEL self
|
||||||
@@ -1026,6 +1050,10 @@ function INTEL:onafterStatus(From, Event, To)
|
|||||||
-- FSM state.
|
-- FSM state.
|
||||||
local fsmstate=self:GetState()
|
local fsmstate=self:GetState()
|
||||||
|
|
||||||
|
if self.update_detectionset then
|
||||||
|
self:_UpdateAgents()
|
||||||
|
end
|
||||||
|
|
||||||
-- Fresh arrays.
|
-- Fresh arrays.
|
||||||
self.ContactsLost={}
|
self.ContactsLost={}
|
||||||
self.ContactsUnknown={}
|
self.ContactsUnknown={}
|
||||||
|
|||||||
@@ -306,7 +306,6 @@ function LEGION:New(WarehouseName, LegionName)
|
|||||||
-- @param Ops.Cohort#COHORT Cohort The cohort the asset belongs to.
|
-- @param Ops.Cohort#COHORT Cohort The cohort the asset belongs to.
|
||||||
-- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset that returned.
|
-- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset that returned.
|
||||||
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2099,6 +2098,23 @@ function LEGION:CountAssets(InStock, MissionTypes, Attributes)
|
|||||||
return N
|
return N
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Count total number of available assets in the legion stock.
|
||||||
|
-- @param #LEGION self
|
||||||
|
-- @param #table MissionTypes (Optional) Count only assest that can perform certain mission type(s). Default is all types.
|
||||||
|
-- @param #table Attributes (Optional) Count only assest that have a certain attribute(s), e.g. `GROUP.Attribute.AIR_BOMBER`.
|
||||||
|
-- @return #number Amount of asset groups in stock.
|
||||||
|
function LEGION:CountAvailableAssets(MissionTypes, Attributes)
|
||||||
|
|
||||||
|
local N=0
|
||||||
|
|
||||||
|
for _,_cohort in pairs(self.cohorts) do
|
||||||
|
local cohort=_cohort --Ops.Cohort#COHORT
|
||||||
|
N=N+cohort:CountAvailableAssets(MissionTypes,Attributes)
|
||||||
|
end
|
||||||
|
|
||||||
|
return N
|
||||||
|
end
|
||||||
|
|
||||||
--- Get OPSGROUPs that are spawned and alive.
|
--- Get OPSGROUPs that are spawned and alive.
|
||||||
-- @param #LEGION self
|
-- @param #LEGION self
|
||||||
-- @param #table MissionTypes (Optional) Get only assest that can perform certain mission type(s). Default is all types.
|
-- @param #table MissionTypes (Optional) Get only assest that can perform certain mission type(s). Default is all types.
|
||||||
|
|||||||
@@ -4691,7 +4691,7 @@ function OPSGROUP:_UpdateTask(Task, Mission)
|
|||||||
self:T(self.lid..string.format("Zone %s captured ==> Task DONE!", zoneCurr:GetName()))
|
self:T(self.lid..string.format("Zone %s captured ==> Task DONE!", zoneCurr:GetName()))
|
||||||
|
|
||||||
-- Task done.
|
-- Task done.
|
||||||
if Task.StayInZoneTime then
|
if Task.StayInZoneTime and Task.StayInZoneTime>0 then
|
||||||
local stay = Task.StayInZoneTime
|
local stay = Task.StayInZoneTime
|
||||||
self:__TaskDone(stay,Task)
|
self:__TaskDone(stay,Task)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ function PLATOON:New(TemplateGroupName, Ngroups, PlatoonName)
|
|||||||
-- Get ammo.
|
-- Get ammo.
|
||||||
self.ammo=self:_CheckAmmo()
|
self.ammo=self:_CheckAmmo()
|
||||||
|
|
||||||
|
-- Add cohort to DB
|
||||||
|
_DATABASE:AddCohort(self)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -116,6 +116,9 @@ function SQUADRON:New(TemplateGroupName, Ngroups, SquadronName)
|
|||||||
|
|
||||||
-- See COHORT class
|
-- See COHORT class
|
||||||
|
|
||||||
|
-- Add cohort to DB
|
||||||
|
_DATABASE:AddCohort(self)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ _TARGETID=0
|
|||||||
|
|
||||||
--- TARGET class version.
|
--- TARGET class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
TARGET.version="0.7.1"
|
TARGET.version="0.8.0"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@@ -206,6 +206,9 @@ function TARGET:New(TargetObject)
|
|||||||
self:AddTransition("*", "Status", "*") -- Status update.
|
self:AddTransition("*", "Status", "*") -- Status update.
|
||||||
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
|
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
|
||||||
|
|
||||||
|
self:AddTransition("*", "ElementDestroyed", "*") -- A target element was destroyed.
|
||||||
|
self:AddTransition("*", "ElementDead", "*") -- A target element is dead (destroyed or despawned).
|
||||||
|
|
||||||
self:AddTransition("*", "ObjectDamaged", "*") -- A target object was damaged.
|
self:AddTransition("*", "ObjectDamaged", "*") -- A target object was damaged.
|
||||||
self:AddTransition("*", "ObjectDestroyed", "*") -- A target object was destroyed.
|
self:AddTransition("*", "ObjectDestroyed", "*") -- A target object was destroyed.
|
||||||
self:AddTransition("*", "ObjectDead", "*") -- A target object is dead (destroyed or despawned).
|
self:AddTransition("*", "ObjectDead", "*") -- A target object is dead (destroyed or despawned).
|
||||||
@@ -245,6 +248,19 @@ function TARGET:New(TargetObject)
|
|||||||
-- @param #number delay Delay in seconds.
|
-- @param #number delay Delay in seconds.
|
||||||
|
|
||||||
|
|
||||||
|
--- Triggers the FSM event "ElementDestroyed".
|
||||||
|
-- @function [parent=#TARGET] ElementDestroyed
|
||||||
|
-- @param #TARGET self
|
||||||
|
-- @param #string ElementName Name of the element.
|
||||||
|
-- @param #TARGET.Object Target Target object.
|
||||||
|
|
||||||
|
--- Triggers the FSM event "ElementDead".
|
||||||
|
-- @function [parent=#TARGET] ElementDead
|
||||||
|
-- @param #TARGET self
|
||||||
|
-- @param #string ElementName Name of the element.
|
||||||
|
-- @param #TARGET.Object Target Target object.
|
||||||
|
|
||||||
|
|
||||||
--- Triggers the FSM event "ObjectDamaged".
|
--- Triggers the FSM event "ObjectDamaged".
|
||||||
-- @function [parent=#TARGET] ObjectDamaged
|
-- @function [parent=#TARGET] ObjectDamaged
|
||||||
-- @param #TARGET self
|
-- @param #TARGET self
|
||||||
@@ -643,6 +659,19 @@ function TARGET:onafterStatus(From, Event, To)
|
|||||||
-- FSM state.
|
-- FSM state.
|
||||||
local fsmstate=self:GetState()
|
local fsmstate=self:GetState()
|
||||||
|
|
||||||
|
-- First we check any target has been destroyed and the dead/unitlost event was not fired
|
||||||
|
for i,_target in pairs(self.targets) do
|
||||||
|
local target=_target --#TARGET.Object
|
||||||
|
local life=self:GetTargetLife(target)
|
||||||
|
if life<1 and target.Status~=TARGET.ObjectStatus.DEAD then
|
||||||
|
self:E(self.lid..string.format("FF life is zero but no object dead event fired ==> waiting for target object %s events!", tostring(target.Name)))
|
||||||
|
-- We wait 60 seconds for the events to occur
|
||||||
|
self:__Status(-60)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
-- Update damage.
|
-- Update damage.
|
||||||
local damaged=false
|
local damaged=false
|
||||||
for i,_target in pairs(self.targets) do
|
for i,_target in pairs(self.targets) do
|
||||||
@@ -736,6 +765,61 @@ end
|
|||||||
-- FSM Events
|
-- FSM Events
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- On after "ElementDestroyed" event.
|
||||||
|
-- @param #TARGET self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param #string Name Name of the element.
|
||||||
|
-- @param #TARGET.Object Target Target object.
|
||||||
|
function TARGET:onafterElementDestroyed(From, Event, To, Name, Target)
|
||||||
|
-- Debug message.
|
||||||
|
self:T(self.lid..string.format("Element %s of target object %s destroyed", Name, Target.Name))
|
||||||
|
|
||||||
|
-- Increase destroyed counter.
|
||||||
|
Target.Ndestroyed=Target.Ndestroyed+1
|
||||||
|
|
||||||
|
-- Increase dead counter.
|
||||||
|
self.Ndestroyed=self.Ndestroyed+1
|
||||||
|
|
||||||
|
self:ElementDead(Name, Target)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- On after "ElementDead" event.
|
||||||
|
-- @param #TARGET self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param #string Name Name of the element.
|
||||||
|
-- @param #TARGET.Object Target Target object.
|
||||||
|
function TARGET:onafterElementDead(From, Event, To, Name, Target)
|
||||||
|
-- Debug message.
|
||||||
|
self:T(self.lid..string.format("Element %s of target object %s dead", Name, Target.Name))
|
||||||
|
|
||||||
|
-- Increase dead counter.
|
||||||
|
Target.Ndead=Target.Ndead+1
|
||||||
|
|
||||||
|
-- Increase dead counter.
|
||||||
|
self.Ndead=self.Ndead+1
|
||||||
|
|
||||||
|
-- All dead ==> Trigger event.
|
||||||
|
if Target.Ndestroyed==Target.N0 then
|
||||||
|
|
||||||
|
self:ObjectDestroyed(Target)
|
||||||
|
|
||||||
|
elseif Target.Ndead==Target.N0 then
|
||||||
|
|
||||||
|
self:ObjectDead(Target)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- On after "ObjectDamaged" event.
|
--- On after "ObjectDamaged" event.
|
||||||
-- @param #TARGET self
|
-- @param #TARGET self
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
@@ -761,11 +845,6 @@ function TARGET:onafterObjectDestroyed(From, Event, To, Target)
|
|||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:T(self.lid..string.format("Object %s destroyed", Target.Name))
|
self:T(self.lid..string.format("Object %s destroyed", Target.Name))
|
||||||
|
|
||||||
-- Increase destroyed counter.
|
|
||||||
self.Ndestroyed=self.Ndestroyed+1
|
|
||||||
|
|
||||||
Target.Ndestroyed=Target.Ndestroyed+1
|
|
||||||
|
|
||||||
Target.Life=0
|
Target.Life=0
|
||||||
|
|
||||||
-- Call object dead event.
|
-- Call object dead event.
|
||||||
@@ -788,15 +867,9 @@ function TARGET:onafterObjectDead(From, Event, To, Target)
|
|||||||
-- Set target status.
|
-- Set target status.
|
||||||
Target.Status=TARGET.ObjectStatus.DEAD
|
Target.Status=TARGET.ObjectStatus.DEAD
|
||||||
|
|
||||||
-- Increase dead object counter
|
|
||||||
Target.Ndead=Target.Ndead+1
|
|
||||||
|
|
||||||
-- Set target object life to 0.
|
-- Set target object life to 0.
|
||||||
Target.Life=0
|
Target.Life=0
|
||||||
|
|
||||||
-- Increase dead counter.
|
|
||||||
self.Ndead=self.Ndead+1
|
|
||||||
|
|
||||||
-- Check if anyone is alive?
|
-- Check if anyone is alive?
|
||||||
local dead=true
|
local dead=true
|
||||||
for _,_target in pairs(self.targets) do
|
for _,_target in pairs(self.targets) do
|
||||||
@@ -889,54 +962,21 @@ function TARGET:OnEventUnitDeadOrLost(EventData)
|
|||||||
-- Add to the list of casualties.
|
-- Add to the list of casualties.
|
||||||
table.insert(self.casualties, Name)
|
table.insert(self.casualties, Name)
|
||||||
|
|
||||||
-- Try to get target Group.
|
-- Get target from Group or Unit.
|
||||||
local target=self:GetTargetByName(EventData.IniGroupName)
|
local target=self:GetTargetByName(EventData.IniGroupName) or self:GetTargetByName(EventData.IniUnitName)
|
||||||
|
|
||||||
-- Try unit target.
|
|
||||||
if not target then
|
|
||||||
target=self:GetTargetByName(EventData.IniUnitName)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check if we could find a target object.
|
-- Check if we could find a target object.
|
||||||
if target then
|
if target then
|
||||||
|
|
||||||
local Ndead=target.Ndead
|
-- Increase dead/destroyed counter
|
||||||
local Ndestroyed=target.Ndestroyed
|
|
||||||
if EventData.id==EVENTS.RemoveUnit then
|
if EventData.id==EVENTS.RemoveUnit then
|
||||||
Ndead=Ndead+1
|
self:ElementDead(Name, target)
|
||||||
else
|
else
|
||||||
Ndestroyed=Ndestroyed+1
|
self:ElementDestroyed(Name, target)
|
||||||
Ndead=Ndead+1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Check if ALL objects are dead
|
|
||||||
if Ndead==target.N0 then
|
|
||||||
|
|
||||||
if Ndestroyed>=target.N0 then
|
|
||||||
|
|
||||||
-- Debug message.
|
|
||||||
self:T2(self.lid..string.format("EVENT ID=%d: target %s dead/lost ==> destroyed", EventData.id, tostring(target.Name)))
|
|
||||||
|
|
||||||
target.Life = 0
|
|
||||||
|
|
||||||
-- Trigger object destroyed event. This sets the Life to zero and increases Ndestroyed
|
|
||||||
self:ObjectDestroyed(target)
|
|
||||||
|
|
||||||
else
|
else
|
||||||
|
self:E(self.lid..string.format("ERROR: Could not get target from IniGroup or IniUnit name when event Dead or UnitLost occured! Stats are not correctly updated :("))
|
||||||
-- Debug message.
|
|
||||||
self:T2(self.lid..string.format("EVENT ID=%d: target %s removed ==> dead", EventData.id, tostring(target.Name)))
|
|
||||||
|
|
||||||
target.Life = 0
|
|
||||||
|
|
||||||
-- Trigger object dead event. This sets the Life to zero and increases Ndead counter
|
|
||||||
self:ObjectDead(target)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end -- Event belongs to this TARGET
|
end -- Event belongs to this TARGET
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1964,6 +1964,25 @@ function AIRBASE:Register(AirbaseName)
|
|||||||
-- Category.
|
-- Category.
|
||||||
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
|
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
|
||||||
|
|
||||||
|
-- Get DCS object.
|
||||||
|
local airbase=self:GetDCSObject()
|
||||||
|
|
||||||
|
if airbase then
|
||||||
|
self.objectcategory=Object.getCategory(airbase)
|
||||||
|
else
|
||||||
|
self.objectcategory=Object.Category.BASE
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.objectcategory==Object.Category.BASE then
|
||||||
|
self.objectcategoryName="BASE"
|
||||||
|
elseif self.objectcategory==Object.Category.STATIC then
|
||||||
|
self.objectcategoryName="STATIC"
|
||||||
|
elseif self.objectcategory==Object.Category.UNIT then
|
||||||
|
self.objectcategoryName="UNIT"
|
||||||
|
else
|
||||||
|
self.objectcategoryName="OTHER"
|
||||||
|
end
|
||||||
|
|
||||||
-- H2 is bugged
|
-- H2 is bugged
|
||||||
--if self.AirbaseName == "H4" and self.descriptors == nil then
|
--if self.AirbaseName == "H4" and self.descriptors == nil then
|
||||||
--self:E("***** H4 on Syria map is currently bugged!")
|
--self:E("***** H4 on Syria map is currently bugged!")
|
||||||
@@ -1971,12 +1990,12 @@ function AIRBASE:Register(AirbaseName)
|
|||||||
--end
|
--end
|
||||||
|
|
||||||
-- Set category.
|
-- Set category.
|
||||||
if self.category==Airbase.Category.AIRDROME then
|
if self.category==Airbase.Category.AIRDROME then
|
||||||
self.isAirdrome=true
|
self.isAirdrome=true
|
||||||
elseif self.category==Airbase.Category.HELIPAD or self.descriptors.typeName=="FARP_SINGLE_01" then
|
elseif self.category==Airbase.Category.HELIPAD or self.descriptors.typeName=="FARP_SINGLE_01" then
|
||||||
self.isHelipad=true
|
self.isHelipad=true
|
||||||
self.category=Airbase.Category.HELIPAD
|
self.category=Airbase.Category.HELIPAD
|
||||||
elseif self.category==Airbase.Category.SHIP then
|
elseif self.category==Airbase.Category.SHIP then
|
||||||
self.isShip=true
|
self.isShip=true
|
||||||
-- DCS bug: Oil rigs and gas platforms have category=2 (ship). Also they cannot be retrieved by coalition.getStaticObjects()
|
-- DCS bug: Oil rigs and gas platforms have category=2 (ship). Also they cannot be retrieved by coalition.getStaticObjects()
|
||||||
if self.descriptors.typeName=="Oil rig" or self.descriptors.typeName=="Ga" then
|
if self.descriptors.typeName=="Oil rig" or self.descriptors.typeName=="Ga" then
|
||||||
@@ -1986,9 +2005,9 @@ elseif self.category==Airbase.Category.SHIP then
|
|||||||
_DATABASE:AddStatic(AirbaseName)
|
_DATABASE:AddStatic(AirbaseName)
|
||||||
end
|
end
|
||||||
if self:GetTypeName() == "Zell" then self.isZell = true end
|
if self:GetTypeName() == "Zell" then self.isZell = true end
|
||||||
else
|
else
|
||||||
self:E("ERROR: Unknown airbase category!")
|
self:E("ERROR: Unknown airbase category!")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Init Runways.
|
-- Init Runways.
|
||||||
self:_InitRunways()
|
self:_InitRunways()
|
||||||
@@ -2614,7 +2633,7 @@ function AIRBASE:GetMinimumBoundingCircleFromParkingSpots(mark)
|
|||||||
local spots = self:GetParkingSpotsVec2s()
|
local spots = self:GetParkingSpotsVec2s()
|
||||||
if #spots == 0 then return self.AirbaseZone end
|
if #spots == 0 then return self.AirbaseZone end
|
||||||
local center, radius = UTILS.GetMinimumBoundingCircle(spots)
|
local center, radius = UTILS.GetMinimumBoundingCircle(spots)
|
||||||
self.parkingCircle = ZONE_RADIUS:New(self.AirbaseName.." ParkingCircle",center,radius+50)
|
self.parkingCircle = ZONE_RADIUS:New(self.AirbaseName.." ParkingCircle", center, radius+50, true)
|
||||||
if mark == true then
|
if mark == true then
|
||||||
self.parkingCircle:DrawZone(-1,{1,0,0},1,{0,1,0},0.2,3)
|
self.parkingCircle:DrawZone(-1,{1,0,0},1,{0,1,0},0.2,3)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user